2019-05-19 07:01 AM
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
2019-05-19 08:02 AM
Make sure
#define HSE_VALUE 16000000
Often in stm32f3xx_conf.h, or similar
2019-05-19 08:41 AM
I have chnged both that and the " options for target 1 " in keil to no avail
2019-05-19 09:31 AM
I did update the HSE_VALUE to reflect what I have but that did not fix it.
The mistake was in line 44 and 43. I removed the CFGR 2 line and added the following to line 44 | RCC_CFGR_PLLXTPRE_HSE_PREDIV_DIV2. That was my main issue.
I also had another little mistake in the last while loop of the RCC Init but that was not the issue.
I was setting CFGR2 as the pre div inas seen below, as it says it is the same as CFGR, however when I set CFGR1 instead and removed the statement of CFGR2 it all worked well. A bit confusing but figured it out now thanks to your help.
Edit: On second thought I had tried the PLLXTPRE thing before and it didin't work so I think it was the change in definition and putting PLLXTPRE in again together