Refer to STM32F1 Development Guide (Elite version) library function version - Chapter 5
1, SystemInit clock initialization function
Use the V3.5 library function, which will be called automatically after system startup:
startup_ stm32f10x_ In XX. S file:
; Reset handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP
#define SYSCLK_FREQ_72MHz 72000000
SYSCLK (system clock) 72MHz
AHB bus clock (using SYSCLK) 72MHz
APB1 bus clock (PCLK1) 36MHz
APB2 bus clock (PCLK2) 72MHz
PLL clock 72MHz
2, Systick tick timer
1. Systick timer, cm3 and CM4 core chips are available.
2. Systick timer is often used as delay or heartbeat clock of real-time system
It saves MCU resources and does not waste a timer. For example, in UCOS, time-sharing multiplexing requires a minimum timestamp. Generally, Systick is used as UCOS heartbeat clock in STM32+UCOS system.
3. Systick timer is the system tick timer, a 24 bit countdown timer.
When 0 is counted, the initial value of the loading timing will be automatically reloaded from the RELOAD register. As long as the enable bit in the Systick control and status register is not cleared, it will never stop and can work even in sleep mode.
4. Systick timer is bundled in NVIC to generate systick exception (exception No.: 15).
5. The priority of Systick interrupt can also be set.
6. 4 Systick registers (refer to Cortex M3 authoritative guide)
①: CTRL SysTick control and status register
Bit 0: ENABLE ENABLE bit: Set 1 when using Systick timer
Bit 1: TICKINT: whether an interrupt is generated
Bit 2: CLKSOURCE Clock source function (configured by SysTick_CLKSourceConfig)
Bit 16: COUNTFLAG: read this bit and reset it automatically ---- > to avoid misreading
For STM32, the external clock source is 1 / 8 of HCLK (AHB bus clock), and the core clock is HCLK clock.
Configuration function: SysTick_CLKSourceConfig();
②: LOAD SysTick Automatic reload division value register
24 bit reload register, even 32 bits, only 24 bits are valid
③: VAL SysTick Current value register
④: CALIB SysTick Calibration value register
7. Systick related functions in the firmware library:
SysTick_CLKSourceConfig() // Systick clock source selection In misc.c file
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) { /* Check the parameters */ assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); if (SysTick_CLKSource == SysTick_CLKSource_HCLK) { SysTick->CTRL |= SysTick_CLKSource_HCLK; } else { SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; } }
static __INLINE uint32_t SysTick_Config(uint32_t ticks) { if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ /* set reload register */ SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set Priority for Cortex-M0 System Interrupts */ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); SysTick->VAL = 0; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0); /* Function successful */ }
SysTick_Config(uint32_t ticks) / / initialize systick, set the clock to HCLK, and enable interrupt // core_cm3.h/core_cm4.h file (two interrupt intervals)
8. Systick interrupt service function
void SysTick_Handler(void);
9. delay is realized by interrupt
static __IO uint32_t TimingDelay; void Delay(__IO uint32_t nTime) { TimingDelay = nTime; while(TimingDelay != 0); } void SysTick_Handler(void) { if (TimingDelay != 0x00) { TimingDelay--; } } int main(void) { ... if (SysTick_Config(SystemCoreClock / 1000)) //systick clock is HCLK, and the interrupt time interval is 1ms { while (1); } while(1) { Delay(200);//2ms ... } }
3, delay function
If the delay is inconsistent during use, the problem is generally because the clocks of different cores are different. Just modify the tciks value.
void delay_ms(u16 nms) { u32 temp; SysTick->LOAD=(u32)nms*fac_ms; //Time loading (systick - > load is 24bit) SysTick->VAL =0x00; //Clear counter SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //Start counting down do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //Waiting time arrives SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //Turn off counter SysTick->VAL =0X00; //Clear counter }