STM32L151C8T6 USART1 works from time to time
Hello.
I'm using STM32L151C8T6 for some simple task. In the beginning I used MSI clock and everything was fine. But I decided to switch to HSI and now I got problems using USART1, namely I think that the USART1 periphery isn't properly initialized due to some clock problem.
If I use the debugger and I'm watching the USART1 registers, then my program works fine. If I switch to monitor the CPU registers for example, then my program got stuck in my implementation of fputc(). All data for the USART1 registers is 0x00. I guess that something went wrong moving my code to HSI from MSI. Below is the code.
void main() {
sysinit();
Dummy_USART_Init(); // #include "usart.h"
setupIWDG();
IWDGReset = isIWDGReset();
//some code to read/write variables from the EEPROM
while(1) {
/*...*/
}
}
void sysinit() {
RCC_DeInit();
RCC_HSICmd(ENABLE); //16MHz, ADC requirement // TODO: The ADC HSI need at least 1.5V core!! check for bugs! BUGBUG
while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);
RCC_SYSCLKConfig( RCC_SYSCLKSource_HSI ); // MSI, HSI, HSE or PLL
while(RCC_GetSYSCLKSource() != 0x04);
RCC_HCLKConfig( RCC_SYSCLK_Div1 ); // AHB clock = SYSCLK
RCC_PCLK1Config( RCC_HCLK_Div1 );
RCC_PCLK2Config( RCC_HCLK_Div1 ); //RCC_HCLK_Div1: APB2 clock = HCLK (from AHB clock)
//RCC_PLLConfig( RCC_PLLSource_HSI_Div2, RCC_PLLMul_6 );
//RCC_PLLCmd( ENABLE );
//RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK ); //use PLL as the SYSCLK clock source
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); //MISC in the help file...
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
RCC_ClocksTypeDef workingFreq;
RCC_GetClocksFreq(&workingFreq);
systicks = workingFreq.SYSCLK_Frequency / 1000;
SysTick_Config(systicks); //ticks - number of ticks btw. 2 interrupts
if(workingFreq.SYSCLK_Frequency > 1000000) {
sysTicksPerMs = systicks/(workingFreq.SYSCLK_Frequency/1000);
}
}void Dummy_USART_Init() {
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE );
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1, ENABLE );
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //push-pull output
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; //400kHz, 2,10,40 MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init( GPIOA, &GPIO_InitStructure );
GPIO_PinAFConfig( GPIOA, GPIO_PinSource9, GPIO_AF_USART1 );
GPIO_PinAFConfig( GPIOA, GPIO_PinSource10, GPIO_AF_USART1 );
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
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_DeInit( USART1 );
USART_Init( USART1, &USART_InitStructure );
USART_Cmd( USART1, ENABLE );
}Any advises would be helpful!
Edit: here is the fputc()
int fputc(int ch, FILE * f) { //file is defined in stdio.h; set library configuration to FULL
while( USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );
USART_SendData( USART1, (unsigned int) ch );
return ch;
}The TC and TXE flags in USART1 are always 0.
