#include
#include
// 1<=nus<=13107
void delay_us(uint16_t nus)
{
if ((RCC->APB1ENR2 & RCC_APB1ENR2_LPTIM2EN) == 0)
{
RCC->APB1ENR2 |= RCC_APB1ENR2_LPTIM2EN;
LPTIM2->CFGR = 4 << LPTIM_CFGR_PRESC_Pos; // 80MHz/16=5MHz
LPTIM2->CR = LPTIM_CR_ENABLE;
}
LPTIM2->ARR = nus * 5 - 1;
LPTIM2->CR |= LPTIM_CR_SNGSTRT;
while ((LPTIM2->ISR & LPTIM_ISR_ARRM) == 0);
LPTIM2->ICR = LPTIM_ICR_ARRMCF;
}
int fputc(int ch, FILE *fp)
{
if (fp == stdout)
{
if (ch == '\n')
{
while ((USART2->ISR & USART_ISR_TXE) == 0);
USART2->TDR = '\r';
}
while ((USART2->ISR & USART_ISR_TXE) == 0);
USART2->TDR = ch;
}
return ch;
}
void set_clock(void)
{
RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
PWR->CR1 |= PWR_CR1_DBP; // Allow access to the backup area register
// Open LSE
if ((RCC->BDCR & RCC_BDCR_LSEON) == 0)
{
RCC->BDCR |= RCC_BDCR_LSEON;
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0); // Wait for LSE to stabilize
}
RCC->CR |= RCC_CR_MSIPLLEN; //MSI uses LSE to calibrate MSI
//Configure PLL: MSI/M*N/R=4MHz/1*40/2=80MHz
RCC->PLLCFGR = RCC_PLLCFGR_PLLREN | (40 << RCC_PLLCFGR_PLLN_Pos) | RCC_PLLCFGR_PLLSRC_MSI;
RCC->CR |= RCC_CR_PLLON;
while ((RCC->CR & RCC_CR_PLLRDY) == 0); // Wait for PLL to stabilize
// According to reference manual 3.3.3 Read access latency, Table 11. Number of wait states according to CPU clock (HCLK) frequency
// The CPU clock must reach 64MHz or above, and LATENCY must be 4WS
// From PWR_CR1_VOS, we know that the current V_CORE is Range 1 (maximum clock frequency 80MHz)
FLASH->ACR |= FLASH_ACR_LATENCY_4WS; // 参阅: Increasing the CPU frequency
while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_4WS);
// Select PLL as system clock
RCC->CFGR |= RCC_CFGR_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS);
// At the beginning, MSI has not been calibrated, so a delay is required when using 115200 baud rate, otherwise the first four characters will be garbled
// Delay 5 bytes, 69.4us per byte, 347us in total
delay_us(347);
// When using 9600 baud rate, it takes 833.3us to send a character, which is much longer than this time, so no delay is needed
}
int main(void)
{
set_clock();
//LED light configuration
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
GPIOA->MODE &= ~GPIO_MODER_MODE5_1;
GPIOA->BSRR = GPIO_BSRR_BS5; // LED turns on
//Configure serial port 2
RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN;
GPIOA->AFR[0] = 7 << GPIO_AFRL_AFSEL2_Pos;
GPIOA->MODE &= ~GPIO_MODER_MODE2_0;
//GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEED2;
USART2->BRR = 80000000 / 115200; // The dividend is the clock frequency, the divisor is the baud rate
USART2->CR1 = USART_CR1_UE | USART_CR1_TE;
printf("ABCDEFGH\n");
printf("PWR->CR1=0x%08x\n", PWR->CR1);
printf("RCC->BDCR=0x%08x\n", RCC->BDCR);
printf("RCC->CFGR=0x%08x\n", RCC->CFGR);
printf("RCC->CR=0x%08x\n", RCC->CR);
printf("RCC->PLLCFGR=0x%08x\n", RCC->PLLCFGR);
printf("USART2->BRR=%d\n", USART2->BRR);
GPIOA->BRR = GPIO_BRR_BR5; // LED off
while (1);
}
MSI晶振接到PLL上后会通过外部的LSE晶振进行自动校准。校准期间,不精准的MSI时钟频率被PLL放大之后就会显著地影响串口的时钟,导致串口字符乱码,因此时钟切换后串口发送第一个字符之前必须延时,等待MSI时钟校准。
There is a simpler way to solve the serial port garbled problem without delay. The microcontroller also has a 16MHz HSI clock. Switching the USART2 clock from the APB1 clock related to MSI to the HSI clock in the RCC->CCIPR register can completely solve the problem.
【Procedure 2】
#include
#include
int fputc(int ch, FILE *fp)
{
if (fp == stdout)
{
if (ch == '\n')
{
while ((USART2->ISR & USART_ISR_TXE) == 0);
USART2->TDR = '\r';
}
while ((USART2->ISR & USART_ISR_TXE) == 0);
USART2->TDR = ch;
}
return ch;
}
void set_clock(void)
{
RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
PWR->CR1 |= PWR_CR1_DBP; // Allow access to the backup area register
// Open LSE
if ((RCC->BDCR & RCC_BDCR_LSEON) == 0)
{
RCC->BDCR |= RCC_BDCR_LSEON;
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0); // Wait for LSE to stabilize
}
RCC->CR |= RCC_CR_MSIPLLEN; //MSI uses LSE to calibrate MSI
//Configure PLL: MSI/M*N/R=4MHz/1*40/2=80MHz
RCC->PLLCFGR = RCC_PLLCFGR_PLLREN | (40 << RCC_PLLCFGR_PLLN_Pos) | RCC_PLLCFGR_PLLSRC_MSI;
RCC->CR |= RCC_CR_PLLON;
while ((RCC->CR & RCC_CR_PLLRDY) == 0); // Wait for PLL to stabilize
// According to reference manual 3.3.3 Read access latency, Table 11. Number of wait states according to CPU clock (HCLK) frequency
// The CPU clock must reach 64MHz or above, and LATENCY must be 4WS
// From PWR_CR1_VOS, we know that the current V_CORE is Range 1 (maximum clock frequency 80MHz)
FLASH->ACR |= FLASH_ACR_LATENCY_4WS; // 参阅: Increasing the CPU frequency
while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_4WS);
// Select PLL as system clock
RCC->CFGR |= RCC_CFGR_SW;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS);
}
int main(void)
{
set_clock();
//LED light configuration
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;
GPIOA->MODE &= ~GPIO_MODER_MODE5_1;
GPIOA->BSRR = GPIO_BSRR_BS5; // LED turns on
//Configure serial port 2
RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN;
GPIOA->AFR[0] = 7 << GPIO_AFRL_AFSEL2_Pos;
GPIOA->MODE &= ~GPIO_MODER_MODE2_0;
//GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEED2;
// Using HSI16 as the clock of USART2 can avoid garbled characters
RCC->CR |= RCC_CR_HSION;
while ((RCC->CR & RCC_CR_HSIRDY) == 0);
RCC->CCIPR = RCC_CCIPR_USART2SEL_1; // HSI16 as the clock of USART2
USART2->BRR = 16000000 / 115200; // The dividend is the clock frequency, the divisor is the baud rate
USART2->CR1 = USART_CR1_UE | USART_CR1_TE;
printf("ABCDEFGH\n");
printf("PWR->CR1=0x%08x\n", PWR->CR1);
printf("RCC->BDCR=0x%08x\n", RCC->BDCR);
printf("RCC->CFGR=0x%08x\n", RCC->CFGR);
printf("RCC->CR=0x%08x\n", RCC->CR);
printf("RCC->PLLCFGR=0x%08x\n", RCC->PLLCFGR);
printf("USART2->BRR=%d\n", USART2->BRR);
GPIOA->BRR = GPIO_BRR_BR5; // LED off
while (1);
}
Previous article:stm32l476 clock settings
Next article:STM3210X external clock configuration and frequency multiplication selection
Recommended ReadingLatest update time:2024-11-23 07:26
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- Help TI series high profit series model
- FPGA_100 Days Journey_Blocking and Non-Blocking
- 4 charts showing how and when the chip shortage will end
- AD19 only shows wireframe after copper is laid, which does not look like laid copper
- 【EVK-NINA-B400 Evaluation Kit】Hardware
- BA6849FM (Optical storage media, Active Filters, CD, DVD, system processing)
- Oh, mobile
- MicroPython 7th Anniversary Celebration
- [Gizwits Gokit3 Review] Unboxing and Getting Started
- This week's evaluation information is presented to you~