cancel
Showing results for 
Search instead for 
Did you mean: 

Wrong register BRR in usart

maxime
Associate II
Posted on July 30, 2014 at 15:16

Hi,

I'm trying to initialize a usart, and read some data on a Terminal. The terminal receives some data but not the good one. The problem seems to be a clock problem, and the usart register BRR looks wrong. Moreover, in the terminal settings, it reeds the rated speed at 115200 instead of 57600 and even if i change the baudrate in the usart init, the terminal still read 115200.

Any idea what could be the problem ?

Thanks

#stm32f105 #stm32f105-usb-host
11 REPLIES 11
Posted on July 30, 2014 at 16:26

It looks wrong, but you can't tell us what it is?

It should be a function of the APBx clock the USART is attached too. The BRR might be wrong if the HSE_VALUE doesn't match the external crystal on the board, or related PLL settings.

The terminal program will just tell you what you selected as a baud rate for the COM port.

Have the STM32 send a repetitive stream of data, say 'U' or 0x55, get a SCOPE, and MEASURE the bit timings. If these appear wrong, step back and look at the clocks being supplied to the part, and output internal clocks via MCOx pins, and MEASURE those.

For a 36 MHz APB clock I'd expect BRR for a 115200 baud clock to be 312 or 313

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
maxime
Associate II
Posted on July 30, 2014 at 16:58

Thanks for the answer,

here is the code :

#define UART_USER                                USART2

#define USART_USER_TB_TX                         GPIO_Pin_2

#define USART_USER_TB_PIN_SOURCE_TX             GPIO_PinSource2

#define USART_USER_TB_RX                         GPIO_Pin_3

#define USART_USER_TB_PIN_SOURCE_RX             GPIO_PinSource3

#define USART_USER_TB_GPIO_PORT                 GPIOA

#define PERIF_CLOCK_USART_TB_USER                 RCC_APB1Periph_USART2

#define PERIF_CLOCK_PINS_USART_TB_USER             RCC_APB2Periph_GPIOA

void uart_init_user()

{

    GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as TX and RX

    USART_InitTypeDef USART_InitStruct; // this is for the USART1 initilization

    NVIC_InitTypeDef NVIC_InitStructure; // this is used to configure the NVIC (nested vector interrupt controller)

    RCC_APB1PeriphClockCmd(PERIF_CLOCK_USART_TB_USER, ENABLE);

    RCC_APB2PeriphClockCmd(PERIF_CLOCK_PINS_USART_TB_USER, ENABLE);

    GPIO_InitStruct.GPIO_Pin = USART_USER_TB_TX;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // the pins are configured as alternate function so the USART peripheral has access to them

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(USART_USER_TB_GPIO_PORT, &GPIO_InitStruct);

    GPIO_InitStruct.GPIO_Pin = USART_USER_TB_RX;

    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init(USART_USER_TB_GPIO_PORT, &GPIO_InitStruct);

    USART_InitStruct.USART_BaudRate = 57600; // the baudrate is set to the value we passed into this init function

    USART_InitStruct.USART_WordLength = USART_WordLength_8b;// we want the data frame size to be 8 bits (standard)

    USART_InitStruct.USART_StopBits = USART_StopBits_1; // we want 1 stop bit (standard)

    USART_InitStruct.USART_Parity = USART_Parity_No; // we don't want a parity bit (standard)

    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard)

    USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver

    USART_Init(UART_USER, &USART_InitStruct);

    USART_ITConfig(UART_USER, USART_IT_RXNE, ENABLE); // enable the usart receive interrupt

    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // this sets the priority group of the USART1 interrupts

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // this sets the subpriority inside the group

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART interrupts are globally enabled

    NVIC_Init(&NVIC_InitStructure); // the properties are passed to the NVIC_Init function which takes care of the low level stuff

    USART_Cmd(UART_USER, ENABLE);

}

I think all the init function is good, what do you think ?

My HSE_VALUE is 12MHz, so BRR should be equal to 209. I've 200. It is a problem ?

I send 'a', 'b', 'c' ... 'j' and i receive '..j.+....j.+..'

Posted on July 30, 2014 at 18:40

It's suggestive that it thinks the APB clock is 11520000 Hz

RCC_ClocksTypeDef RCC_ClocksStatus;
RCC_GetClocksFreq(&RCC_ClocksStatus);
printf(''%d %d
'',RCC_ClocksStatus.PCLK1_Frequency, RCC_ClocksStatus.PCLK2_Frequency);

Can you ZIP up a small and complete project (for Keil, IAR or GNU/GCC), including the system_stm32f10x.c file and any PLL settings.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
maxime
Associate II
Posted on July 31, 2014 at 08:53

I will zip my project, but you talk about PLL settings, are they not call in the system_stm32f1x.c file ?

________________

Attachments :

workspace.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0Z8&d=%2Fa%2F0X0000000baS%2FWbEHFpv1V.r2.7m1c_MVMNEegdHhDUs0WucwCF_iivE&asPdf=false
maxime
Associate II
Posted on July 31, 2014 at 09:10

In system_stm32f10x.c, the function configure PLL1 and PLL2 but enable just PLL2. Shall I enable PLL aswell ?

#ifdef STM32F10X_CL
/* Configure PLLs ------------------------------------------------------*/
/* PLL configuration: PLLCLK = PREDIV1 * 9 = 36 MHz */
RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
RCC_CFGR_PLLMULL9); 
/*!< PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
/* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */
RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10);
/* Enable PLL2 */
RCC->CR |= RCC_CR_PLL2ON;
/* Wait till PLL2 is ready */
while
((RCC->CR & RCC_CR_PLL2RDY) == 0)
{
}

maxime
Associate II
Posted on July 31, 2014 at 09:38

RCC_ClocksTypeDef RCC_ClocksStatus;
RCC_GetClocksFreq(&RCC_ClocksStatus);

When I look at RCC_ClocksStatus, I have : SYSCLK = 23MHz HCLK = 23MHz PCLK1 = 11520000 PCLK2 = 23Mhz ADCCLK = 11520000
Posted on July 31, 2014 at 17:37

Most of your object files suggest HSE_VALUE is 8000000

printf(''%d '', HSE_VALUE); You should probably adjust your PLL setting, so as not to assume a 25 MHz crystal

#ifdef STM32F10X_CL
/* Configure PLLs ------------------------------------------------------*/
/* PLL configuration: PLLCLK = PREDIV1 * 9 = 36 MHz - where PREDIV1 is 4 MHz, see below */
RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
RCC_CFGR_PLLMULL9);
/*!< 
PLL2
configuration: PLL2CLK = (HSE / 3) * 
10
= 
40
MHz - where HSE is 12 MHz */
/* PREDIV1 configuration: 
PREDIV1CLK
= 
PLL2
/ 
10
= 
4
MHz */
RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV3 | RCC_CFGR2_PLL2MUL10 |
RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10);
/* Enable PLL2 */
RCC->CR |= RCC_CR_PLL2ON;
/* Wait till PLL2 is ready */
while((RCC->CR & RCC_CR_PLL2RDY) == 0)
{
}

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on July 31, 2014 at 17:46

The actual speed you're running at is

((((12 / 5) * 😎 / 10) * 9) = 17.28 MHz

The machine thinks you're running at

((((8 / 5) * 😎 / 10) * 9) = 11.52 MHz

The discrepancy here means your baud clock is wrong. You could measure the 17.28 MHz at the MCO pin if you tried.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on July 31, 2014 at 17:49

((((12 / 3) * 10) / 10) * 9) = 36.00 MHz

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..