cancel
Showing results for 
Search instead for 
Did you mean: 

Higher than 921600 baud does not work stm32f4Discovery

michaelmccartyeng
Associate II
Posted on March 11, 2014 at 00:15

Hello All,

I'm communicating with a wifi module that uses a stm32 internally and it supports up to 2073600. I can use that baud rate with usb to uart adapter and communicate with the wifi module but when I put my stm32f4 discovery any higher than 921600 it does not seem to work. Is it possible to achieve this speed ? Thanks !

void setupCommUart(int baud)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// init clocks 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
//110, 150, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
USART_InitStructure.USART_BaudRate = baud;
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_Init(USART2, &USART_InitStructure);
// enable usart
USART_Cmd(USART2, ENABLE);
}

#discovery #stm32f4 #uart
20 REPLIES 20
michaelmccartyeng
Associate II
Posted on March 16, 2014 at 03:42

USART2 uses APB1, 42,000,000 hz. That divided by 16 is 2,625,000. So I should be able to reach the maximum desired baud rate at 2073600.

I tested 2073600 between my usb/uart to the wifi device using the uart at that rate. It works.

Then I test from my stm32f4 discovery to the uart, I see the RX light but see nothing on the screen (in putty). Tested several times. Also set BP on RX in keil and tried to get it to break by sending data, no go. Then without shutting down anything I re plugged it into the wifi module already talking at that baud and it worked fine.

I must be doing something right or it would not work at the other baud rates ?

Tried that function you suggest

    RCC_GetClocksFreq(&rcc_clocks);

sysclk = 84000000

hclk = 84000000

PCLK1 = 21000000

PCLK2 = 42000000

I think that means I'm running at 84MHz not 168MHz, so that would mean my max baud is

21000000/16 = 1312500 which makes perfect sense !

Am I right in all this is pclk1 and pclk2 apb1 and apb2 ? and sysclk is the actual clock at which everything runs ?

If so do you have any idea how I can change it to 168MHz? I need to get smarter about the stm32 clocking situation. It has left me stumped quite a few times. I had set up clocks in the PIC years ago and understood how the different pieces fit together to form the system clock, similar to the tim setup.

Let me know if I'm on the right track and I'll continue down it.

michaelmccartyeng
Associate II
Posted on March 16, 2014 at 04:00

Reading the top of the system_stm32f4xx.c file I see it references 25 as the value to use for PLL_M. I was previosly using But when I change it to 25 I get a system clock of 53,760,000 and of course nothing works because lower down I can see

#if defined (STM32F40_41xxx) uint32_t SystemCoreClock = 168000000; #endif /* STM32F40_41xxx */ and I have defined STM32F40_41xxx

/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 25
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7
#if defined (STM32F40_41xxx)
#define PLL_N 336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
#endif /* STM32F40_41xxx */
#if defined (STM32F427_437xx) || defined (STM32F429_439xx)
#define PLL_N 360
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
#endif /* STM32F427_437x || STM32F429_439xx */
#if defined (STM32F401xx)
#define PLL_N 336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 4
#endif /* STM32F401xx */

I'm using the stm32f4 discovery board so I'm not sure if I should have those defines. The only other user configurable thing seems to be __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; In the project options I have defined ''Xtal (MHz)'' as 8.0. And the only xtals I see on the board are 8MHz. Unless there is a small surface mount one somewhere. X3 is not populated on my board. This is going to be so awesome if I can get this to work, I cant believe I've only been going at half speed this whole time !
Posted on March 16, 2014 at 08:42

A PLL_M value of 16 would suggest the code is using the HSI as a clock source, the Discovery board has a 8 MHz HSE source, either from X3, or from the 8 MHz PA8/MCO output of the ST-LINK interface chip (F103). In the latter case the HSE should be in BYPASS mode.

