cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 and USART issues

simo zz
Senior
Posted on November 07, 2017 at 23:41

Hello,

I am trying to run a custom example of USART6 transmitter from the STM32F4 Discovery (so using an STM32F407VGT) and I am having problems since I only see garbage characters like '�' through the PC serial console (Putty or screen).

The source code I am testing is the following one:

#include <stm32f4xx.h>
volatile uint8_t flag;
void EXTI0_IRQHandler(void)
{
 //USART_SendData(USART6, 0xaa);
 if(EXTI_GetITStatus(EXTI_Line0) != RESET)
 {
 // keep the ISR as short as possible
 // set the flag and go out
 USART_SendData(USART6, 0x41);
 EXTI_ClearITPendingBit(EXTI_Line0);
 }
}
int main(void)
{
 // GPIO, NVIC and EXTI declarations
 GPIO_InitTypeDef gpio_t;
 USART_InitTypeDef usart_t;
 //USART_ClockInitTypeDef usart_clk_t;
 NVIC_InitTypeDef nvic_t;
 EXTI_InitTypeDef exti_t;
 RCC_DeInit();
 // Enable resonator frequency
 RCC_HSEConfig(RCC_HSE_ON);
 while (!RCC_WaitForHSEStartUp())
 ;
 //RCC_PLLCmd(DISABLE);
 //RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)
 RCC_PLLConfig(RCC_PLLSource_HSE, 4, 50, 2, 1);
 RCC_PLLCmd(ENABLE);
 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) != SET)
 ;
 // Configure AHBP Clock
 RCC_HCLKConfig(RCC_SYSCLK_Div1);
 // set APB2 clock divider (PPRE2 bits)
 RCC_PCLK2Config(RCC_HCLK_Div2);
 // Sys clock config is the PLL
 RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);
 //RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
 SystemCoreClockUpdate();
 // Enable SYSCFG and USART6 Clock
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG | RCC_APB2Periph_USART6, ENABLE);
 // Enable GPIOA and GPIOC Clock
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE);
 // configure GPIOA_0 as input
 gpio_t.GPIO_Pin = GPIO_Pin_0;
 gpio_t.GPIO_Mode = GPIO_Mode_IN;
 //gpio_t.GPIO_OType = GPIO_OType_PP;
 gpio_t.GPIO_Speed = GPIO_Speed_100MHz;
 GPIO_Init(GPIOA, &gpio_t);
 // configure GPIOC_6 to AF USART6 Tx
 // Configure port as pushpull, 50MHz and No pull up & down
 //gpio_t.GPIO_OType = GPIO_OType_PP;
 //gpio_t.GPIO_PuPd = GPIO_PuPd_NOPULL;
 //gpio_t.GPIO_Speed = GPIO_Speed_2MHz;
 // Configure PC6 as alternate function
 gpio_t.GPIO_Pin = GPIO_Pin_6;
 gpio_t.GPIO_Mode = GPIO_Mode_AF;
 GPIO_Init(GPIOC, &gpio_t);
 // Configure PC7 as alternate function
 gpio_t.GPIO_Pin = GPIO_Pin_7;
 gpio_t.GPIO_Mode = GPIO_Mode_AF;
 GPIO_Init(GPIOC, &gpio_t);
 /* 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);
 usart_t.USART_BaudRate = 115200;
 usart_t.USART_WordLength = USART_WordLength_8b;
 usart_t.USART_StopBits = USART_StopBits_1;
 //usart_t.USART_Parity = USART_Parity_No;
 usart_t.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
 usart_t.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
 USART_Init(USART6, &usart_t);
 USART_Cmd(USART6, ENABLE);
 // Configure external interrupt for PA0
 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
 exti_t.EXTI_Line = EXTI_Line0;
 exti_t.EXTI_Mode = EXTI_Mode_Interrupt;
 exti_t.EXTI_Trigger = EXTI_Trigger_Rising;
 exti_t.EXTI_LineCmd = ENABLE;
 EXTI_Init(&exti_t);
 // enable EXTI0 interrupt for NVIC
 nvic_t.NVIC_IRQChannel = EXTI0_IRQn;
 nvic_t.NVIC_IRQChannelPreemptionPriority = 0;
 nvic_t.NVIC_IRQChannelSubPriority = 0;
 nvic_t.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&nvic_t);
 flag = 1;
 while(1)
 {
 if(flag)
 {
 USART_SendData(USART6, 0x01);
 }
 }
 return 0;
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Even if the serial console configuration matches the USART configuration, I cannot receive the correct character.

Digital logic (both Tx and Rx side) is all working at 3V3, so the voltage threshold are OK.

The USART configuration is copied from the USART_HyperTerminal example of Standard Peripheral Libraries.

What's wrong or what more configuration I am missing in my code ? Thank you in advance.

Regards,

Simon

1 ACCEPTED SOLUTION

Accepted Solutions
simo zz
Senior
Posted on November 08, 2017 at 16:52

Solved !

The problem was in the definition of HSE into stm32f4xx.h.

 #if !defined (HSE_VALUE) 
 #define HSE_VALUE ((uint32_t) 8000000) /*!< Value of the External oscillator in Hz */
 #endif /* HSE_VALUE */�?�?�?�?�?�?

It is defined to 25 MHz. I changed to 8 MHz (since I am using this resonator value) as above and now everything works fine.

Simon

View solution in original post

8 REPLIES 8
simo zz
Senior
Posted on November 08, 2017 at 11:31

One strange thing I noticed, is that if I comment the settings for PC7 (AF USART6_TX) so commenting these lines:

// Configure PC7 as alternate function
gpio_t.GPIO_Mode = GPIO_Mode_AF;
gpio_t.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOC, &gpio_t);�?�?�?�?�?�?�?�?

the transmitter doesn't work.

If the USART is configured in TX mode only, the RX pin should be free to be used for other purposes. Shouldn't it ?

I suspect that the gcc compiler is not generating good code..

Simon

Andrew Neil
Evangelist
Posted on November 08, 2017 at 12:08

I only see garbage characters like '�' through the PC serial console

That usually means that the baud rate is wrong.

Have you checked what is actually happening on the pin - with an oscilloscope or logic analyser ?

Posted on November 08, 2017 at 12:33

Hello

Neil.Andrew

,

Andrew Neil wrote:

That usually means that the baud rate is wrong.

This is what I also suspect, but I am not totally sure about it.

Yes I do have an oscilloscope and I can see the transmitted signal on PC6 pin (USART6_TX).

Unfortunately I don't have a logic analyzer.

Simon

Posted on November 08, 2017 at 12:49

So does your 'scope confirm that the signal is correct?

In particular, the board rate?

Polarity ... ?

simo zz
Senior
Posted on November 08, 2017 at 14:35

Neil.Andrew

you are right. I could do better tests.

Sending a just a bit (0x01) at 115200 bps the pulse width is 25 us with leads to a wrong baudrate.

To ensure myself, I compared the pulse width with a USB/232 cable sending the same data at 115200, and pulse width is approx 9 us, which is correct.

I confirm the baud-rate is wrong.

simo zz
Senior
Posted on November 08, 2017 at 16:52

Solved !

The problem was in the definition of HSE into stm32f4xx.h.

 #if !defined (HSE_VALUE) 
 #define HSE_VALUE ((uint32_t) 8000000) /*!< Value of the External oscillator in Hz */
 #endif /* HSE_VALUE */�?�?�?�?�?�?

It is defined to 25 MHz. I changed to 8 MHz (since I am using this resonator value) as above and now everything works fine.

Simon

Posted on November 08, 2017 at 19:04

Hmm ... I guess someone thought they were being 'helpful' with that - but silently providing an arbitrary default like that is almost certainly

not

helpful!!

It would have been far more helpful to do something like:

 #if !defined (HSE_VALUE) 
 #error 'HSE_VALUE must be definedasthe External oscillator frequency, in Hz'
 #endif /* HSE_VALUE */

Posted on November 08, 2017 at 19:06

Note that an easier way to test serial comms is to continuously send 'U' - since that gives a nice ...1010101... pattern which is easy to see on a 'scope.