Несколько USART на STM32F4
Несколько USART на STM32F4
Ребят, подскажите пожалуйста, реальна ли одновременная работа 2х - 4х USART с прерываниями по приему ? У меня два USART работают, а при инициализации третьего прерывание по приему не происходит....не знаю в чем дело, подскажите. Нужен будет код - прикреплю. Заранее спасибо
Re: Несколько USART на STM32F4
Насколько помню у STM32 часто на несколько интерфейсов или событий часто одно прерывание, которое и срабатывает, а программист должен по флагам определить, что именно сработало.
Возможно забыли включить прерывание для одного UART`а. Опять же все включать надо (зато если не включать - экономится энергия).
Без кода конечно не понятно...
UPD. Вспомнил еще, что некоторые порты могут быть по умолчанию на что-то еще инициализированы, например JTAG, тогда надо отключать или переносить на другие пины. У Вас вообще этот UART работает?
Возможно забыли включить прерывание для одного UART`а. Опять же все включать надо (зато если не включать - экономится энергия).
Без кода конечно не понятно...
UPD. Вспомнил еще, что некоторые порты могут быть по умолчанию на что-то еще инициализированы, например JTAG, тогда надо отключать или переносить на другие пины. У Вас вообще этот UART работает?
Re: Несколько USART на STM32F4
Код: Выделить всё
/* Include my libraries here */
#include "defines.h"
#include "main.h"
#include "tm_stm32f4_ili9341.h"
#include "stdlib.h"
#include <string.h>
#include <stdio.h>
#define ADC_CDR_ADDRESS ((uint32_t)0x40012308)
TM_RTC_Time_t datatIme;
char irtc [32];
char adc_1 [8];
char adc_2 [8];
char vbat [8];
char string [256];
char usart_rx [128];
char rx_str [128];
//---------------------test---------------------------//
#define MAX_STRLEN 128 // this is the maximum string length of our string in characters
char received_string_usrt6[MAX_STRLEN+1]; // this will hold the recieved string
char received_string_usrt3[MAX_STRLEN+1]; // this will hold the recieved string
char received_string_usrt1[MAX_STRLEN+1]; // this will hold the recieved string
u32 StringLen = 0;
u32 StringRdy = 0;
//---------------------test---------------------------//
char vbat_str [6];
char adc1_str [6];
char adc2_str [4];
int i_vbat;
int i_adc1;
int i_adc2;
uint8_t c;
long double result_vbat;
long double result_adc1;
long double result_adc2;
//---------------------test---------------------------//
void TM_USART6_ReceiveHandler(uint8_t c){
if ((c != '\r') && (StringLen < MAX_STRLEN))
{
received_string_usrt6[StringLen++] = c;
TM_GPIO_TogglePinValue(GPIOD, GPIO_Pin_14);
TM_DISCO_LedOn(LED_RED);
}
else
{
if (StringLen < MAX_STRLEN)
{
// save LF as well
received_string_usrt6[StringLen++] = c;
}
received_string_usrt6[StringLen] = 0;
StringRdy = 1;
StringLen = 0;
}
if(StringRdy){
TM_USART_Puts(USART6,received_string_usrt6);
TM_USART_Puts(USART6, "\n\r");
TM_USART_Puts(USART1,received_string_usrt6);
TM_USART_Puts(USART1, "\n\r");
StringRdy = 0;
memset(received_string_usrt6, 0, sizeof(received_string_usrt6));
}
}
void TM_USART3_ReceiveHandler(uint8_t c){
if ((c != '\r') && (StringLen < MAX_STRLEN))
{
received_string_usrt3[StringLen++] = c;
TM_GPIO_TogglePinValue(GPIOD, GPIO_Pin_12);
}
else
{
if (StringLen < MAX_STRLEN)
{
// save LF as well
received_string_usrt3[StringLen++] = c;
}
received_string_usrt3[StringLen] = 0;
StringRdy = 1;
StringLen = 0;
}
if(StringRdy){
// TM_USART_Puts(USART3,received_string_usrt3);
// TM_USART_Puts(USART3, "\n\r");
TM_USART_Puts(USART1,received_string_usrt3);
TM_USART_Puts(USART1, "\n\r");
StringRdy = 0;
memset(received_string_usrt3, 0, sizeof(received_string_usrt3));
}
}
void TM_USART1_ReceiveHandler(uint8_t c){
if ((c != '\r') && (StringLen < MAX_STRLEN))
{
received_string_usrt1[StringLen++] = c;
TM_GPIO_TogglePinValue(GPIOD, GPIO_Pin_10);
}
else
{
if (StringLen < MAX_STRLEN)
{
// save LF as well
received_string_usrt1[StringLen++] = c;
}
received_string_usrt1[StringLen] = 0;
StringRdy = 1;
StringLen = 0;
}
if (c == '\r')
{
if(strcmp(received_string_usrt1,"status\r")==0){
TM_USART_Puts(USART1,"received:");
TM_USART_Puts(USART3, "+++AT?S\r");
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}
else if(strcmp(received_string_usrt1,"sound\r")==0){
TM_USART_Puts(USART1,"received:");
TM_USART_Puts(USART3, "+++AT?CA\r");
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}
else if(strcmp(received_string_usrt1,"local\r")==0){
TM_USART_Puts(USART1,"received:");
TM_USART_Puts(USART3, "+++AT?BL\r");
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}
else if(strcmp(received_string_usrt1,"remote\r")==0){
TM_USART_Puts(USART1,"received:");
TM_USART_Puts(USART3, "+++AT?BR\r");
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}else if(strcmp(received_string_usrt1,"rssi\r")==0){
TM_USART_Puts(USART1,"received:");
TM_USART_Puts(USART3, "+++AT?E\r");
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}else if(strcmp(received_string_usrt1,"signal\r")==0){
TM_USART_Puts(USART1,"received:");
TM_USART_Puts(USART3, "+++AT?I\r");
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}else if(strcmp(received_string_usrt1,"time\r")==0){
TM_USART_Puts(USART1,"received:");
TM_USART_Puts(USART3, "+++AT?T\r");
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}else if(strcmp(received_string_usrt1,"speed\r")==0){
TM_USART_Puts(USART1,"received:");
TM_USART_Puts(USART3, "+++AT?V\r");
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}else if(strcmp(received_string_usrt1,"battery\r")==0){
TM_USART_Puts(USART1,"received:");
TM_USART_Puts(USART3, "+++AT?BV\r");
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}else if(strcmp(received_string_usrt1,"counter\r")==0){
TM_USART_Puts(USART1,"received:");
TM_USART_Puts(USART3, "+++AT?ZE\r");
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}else if(strcmp(received_string_usrt1,"help\r")==0){
TM_USART_Puts(USART1,"received:");
TM_USART_Puts(USART1, "1)status\n\r2)sound\n\r3)local\n\r4)remote\n\r5)rssi\n\r6)signal\n\r7)time\n\r8)speed\n\r9)battery\n\r10)counter\n\r");
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}else{
// TM_USART_Puts(USART1,received_string_usrt1);
TM_USART_Puts(USART3,received_string_usrt1);
TM_USART_Puts(USART3, "\n");
StringRdy = 0;
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}if(StringRdy){
TM_USART_Puts(USART3,received_string_usrt1);
TM_USART_Puts(USART3, "\n\r");
// TM_USART_Puts(USART1,received_string_usrt1);
// TM_USART_Puts(USART1, "\n\r");
StringRdy = 0;
if(f_printf(&fl,received_string_usrt1) == FR_OK){
f_sync(&fl);
}
memset(received_string_usrt1, 0, sizeof(received_string_usrt1));
}
}
}
int main(void) {
/* Initialize system */
SystemInit();
//Initiaize button
TM_DISCO_ButtonInit();
//Initialize Leds
TM_DISCO_LedInit();
/* Initialize Delay library */
TM_DELAY_Init();
// init_timer_data();
GPIO_Init_Leds();
/* Initialize USART3, 19200baud PB10 PB11 */
TM_USART_Init(USART3, TM_USART_PinsPack_1, 19200);
TM_USART_Puts(USART3, "STARTED USART3!!!\n\r");
/* Initialize USART6, 115200baud PC6 PC7*/
// TM_USART_Init(USART6, TM_USART_PinsPack_1, 19200);
// TM_USART_Puts(USART6, "STARTED USART6!!!\n\r");
/* Initialize USART1, 19200baud PA2 PA3*/
TM_USART_Init(USART1, TM_USART_PinsPack_1, 19200);
TM_USART_Puts(USART1, "STARTED USART1!!!\n\r");
TM_RTC_Interrupts(TM_RTC_Int_1s);
while (1) {
if(TM_DISCO_ButtonPressed()){
f_close(&fl);
f_mount(0, "", 1);
TM_ILI9341_Puts(10, 120, "USB flash drive is removed successfully" , &TM_Font_7x10, ILI9341_COLOR_ORANGE, 0x0000);
}else{}
/* Read ADC1 Channel0 Read ADC1 Channel3 */
snprintf(adc_1 ,sizeof(adc_1) , "%4d" , TM_ADC_Read(ADC1, ADC_Channel_8));
snprintf(adc_2 ,sizeof(adc_2) , "%4d" , TM_ADC_Read(ADC1, ADC_Channel_9));
/* Read & format data */
snprintf(vbat, sizeof(vbat) , "%4d" , TM_ADC_ReadVbat(ADC1));
snprintf(string,sizeof(string),"|%s|-|%s-%s-%s|\n\r",irtc, vbat_str, adc1_str, adc2_str);
TM_ILI9341_Puts(75 , 60, vbat_str ,&TM_Font_7x10, ILI9341_COLOR_WHITE , 0x0000);
TM_ILI9341_Puts(75 , 30, adc1_str ,&TM_Font_7x10, ILI9341_COLOR_WHITE , 0x0000);
TM_ILI9341_Puts(75 , 45, adc2_str ,&TM_Font_7x10, ILI9341_COLOR_WHITE , 0x0000);
TM_ILI9341_Puts(10 , 15, irtc ,&TM_Font_7x10, ILI9341_COLOR_WHITE , 0x0000);
i_vbat = atoi(vbat);
result_vbat = ((3.14 / 4096) * i_vbat)+ 0.6;
sprintf(vbat_str, "%.2Lf", result_vbat);
i_adc1 = atoi(adc_1);
result_adc1 = ((3.14 / 4096) * i_adc1)+ 0.3;
sprintf(adc1_str, "%.2Lf", result_adc1);
i_adc2 = atoi(adc_2);
result_adc2 = ((3.14 / 4096) * i_adc2);
sprintf(adc2_str, "%.2Lf", result_adc2);
f_printf(&fl,string);
f_sync(&fl);
/* Little delay */
Delayms(100);
}
}
Собственно вот кусочек кода, самое основное я выкладываю, библиотеками пользуюсь отсюда - http://stm32f4-discovery.com/2014/04/library-04-connect-stm32f429-discovery-to-computer-with-usart/ Что очень упростило разработку в целом, 2 порта стабильно работают, третий порт, он же шестой усарт, показывает, что работает, но прерывание у него не срабатывает, данные не синхронно поступают. То есть по факту один порт отладки(условно), второй порт - передача данных, третий порт - управление через Wi-fi(usart-модуль). Ссылка на библиотеки есть, попробую оттестить каждый порт по одному, для проверки их на работоспособность, но почему-то меня терзают смутные сомнения, ибо из 8-ми усартов работает только два.......Странно это очень. За код не ругайте, сам знаю, что это полный колхоз. Комменты поставил осознанно, по причине того, что порт тупо висит и я его не инициализирую пока....Может кто попробует запустить 3 порта и 3 прерывания на них...было бы интересно узнать, работает ли оно так вообще. Заранее спасибо
Re: Несколько USART на STM32F4
1. Могу предположить, что Вы что-то тестировали и просто временно закомментировали инициализацию USART6.
Хорошо бы именно видеть его инициализацию и его прерывания.
2. Самое главное: Согласно документации на STM32F4Discovery, на пине PC7, где расположен USART6_RX, подключен модуль CS43L22, а именно MCLK. В таких случаях надо, или использовать другой USART, или переназначать ножку на др. пин (конкретно USART6 никуда не переносится)
UPD. Ни чем не заняты на STM32F4Discovery USART2 и UART4. Если у Вас USART3_TX подключен к PB10 (не нашел у Вас включение тактирования портов, с инициализацией конкретных пинов), он на STM32F4Discovery тоже занят, но он переносится на свободный PD8. Аналогично у USART1_RX порт PA1 занят, но переносится на свободный PB7, а USART1_TX на PB6 тоже занят и переносится только на занятый PA9. Использовать интерфейсы на занятых портах - это всегда риск, что работать не будет, т.к. подключенный к порту чип может по умолчанию прижимать порт к 0 или 1. К тому же сразу не ясно, если у Вас все сейчас работает, не убьется ли что потом. Можно физически отрезать дорожку мешающего устройства.
Если порт занят отладчиком, то тут проще: снимаем перемычки отладчика и программно, в начале инициализации периферии, отключаем отладочные интерфейсы.
В этом недостаток демо-отладочных плат - уже куча доп. периферии, которая Вам не нужна, а использовать занятые порты очень хочется.
Хорошо бы именно видеть его инициализацию и его прерывания.
2. Самое главное: Согласно документации на STM32F4Discovery, на пине PC7, где расположен USART6_RX, подключен модуль CS43L22, а именно MCLK. В таких случаях надо, или использовать другой USART, или переназначать ножку на др. пин (конкретно USART6 никуда не переносится)
UPD. Ни чем не заняты на STM32F4Discovery USART2 и UART4. Если у Вас USART3_TX подключен к PB10 (не нашел у Вас включение тактирования портов, с инициализацией конкретных пинов), он на STM32F4Discovery тоже занят, но он переносится на свободный PD8. Аналогично у USART1_RX порт PA1 занят, но переносится на свободный PB7, а USART1_TX на PB6 тоже занят и переносится только на занятый PA9. Использовать интерфейсы на занятых портах - это всегда риск, что работать не будет, т.к. подключенный к порту чип может по умолчанию прижимать порт к 0 или 1. К тому же сразу не ясно, если у Вас все сейчас работает, не убьется ли что потом. Можно физически отрезать дорожку мешающего устройства.
Если порт занят отладчиком, то тут проще: снимаем перемычки отладчика и программно, в начале инициализации периферии, отключаем отладочные интерфейсы.
В этом недостаток демо-отладочных плат - уже куча доп. периферии, которая Вам не нужна, а использовать занятые порты очень хочется.
Re: Несколько USART на STM32F4
В ссылке на библиотеку там все есть, помимо сторонней библиотеки на USART там есть еще остальные библиотеки. Что странно, что USART 3 и USART 1 работают исправно. USART 6 и остальные усарты инициализацию проходят, после нее пишут сообщение в порт о том, что они инициализировались, но данные не принимают, то есть прерывания для них не срабатывают. В ссылке на сторонние библиотеки к stm32f4 всю инициализацию можно увидеть для каждого инициализацию. Все тактирование с инициализацией пинов уже прописано....Ладно, попробую каждый порт по одному протестить, а затем буду совмещать 2 порта и так далее....я тоже читал, что по умолчанию несколько портов у stm32 заняты....очень неудобно, когда лишнего на демоплате много -_-
Re: Несколько USART на STM32F4
Тут речь не то что у stm32 что занято, а именно что на демо-платах к пину уже подключено некое устройство. К устройству подведено питание, т.е. оно как-то работает и вполне может вносить на пин что-то свое.
Собственно, в Вашем коде отсутствуют функции инициализирующие USART6 и его прерываний, что также может вызывать сомнения в правильности включения онных. Там также тактирование портов и периферии включается через разные RCC_APB1 или RCC_APB2 (RCC_APB1 или RCC_APB2). Не через ту включил и ничего не работает.
Вот нашел пример инициализации, вроде как даже для самого Discovery и должен работать (остается только прерывание добавить):
P.S. Но я бы все-таки выбрал полностью свободные интерфейсы, слава богу, их там навалом.
Собственно, в Вашем коде отсутствуют функции инициализирующие USART6 и его прерываний, что также может вызывать сомнения в правильности включения онных. Там также тактирование портов и периферии включается через разные RCC_APB1 или RCC_APB2 (RCC_APB1 или RCC_APB2). Не через ту включил и ничего не работает.
Вот нашел пример инициализации, вроде как даже для самого Discovery и должен работать (остается только прерывание добавить):
Код: Выделить всё
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f4xx.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
/* Enable GPIOC clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/* Enable USART6 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
/* Configure port as pushpull, 50MHz and No pull up & down */
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/* Configure PC6 as alternate function */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure PC7 as alternate function */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Connect PC6 to USART6_Tx*/
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);
/* Connect PC7 to USART6_Rx*/
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);
/* USART6 configured as follow:
- BaudRate = 115200 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* USART configuration */
USART_Init(USART6, &USART_InitStructure);
/* Enable USART */
USART_Cmd(USART6, ENABLE);
/* Output a message on Hyperterminal using printf function */
printf("\n\rUSART Printf Example: retarget the C library printf function to the USART\n\r");
while (1)
{
int ch;
while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_RXNE) == RESET);
ch = USART_ReceiveData(EVAL_COM1);
printf("%c", ch&0xff);
}
}
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(EVAL_COM1, (uint8_t) ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TC) == RESET);
return ch;
}
P.S. Но я бы все-таки выбрал полностью свободные интерфейсы, слава богу, их там навалом.
Re: Несколько USART на STM32F4
Хорошо,большое спасибо, почитаю про свободные пины, переназначу порты и протестирую.
-
- Сообщения: 10
- Зарегистрирован: Пн окт 19, 2015 10:43 am
Несколько USART на STM32F4
Я новичок в работе с данными контроллерами.
Вопрос состоит в следующием:
Можно ли использовать вывод XCK USART External Clock Input/Output
как порт ввода/вывода, если у меня USART работает в асинхронном режиме?
Вопрос состоит в следующием:
Можно ли использовать вывод XCK USART External Clock Input/Output
как порт ввода/вывода, если у меня USART работает в асинхронном режиме?
Вернуться в «Микроконтроллеры и автоматизация»
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя