Skip to main content
glenn0010
Associate III
May 19, 2019
Question

STM32F£02R8 Clcok Issue

  • May 19, 2019
  • 3 replies
  • 892 views

Hi All,

So I have trying to get the UART to work for a while and after looking at the lines with scope, I discovered the the uart is twice the Baud rate I programmed it to and I don't know why.

So I am running my uC of a 16MHz external crystal dividing that by 2 to get 8MHz at PLL input. Multiplying that by 9 to get 72MHz SYSCLK and then dividing that by 2 to get 36MHz APB!1clock which is the maximum.

After I do this I stole a function from the SDPherif Libraries to check that the clocks are indeed what I set them to and they are correct PCLK1 is 36MHz.

With the R8, the USART 2 clock source can only be PCLK1 as indicated by the datasheet and it cannot be changed.

Hence then I set my Baud rate by plugging in the following into the BRR register. 36000000/9600. However the baud rate comes out twice as fast.

So that means either:

1 - APB1 is running off 72MHz which is outside is spec

2 - The clock source for the UART2 is being used as the SYSCLK

Here is the code:

/*---------------------------------------------------------------------------------------------------------------
 
12/5/2019
 
SysCroeClock = 64Mhz
 
Blinky
ADC scaninng 2 channels continously in DMA Mode 1.5 conversiion cycles at 64Mhz
UART2 with interrupt running on clock of 32MHz at 9600 baud
---------------------------------------------------------------------------------------------------------------*/
 
 
 
 
#include "stm32f302x8.h"
 //----------------- Gloobal Variables -------------------------------------------------------------------------
uint16_t ADC_Samples[2] = {0,0};
void Delay (uint32_t nTime);
uint16_t ADC1ConvertedValue = 0;
uint16_t ADC1ConvertedVoltage = 0;
int calibration_value = 0;
volatile uint32_t TimingDelay = 0;
int x =0;
int 	CoreClock = 0;
 
 
static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
 
 uint32_t tmp = 0, presc = 0; 
 uint32_t hcklf = 0, pckl1f= 0; 
 
 
int init ()
{
	
	//---------------------- RCC Clock Initalization ------------------------------------------------------------------
 
	RCC->CR |= RCC_CR_HSEON; //HSE on
	while((RCC->CR & RCC_CR_HSERDY) != RCC_CR_HSERDY); // Waiting for HSE to be ready
 
	RCC->CR &= ~RCC_CR_PLLON; // Disable PLL
	while((RCC->CR & RCC_CR_PLLRDY)== RCC_CR_PLLRDY); // Wait for pll to turn off
	RCC->CFGR2 = RCC_CFGR2_PREDIV_DIV2; //HSE / 2 = 8MHz for PLL
	RCC->CFGR = RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PLLMUL9 | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE1_DIV2; //PLLSCR = HSE/2 , PLLMUL = x9 (72Mhz),AHB prescaler not devided, APB1 Clock /2 = 36MHz (Max=36MHz)
	RCC->CR |= 0x01000000; // Turn on PLL on
	while((RCC->CR & RCC_CR_PLLRDY) != RCC_CR_PLLRDY); // Waiting for PLL to be ready
	FLASH->ACR |= FLASH_ACR_LATENCY_1; // Adjust flash speed for new frequency
	RCC->CFGR |= RCC_CFGR_SW_1; // Set PLL as system clock
	while((RCC->CFGR & RCC_CFGR_SWS_1) != RCC_CFGR_SWS_1); // Wait fpr pll to be used as syste, clock
	
	
	
	//---------------------- Blinky Initialization ----------------------------------------------------------------
	
	RCC->AHBENR |= (1<<18); //Enabling AHB GPIOB
	 
 GPIOB->MODER |= 0x00000010; // PB2 Output
	GPIOB->OSPEEDR |= 0x0; // Low speed output on all of port B
 GPIOB->PUPDR |= 0x30; // PB2 pull down
 
	
	//----------------------- Checking System Clock ---------------------------------------------------------------
 SystemCoreClockUpdate(); // Calculating new system clock
	CoreClock = SystemCoreClock; 
	
	while (CoreClock != 72000000) // Error Handling
	{
		GPIOB->BSRR = (1<<2) ;
	}
 
	//------------------------------------ UART Enable -------------------------------------
	RCC->APB1ENR |= RCC_APB1ENR_USART2EN; // Enabling USART2 Clock
	RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // Enabling Port A
	
	GPIOA->MODER |= GPIO_MODER_MODER2_1 | GPIO_MODER_MODER3_1; // Setting PA2, PA3 as alternate function mode
	GPIOA->AFR[0] = 0x7700; // Alternate Functions USART 2 For PA2, PA3
 
	USART2->CR1 &= ~USART_CR1_M;
 USART2->BRR = 36000000/9600; // 36MHz / 9600
	USART2->CR2 = 0x0;
	USART2->CR1 |= USART_CR1_UE ;
	USART2->CR1 |= USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE; 
 	
	NVIC_EnableIRQ(USART2_IRQn); // Enabling USART2 interrupt
	 
	tmp = RCC->CFGR & RCC_CFGR_HPRE;
 tmp = tmp >> 4;
 presc = APBAHBPrescTable[tmp];
 /* HCLK clock frequency */
 hcklf = CoreClock >> presc;
 
 tmp = RCC->CFGR & RCC_CFGR_PPRE1;;
 tmp = tmp >> 8;
 presc = APBAHBPrescTable[tmp];
 /* PCLK1 clock frequency */
 pckl1f = hcklf >> presc;
	
	
	return(0);
	
}
int main()
{
 
	init();
 
	while (1)
	{
		
	 GPIOB->BSRR = (1<<2) ;
		for ( x = 0; x<500000; x++)
		{
		}
		GPIOB->BSRR = (1<<(2+16));
		for ( x = 0; x<500000; x++)
		{
		}
		
		USART2->TDR = 0x55;
	 while (!(USART2->ISR & USART_ISR_TC)){};				 
 
 
}
}
 
void USART2_IRQHandler(void)
{
	 if(USART2->ISR & USART_ISR_RXNE)
		{
			 char temp = USART2->RDR;
			 USART2->TDR = 0x55;
			 while (!(USART2->ISR & USART_ISR_TC)){};				 
		}
		
}
 

Thank you all for taking the time to help me

Cheers

This topic has been closed for replies.

3 replies

Tesla DeLorean
Guru
May 19, 2019

Make sure

#define HSE_VALUE 16000000

Often in stm32f3xx_conf.h, or similar

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
glenn0010
glenn0010Author
Associate III
May 19, 2019

I have chnged both that and the " options for target 1 " in keil to no avail