This is also a chicken rib of STM32. It is too demanding for the LSE external crystal oscillator. The manual requires the use of 6pf. There are too few crystal oscillators of this specification on the market. There are a lot of good and bad crystals, and many experts and rookies have been fooled. The same is true for our own board. After many twists and turns, we have repeatedly tried to use crystal oscillators of different specifications, replace external capacitors, and resistors, but none of them can make this 32.768K LSE oscillate. However, RTC is needed to provide time. There are two main methods to consider. The first is to use an external RTC clock chip, such as DS1302. The second is to use other internal clock sources to provide the RTC clock. There is no doubt that the board has been made. Adding a clock chip will definitely cause changes in the layout of the board, and the board must be remade. Here, the second method is used.
Check the clock tree in the STM32 manual as follows:
Except for the external low-speed LSE that cannot oscillate, only the 128-division of LSI and HSE is available. The LSI is an internal 40KHz RC oscillator with a frequency floating between 30 and 60KHz. Naturally, this cannot be used for RTC timing because the error is too large.
Our board is equipped with the STM32F107 chip, and the external high-speed crystal oscillator is 25MHz. After 128 division, the frequency is 25000000 / 128 = 195312.5 Hz. Obviously, it cannot be very accurate here, and there is a small error.
Then set the RTC_PRL register and write the frequency division value of 195312 to get a frequency of 1Hz. The disadvantage of using HSE as the RTC clock is that it is not possible to use the backup battery to power the RTC after the power is disconnected to maintain the normal operation of the RTC. The host computer needs to set the time again next time.
The code is roughly as follows:
- void RTC_Configuration(void)
- {
- u8 i = 0;
- /* Enable PWR and BKP clocks */
- /* PWR clock (power control) and BKP clock (RTC backup register) enable */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
- /* Allow access to BKP Domain */
- /* Enable RTC and backup register access */
- PWR_BackupAccessCmd(ENABLE);
- /* Reset Backup Domain */
- /* Reset all registers of peripheral BKP to default values */
- BKP_DeInit();
- /* Enable LSE */
- /* Enable LSE (external 32.768KHz low speed crystal oscillator) */
- RCC_LSEConfig(RCC_LSE_ON);
- /* Wait till LSE is ready */
- /* Wait for the external crystal oscillator to stabilize the output */
- TIM5_Init_Query(CALC_TYPE_MS); //ms level
- for (i = 0;i < 10;i++) //10 times of testing, if LSE still does not oscillate, it proves that there is something wrong with it, and jump out of the loop
- {
- if (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != RESET)
- break;
- TIM5_MS_CALC(1); //1ms delay
- }
- //while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){}
- if (i == 10)
- {
- //RCC->CSR |= 0x1; //Turn on the internal low-speed crystal oscillator
- //while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
- //RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); //Use LSI to provide RTC clock
- //Use external high-speed crystal oscillator 128 division
- RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);
- }else
- {
- /* Select LSE as RTC Clock Source */
- /*Use external 32.768KHz crystal as RTC clock */
- RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
- }
- /* Enable RTC Clock */
- /* Enable RTC clock supply */
- RCC_RTCCLKCmd(ENABLE);
- /* Wait for RTC registers synchronization */
- /*Wait for RTC register synchronization */
- RTC_WaitForSynchro();
- /* Wait until last write operation on RTC registers has finished */
- /* Wait for the last write operation to the RTC register to complete */
- RTC_WaitForLastTask();
- /* Enable the RTC Second */
- /* Enable RTC second interrupt */
- RTC_ITConfig(RTC_IT_SEC, ENABLE);
- /* Wait until last write operation on RTC registers has finished */
- /* Wait for the last write operation to the RTC register to complete */
- RTC_WaitForLastTask();
- /* Set RTC prescaler: set RTC period to 1sec */
- /* The pre-division value of the 32.768KHz crystal oscillator is 32767. If you have high requirements for accuracy, you can modify this division value to calibrate the crystal oscillator */
- if (i != 10) //LSE cannot function normally
- RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */
- else
- RTC_SetPrescaler(195312); //25000000 / 128 = 195312.5, if it is 8M / 128 = 62500, then this should be filled in as 62499
- /* Wait until last write operation on RTC registers has finished */
- /* Wait for the last write operation to the RTC register to complete */
- RTC_WaitForLastTask();
- }
- void Init_RTC(void)
- {
- /* The following if...else.... if determines whether the system time has been set and the value of RTC backup register 1
- Is it the previously written 0XA5A5? If not, it means that the RTC is powered on for the first time and needs to be configured.
- Prompt the user to change the system time through the serial port, convert the actual time into the RTC count value and write it into the RTC register.
- And modify the value of backup register 1 to 0XA5A5.
- else indicates that the system time has been set, prints the reason for the last system reset, and enables the RTC second interrupt
- */
- if (BKP_ReadBackupRegister(BKP_DR1) != RTC_SEQ_ID)
- {
- /* Backup data register value is not correct or not yet programmed (when
- the first time the program is executed) */
- /* RTC Configuration */
- RTC_Configuration();
- /* Adjust time by values entred by the user on the hyperterminal */
- RTC_SetCounter(Time_Regulate(YEAR_BASE,01,01,0,0,0)); //2008-1-1 0:0:0
- /* Modify the value of backup register 1 to 0XA5A5 */
- BKP_WriteBackupRegister(BKP_DR1, RTC_SEQ_ID);
- }else
- {
- /* Check if the Power On Reset flag is set */
- //RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET
- // printf("\r\n\n Power On Reset occurred....");
- /* Check if the Pin Reset flag is set */
- //else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
- // printf("\r\n\n External Reset occurred....");
- if (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
- {
- //RCC->CSR |= 0x1; //Turn on the internal low-speed crystal oscillator
- //while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
- //RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); //Use LSI to provide RTC clock
- //RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);
- RTC_Configuration();
- }
- //printf("\r\n No need to configure RTC....");
- /* Wait for RTC registers synchronization */
- RTC_WaitForSynchro();
- /* Enable the RTC Second */
- RTC_ITConfig(RTC_IT_SEC, ENABLE);
- /* Wait until last write operation on RTC registers has finished */
- RTC_WaitForLastTask();
- }
- #ifdef RTCClockOutput_Enable
- /* Enable PWR and BKP clocks */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
- /* Allow access to BKP Domain */
- PWR_BackupAccessCmd(ENABLE);
- /* Disable the Tamper Pin */
- BKP_TamperPinCmd(DISABLE); /* To output RTCCLK/64 on Tamper pin, the tamper
- functionality must be disabled */
- /* Enable RTC Clock Output on Tamper Pin */
- BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
- #endif
- /* Clear reset flags */
- RCC_ClearFlag();
- }
In actual testing, the RTC effect is good, and the synchronization time with the host computer after a certain period of time can basically meet the requirements.
Damn LSE crystal, this thing is simply unbearable...
Previous article:stm32 ADC non-DMA mode
Next article:Use keil to burn stm32 and pay attention to changing the address
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Detailed explanation of intelligent car body perception system
- How to solve the problem that the servo drive is not enabled
- Why does the servo drive not power on?
- What point should I connect to when the servo is turned on?
- How to turn on the internal enable of Panasonic servo drive?
- What is the rigidity setting of Panasonic servo drive?
- How to change the inertia ratio of Panasonic servo drive
- What is the inertia ratio of the servo motor?
- Is it better for the motor to have a large or small moment of inertia?
- What is the difference between low inertia and high inertia of servo motors?
- Purgatory Legend-RAM War
- ATX-100 Series Cable Harness Tester Revealed! (Demo + Features)
- Who can give me the control circuit of the car main driver's door glass lifting switch group
- Reasons why the automatic function of a digital oscilloscope cannot be triggered when measuring low-frequency signals
- Running helloworld-porting on iTOP-4418 development board
- Capacitor selection and installation considerations
- Millimeter wave sensor technology for detecting passengers in moving vehicles
- How to detect whether a POE switch is a single-chip microcomputer
- Two small questions about the C5509A debugging process
- DSP assembly feels difficult to start