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

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

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

Сообщение Syscall »

Ребят, подскажите пожалуйста, реальна ли одновременная работа 2х - 4х USART с прерываниями по приему ? У меня два USART работают, а при инициализации третьего прерывание по приему не происходит....не знаю в чем дело, подскажите. Нужен будет код - прикреплю. Заранее спасибо :D :D :lol:
dtvims
Site Admin
Сообщения: 141
Зарегистрирован: Пн авг 02, 2010 2:43 pm

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

Сообщение dtvims »

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

UPD. Вспомнил еще, что некоторые порты могут быть по умолчанию на что-то еще инициализированы, например JTAG, тогда надо отключать или переносить на другие пины. У Вас вообще этот UART работает?
Syscall
Сообщения: 7
Зарегистрирован: Чт май 21, 2015 8:07 am

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

Сообщение Syscall »

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

/* 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
Сообщения: 141
Зарегистрирован: Пн авг 02, 2010 2:43 pm

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

Сообщение dtvims »

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 »

В ссылке на библиотеку там все есть, помимо сторонней библиотеки на USART там есть еще остальные библиотеки. Что странно, что USART 3 и USART 1 работают исправно. USART 6 и остальные усарты инициализацию проходят, после нее пишут сообщение в порт о том, что они инициализировались, но данные не принимают, то есть прерывания для них не срабатывают. В ссылке на сторонние библиотеки к stm32f4 всю инициализацию можно увидеть для каждого инициализацию. Все тактирование с инициализацией пинов уже прописано....Ладно, попробую каждый порт по одному протестить, а затем буду совмещать 2 порта и так далее....я тоже читал, что по умолчанию несколько портов у stm32 заняты....очень неудобно, когда лишнего на демоплате много -_-
dtvims
Site Admin
Сообщения: 141
Зарегистрирован: Пн авг 02, 2010 2:43 pm

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

Сообщение dtvims »

Тут речь не то что у 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 »

Хорошо,большое спасибо, почитаю про свободные пины, переназначу порты и протестирую. :D
MoskKsusBiz
Сообщения: 10
Зарегистрирован: Пн окт 19, 2015 10:43 am

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

Сообщение MoskKsusBiz »

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

Можно ли использовать вывод XCK USART External Clock Input/Output
как порт ввода/вывода, если у меня USART работает в асинхронном режиме?
dtvims
Site Admin
Сообщения: 141
Зарегистрирован: Пн авг 02, 2010 2:43 pm

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

Сообщение dtvims »

Можно
Ответить