Erratic USART behaviour using KEIL 5 Compiler
Hi All,
I have a project that currently has a blinky, 2 ADC channel on DMA circular which were successfully working .
I have now implemented the USART2 on IRQ on my STM32F302 Nucleo. The USART2 is running at 32Mhz and 9600 baud. I have set up the USARt to echo back what I send from the PC.
As soon as I tried to implement the UART I started having issues.
1 - The characters echoed are not what I sent from my PC. I have tried changing the compiler setting in Keil 5. I changed the optimizations settings on the C/C++ tab from Level 0 to default. This helped somewhat but I still get back some random characters.
Furthermore, when I set it to default I cannot debug properly as the debugger seems to get stuck at some lines.
2 - My blinky also stops working which is odd
/*---------------------------------------------------------------------------------------------------------------
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;
void SysTick_Handler(void)
{
TimingDelay--;
}
void Delay (uint32_t nTime)
{
TimingDelay = nTime;
while (TimingDelay !=0);
}
int init ()
{
//---------------------- RCC Clock Initalization ------------------------------------------------------------------
RCC->CR = 0x1; //HSI on
while((RCC->CR & RCC_CR_HSIRDY) != RCC_CR_HSIRDY); // Waiting for HSI 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->CFGR = RCC_CFGR_PLLSRC_HSI_DIV2 | RCC_CFGR_PLLMUL16 | RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE1_DIV2; //PLLSCR = HSI/2 , PLLMUL = x16 (64Mhz),AHB prescaler not devided, APB1 Clock /2 = 32MHz (Max=32MHz)
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
//---------------------- DMA Initialization -------------------------------------------------------------------
RCC->AHBENR |= RCC_AHBENR_DMA1EN; // DMA1 Enabled
//---------------------- 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 != 64000000) // Error Handling
{
GPIOB->BSRR = (1<<2) ;
}
//--------------------------- ADC Configuration ----------------------------------------------------------------
// ADC running off sysclock at 64Mhz, with mininum cycles for conversion to ensure maximum speed
ADC1_COMMON->CCR = 0x0; // Resetting CKMODE
RCC->CFGR2 = RCC_CFGR2_ADC1PRES_DIV12; // ADC Prescaler /1 i.e. ADC Clock = 64Mhz
RCC->AHBENR |= RCC_AHBENR_ADC1EN; // Enable ADC1 clock
ADC1_COMMON->CCR = 0x0; // Resetting CKMODE
GPIOB->MODER |= 0x0000000F; // GPIOB PB1 set to Analog Mode ADC1_IN12, ADC1_IN11
// Calibration procedure
ADC1->CR &= ~ADC_CR_ADVREGEN;
ADC1->CR |= ADC_CR_ADVREGEN_0; // ADC Voltage regulator enabled
for(x=0;x<500;x++); // Delay for ADC to stabilize
ADC1->CR &= ~ADC_CR_ADCALDIF; // calibration in Single-ended inputs Mode.
ADC1->CR |= ADC_CR_ADCAL; // Start ADC calibration
// Read at 1 means that a calibration in progress.
while (ADC1->CR == (ADC1->CR & ADC_CR_ADCAL)); // wait until calibration done
calibration_value = ADC1->CALFACT; // Get Calibration Value ADC1
ADC1->CR |= ADC_CR_ADEN; // Enable ADC1
while(!ADC1->ISR & ADC_ISR_ADRD); // wait for ADRDY
ADC1->SQR1 = 0xB301; // Channel 12 first, Channel 11 second, two in sequence
ADC1->SMPR2 = 0x0; // Channel 11 and 12 Minimum conversion time
ADC1->CFGR = ADC_CFGR_DMAEN | ADC_CFGR_DMACFG | ADC_CFGR_CONT; // ADC DMA Enableed and set to circular mode and ADC in continous mode
DMA1_Channel1->CPAR = (uint32_t)(&(ADC1->DR)); // Passing the pheripheral address of the data register into DMA Channel 1
DMA1_Channel1->CMAR = (uint32_t)ADC_Samples; // Passing the address of the arry to store the data in
DMA1_Channel1->CNDTR = 2; // " sets of data being passed
DMA1_Channel1->CCR |= DMA_CCR_CIRC | DMA_CCR_MINC | DMA_CCR_PSIZE_0 | DMA_CCR_MSIZE_0; // Channel 1 Circular Mode, Memory Increment , P size = 16bit, M size = 16 bit
DMA1_Channel1->CCR |= DMA_CCR_EN; // Enabling DMA
ADC1->CR |= ADC_CR_ADSTART; // Start ADC1 Software Conversion
//------------------------------------ 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 P24, PA3 as alternate function mode
GPIOA->AFR[0] = 0x7700; // Alternate Functions USART 2 For PA2, PA3
USART2->BRR = 0xD05; // 32MHz / 9600
USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE | USART_CR1_TXEIE; // Transmit Enable, Revive Enable, RX not empty Int Enable, TX not empty Int Enable
USART2->CR1 |= USART_CR1_UE; // Uart Enable
NVIC_EnableIRQ(USART2_IRQn); // Enabling USART2 interrupt
return(0);
}
int main()
{
init();
while (1)
{
GPIOB->BSRR = (1<<2) ;
for ( x = 0; x<5000; x++)
{
}
GPIOB->BSRR = (1<<(2+16));
for ( x = 0; x<5000; x++)
{
}
}
}
void USART2_IRQHandler(void)
{
if (USART2->ISR & USART_ISR_RXNE)
{
char temp = USART2->RDR;
USART2->TDR = temp;
while(!(USART2->ISR & USART_ISR_TC));
}
if (USART2->ISR & USART_ISR_TXE)
{
}
}Do you guys have any ideas on might have cause this?
Thanks,
Glenn