Несколько USART на STM32F4

Syscall
Сообщения: 7
Зарегистрирован: Чт май 21, 2015 8:07 am

Несколько USART на STM32F4

Сообщение Syscall » Пт янв 15, 2016 8:11 am

Ребят, подскажите пожалуйста, реальна ли одновременная работа 2х - 4х USART с прерываниями по приему ? У меня два USART работают, а при инициализации третьего прерывание по приему не происходит....не знаю в чем дело, подскажите. Нужен будет код - прикреплю. Заранее спасибо :D :D :lol:

dtvims
Site Admin
Сообщения: 135
Зарегистрирован: Пн авг 02, 2010 2:43 pm

Re: Несколько USART на STM32F4

Сообщение dtvims » Пт янв 15, 2016 9:27 am

Насколько помню у STM32 часто на несколько интерфейсов или событий часто одно прерывание, которое и срабатывает, а программист должен по флагам определить, что именно сработало.
Возможно забыли включить прерывание для одного UART`а. Опять же все включать надо (зато если не включать - экономится энергия).
Без кода конечно не понятно...

UPD. Вспомнил еще, что некоторые порты могут быть по умолчанию на что-то еще инициализированы, например JTAG, тогда надо отключать или переносить на другие пины. У Вас вообще этот UART работает?

Syscall
Сообщения: 7
Зарегистрирован: Чт май 21, 2015 8:07 am

Re: Несколько USART на STM32F4

Сообщение Syscall » Пт янв 15, 2016 12:47 pm

Код: Выделить всё

/* 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 прерывания на них...было бы интересно узнать, работает ли оно так вообще. Заранее спасибо :D

dtvims
Site Admin
Сообщения: 135
Зарегистрирован: Пн авг 02, 2010 2:43 pm

Re: Несколько USART на STM32F4

Сообщение dtvims » Пт янв 15, 2016 1:33 pm

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. К тому же сразу не ясно, если у Вас все сейчас работает, не убьется ли что потом. Можно физически отрезать дорожку мешающего устройства.
Если порт занят отладчиком, то тут проще: снимаем перемычки отладчика и программно, в начале инициализации периферии, отключаем отладочные интерфейсы.
В этом недостаток демо-отладочных плат - уже куча доп. периферии, которая Вам не нужна, а использовать занятые порты очень хочется.

Syscall
Сообщения: 7
Зарегистрирован: Чт май 21, 2015 8:07 am

Re: Несколько USART на STM32F4

Сообщение Syscall » Пт янв 15, 2016 2:50 pm

В ссылке на библиотеку там все есть, помимо сторонней библиотеки на USART там есть еще остальные библиотеки. Что странно, что USART 3 и USART 1 работают исправно. USART 6 и остальные усарты инициализацию проходят, после нее пишут сообщение в порт о том, что они инициализировались, но данные не принимают, то есть прерывания для них не срабатывают. В ссылке на сторонние библиотеки к stm32f4 всю инициализацию можно увидеть для каждого инициализацию. Все тактирование с инициализацией пинов уже прописано....Ладно, попробую каждый порт по одному протестить, а затем буду совмещать 2 порта и так далее....я тоже читал, что по умолчанию несколько портов у stm32 заняты....очень неудобно, когда лишнего на демоплате много -_-

dtvims
Site Admin
Сообщения: 135
Зарегистрирован: Пн авг 02, 2010 2:43 pm

Re: Несколько USART на STM32F4

Сообщение dtvims » Пт янв 15, 2016 2:59 pm

Тут речь не то что у stm32 что занято, а именно что на демо-платах к пину уже подключено некое устройство. К устройству подведено питание, т.е. оно как-то работает и вполне может вносить на пин что-то свое.
Собственно, в Вашем коде отсутствуют функции инициализирующие 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. Но я бы все-таки выбрал полностью свободные интерфейсы, слава богу, их там навалом.

Syscall
Сообщения: 7
Зарегистрирован: Чт май 21, 2015 8:07 am

Re: Несколько USART на STM32F4

Сообщение Syscall » Пт янв 15, 2016 3:59 pm

Хорошо,большое спасибо, почитаю про свободные пины, переназначу порты и протестирую. :D

MoskKsusBiz
Сообщения: 10
Зарегистрирован: Пн окт 19, 2015 10:43 am

Несколько USART на STM32F4

Сообщение MoskKsusBiz » Пт янв 29, 2016 9:44 pm

Я новичок в работе с данными контроллерами.
Вопрос состоит в следующием:

Можно ли использовать вывод XCK USART External Clock Input/Output
как порт ввода/вывода, если у меня USART работает в асинхронном режиме?

dtvims
Site Admin
Сообщения: 135
Зарегистрирован: Пн авг 02, 2010 2:43 pm

Re: Несколько USART на STM32F4

Сообщение dtvims » Вт фев 02, 2016 2:25 pm

Можно


Вернуться в «Микроконтроллеры и автоматизация»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя