problem found
I have been learning FreeRTOS recently. After the successful transplantation today, I wrote two tasks. One is the task of flashing the LED every 1s, and the other is the task of sending a string every 100ms using UART4. After the download was successful, I found that the interval between the LED flashing and the interval between the serial port printing were incorrect. I was very puzzled at the time: RCC was configured according to the example of the standard library, and the system beat of FreeRTOS was also configured correctly, so this problem could not occur. Later, after careful investigation, I used an oscilloscope to test the waveform of the serial port and found a problem: the program code was configured with a baud rate of 115200, but the actual output waveform was calculated to be 38400, a difference of 3 times. At this point, I began to doubt the RCC configuration. At this time, I turned on the MCO pin and asked it to display the SYSCLK clock. The oscilloscope reflected 72MH. Then I asked it to output the APB1CLK clock, which was a normal 36MHz. I felt confused when debugging here. Later, I carefully checked the RCC configuration code and found that the official example used a 25MHz crystal oscillator, so I changed it to 25Mhz and recalculated the division coefficient. After burning, it became normal. Here is the example template on the official website
problem solved
Clock tree of STM32F107
As can be seen from the figure, the SYSCLK clock of STM32F107 has two configuration routes. The first route can use an 8M external crystal to configure the system to 72MHz. The second route can use a 25M external crystal to configure the system to 72MHz. The first route is used, and the system clock is also correctly configured to 72MHz, but the serial port clock is incorrect (in fact, the HSE_VALUE value has not been modified). After changing to a 25MHz crystal and configuring according to the second route, the serial port is normal
Official RCC configuration example code
void RCC_Configuration(void)
{
RCC_ClocksTypeDef RCC_ClockFreq;
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus != ERROR)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/****************************************************************/
/* HSE=25MHz, HCLK=72MHz, PCLK2=72MHz, PCLK1=36MHz */
/****************************************************************/
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* ADCCLK = PCLK2/4 */
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
/* Configure PLLs *********************************************************/
/* PPL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
RCC_PREDIV2Config(RCC_PREDIV2_Div5);
RCC_PLL2Config(RCC_PLL2Mul_8);
/* Enable PLL2 */
RCC_PLL2Cmd(ENABLE);
/* Wait till PLL2 is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET)
{}
/* PPL1 configuration: PLLCLK = (PLL2 / 5) * 9 = 72 MHz */
RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while (RCC_GetSYSCLKSource() != 0x08)
{}
}
RCC_GetClocksFreq(&RCC_ClockFreq);
/* Enable USART2 clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* Enable ETHERNET clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC | RCC_AHBPeriph_ETH_MAC_Tx |
RCC_AHBPeriph_ETH_MAC_Rx, ENABLE);
/* Enable GPIOs clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE| RCC_APB2Periph_AFIO, ENABLE);
/* Enable ADC1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
}
It can be found that the official example code uses a 25MHz external crystal to configure the system clock. I modified my 8M crystal configuration based on the official code and it did not work properly.
My modified code
void bsp_RCC_Init(void)
{
RCC_ClocksTypeDef RCC_ClockFreq;
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
if(RCC_WaitForHSEStartUp() != ERROR)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/****************************************************************/
/* HSE=8MHz, HCLK=72MHz, PCLK2=72MHz, PCLK1=36MHz */
/****************************************************************/
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* ADCCLK = PCLK2/4 */
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
/* Configure PLLs *********************************************************/
/* PPL2 configuration: PLL2CLK = (HSE / 2) * 10 = 40 MHz */
RCC_PREDIV2Config(RCC_PREDIV2_Div2);
RCC_PLL2Config(RCC_PLL2Mul_10);
/* Enable PLL2 */
RCC_PLL2Cmd(ENABLE);
/* Wait till PLL2 is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET)
{}
/* PPL1 configuration: PLLCLK = (HSE / 1) * 9 = 72 MHz */
RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE, RCC_PREDIV1_Div1);
RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while (RCC_GetSYSCLKSource() != 0x08)
{}
}
}
After using the code I modified above, the serial port baud rate error problem occurred. When checking the registers in Keil debugging, I found that the value of UART->BRR was different from the theoretical calculation. Tracing back the configuration process of the USART_Init() function, I found that the obtained PCLK1 clock frequency was not 36MHz. After
carefully checking the source code, I found that HSE_VALUE was defined as 25000000, which caused the PCLK1_Frequency value obtained by the RCC_GetClockFreq() function in the figure to be calculated incorrectly. Therefore, HSE_VALUE needs to be changed to 8000000.
Another way is to replace the external 8M crystal oscillator with 25M, modify the RCC configuration to the official code, and it will run normally.
Summarize
STM32F107 has Ethernet, USB OTG and other network devices. When Ethernet uses the MII interface, a 25MHz clock is required. It is best for STM32F107 to use an external 25MHz crystal as the clock source. The official also recommends using 25MHz. To use an 8M crystal, you need to modify the HSE_VALUE value to 8000000, and then configure the corresponding PLL clock.
Previous article:About the use of PA15 pin as normal IO in STM32
Next article:STM32 USART garbled code
- 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?
- RAQ #223: How to measure and determine soft-start timing without a soft-start equation?
- RAQ #223: How to measure and determine soft-start timing without a soft-start equation?
- GigaDevice's full range of automotive-grade SPI NOR Flash GD25/55 wins ISO 26262 ASIL D functional safety certification
- GigaDevice's full range of automotive-grade SPI NOR Flash GD25/55 wins ISO 26262 ASIL D functional safety certification
- New IsoVu™ Isolated Current Probes: Bringing a New Dimension to Current Measurements
- New IsoVu™ Isolated Current Probes: Bringing a New Dimension to Current Measurements
- Infineon Technologies Launches ModusToolbox™ Motor Kit to Simplify Motor Control Development
- Infineon Technologies Launches ModusToolbox™ Motor Kit to Simplify Motor Control Development
- STMicroelectronics IO-Link Actuator Board Brings Turnkey Reference Design to Industrial Monitoring and Equipment Manufacturers
- Melexis uses coreless technology to reduce the size of current sensing devices
- How to convert TTL level USART serial port to differential transmission?
- How to derive the relationship between the input and output of this integrator circuit?
- Happy People's Day~
- About the uboot compilation problem of am335x
- TLC7524 interface circuit program.pdf
- [Question] GD32F103RCT6 basic timer 5 clock source frequency
- RC snubber circuit design principles
- A Brief Analysis of Object-Oriented Thinking in RT-Thread System
- EEWORLD University ---- Linux driver tutorial (by itop4412)
- Electromagnetic Field and Electromagnetic Wave Reference Book Zhou Keding