Selecting specific high baud rates is going to depend on how effective the clock division is. Once you have set a value in the BRR (Baud Rate Register) you need to then work the math backward to compute the actual baud rate achieved, and then express that as a percentage to understand how far it deviates from the ideal. To hit specific high values you might have to carefully select crystals, or PLL settings to hit ''magic'' values which divide cleanly/effectively.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on March 16, 2014 at 08:43

A PLL_M value of 16 would suggest the code is using the HSI as a clock source, the Discovery board has a 8 MHz HSE source, either from X3, or from the 8 MHz PA8/MCO output of the ST-LINK interface chip (F103). In the latter case the HSE should be in BYPASS mode.

Selecting specific high baud rates is going to depend on how effective the clock division is. Once you have set a value in the BRR (Baud Rate Register) you need to then work the math backward to compute the actual baud rate achieved, and then express that as a percentage to understand how far it deviates from the ideal. To hit specific high values you might have to carefully select crystals, or PLL settings to hit ''magic'' values which divide cleanly/effectively.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
michaelmccartyeng
Associate II
Posted on March 16, 2014 at 17:35

int main(void)
{
RCC_ClocksTypeDef rcc_clocks;
// this is for testing basic stuff and ''nothing'' else
//testLoop(); 
RCC_HSEConfig(RCC_HSE_Bypass);
while(!RCC_WaitForHSEStartUp())
{
}
RCC_GetClocksFreq(&rcc_clocks);
// init all Zsystems
startupSystems(); 
g_BotState = STATE_NEW; // start stream in uninit mode
while(1)
doTasks();
}

I was using HSE_ON, switched to bypass and get the same exact behavior. I'll try and use the excel spreadsheet and see if I get anywhere.
Posted on March 17, 2014 at 00:07

2073600 84000000 / 40 = 2100000 1.27 % error
2073600 42000000 / 20 = 2100000 1.27 % error
2073600 83000000 / 40 = 2075000 0.07 % error
2073600 41500000 / 20 = 2075000 0.07 % error

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
michaelmccartyeng
Associate II
Posted on March 17, 2014 at 02:34

Sorry, but I really dont understand what you mean. I'm going to read over the ''RM0090''. I always assumed the discovery was always running at 168MHz. Now I dont even know if it can unless I use another crystal. I thought it was some easy settings change.

Tried loading up the excel spreadsheet but it just freezes excel. I'm going to try it on a newer version of excel.

Posted on March 17, 2014 at 13:12

I was trying to impart the rate error for the baud settings, based on APB clocks, and how that might be improved.

The STM32F4-DISCO should definitely run at 168 MHz, with APB2 @ 84 MHz, and APB1 @ 42 MHz. If yours is not you might want to take the stm32f4xx_conf.h and system_stm32f4xx.c from the template project.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
michaelmccartyeng
Associate II
Posted on March 17, 2014 at 16:39

Thanks Clive,

If I start to see high error rates I'll look into the clock rate settings. I did read the datasheet and understand what a lot of the bits in the rcc control registers mean. I was able to get it to run at 168MHz, I got excel 2007 (not 2003) and used the spreadsheet provided by stm. I was following the instructions here http://clockspeeds.blogspot.com/2013/01/stm32f4-discovery-clock-frequency.html Basically you download the excel spreadsheet from stm AN39 Change hclk to the desired fq (168MHz in my case) then click run, I selected HSI, then click generate. After enabling macros in excel of course. It gave me these values which are working for the baud of 2,073,600

/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 16
#define PLL_N 336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7

This is going to make things so much faster ! Including the rate at which my battery drains I'm sure ! Thanks again!
ingjohn
Associate II
Posted on November 11, 2015 at 21:52

Hi clive1, I have a problem with a STM32F40, trying to communicate with a baud rate of 1200 in the uart4, only get me the first character, change to 9600 when everything works. I am afraid that the problem is the clocks HCLK is 168hz, APB1 42MHz and APB2 84Mhz,

how should configure the microcontroller so you can communicate at this speed? What else should check? Thanks