ARM Cortex-M3內核中有一個Systick定時器,它是一個24位(0~(2^24-1))的倒計數定時器,當計數到0時,它就會從Load寄存器中自動重裝定時初值,只要不把CTRL寄存器中的ENABLE清0,它就永不停。
systick定時器寄存器:
時鍾源可以是內部時鍾FCLK或外部時鍾STCLK
配置系統定時器步驟:
①選擇時鍾源 ②設定重載數(reload)③開啟中斷 ④啟動滴答定時器
在core_cm3.h中有關於系統定時器的配置:
static __INLINE uint32_t SysTick_Config(uint32_t ticks) { if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible 判斷是否大於 2^24*/ SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts 異常號2^4-1 =15 */ SysTick->VAL = 0; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | //選擇內部時鍾FCLK SysTick_CTRL_TICKINT_Msk | //中斷使能 SysTick_CTRL_ENABLE_Msk; //定時器使能 /* Enable SysTick IRQ and SysTick Timer */ return (0); /* Function successful */ }
實驗一:
通過systick中斷方式進行定時
實驗代碼:
(1)定時函數
//時基:1/72M //SystemCoreClock /X裝值 //SystemCoreClock /1000000 --1us //SystemCoreClock /1000 --1ms //SystemCoreClock /100000 --10us u32 TimingDelay=0; void Systick_Config(void) { //判斷是否超出范圍 if(SysTick_Config(SystemCoreClock/1000000)) return; //1us SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;//失能定時器 } //time us void Delay_us(__IO u32 time) //--微秒級延時 { TimingDelay =time; SysTick->CTRL |=SysTick_CTRL_ENABLE_Msk;//使能定時器 while(TimingDelay !=0); SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;//失能定時器 } //time ms void Delay_ms(__IO u32 time) //--毫秒級延時 { TimingDelay =time*1000; SysTick->CTRL |=SysTick_CTRL_ENABLE_Msk;//使能定時器 while(TimingDelay !=0); SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;//失能定時器 } //*************滴答定時器中斷****************// //中斷服務函數 void SysTick_Handler(void) { if(TimingDelay !=0) TimingDelay --; }
(2)main函數
1 int main(void) 2 { 3 4 LED_INIT(); 5 Systick_Config(); 6 7 GPIOA->BRR |=1<<8; //點亮led //寫1 reset 8 GPIOA->BSRR |=1<<8;//關閉led //寫1,set 9 10 GPIOD->BRR |=1<<2; //點亮led //寫1 reset 11 GPIOD->BSRR |=1<<2;//關閉led //寫1,set 12 13 GPIOA->ODR &=~(1<<8); //點亮led 14 GPIOA->ODR |= (1<<8); //關閉led 15 16 while(1) 17 { 18 GPIOA->ODR ^= GPIO_Pin_8; //LED_Toggle 19 GPIOD->ODR ^= GPIO_Pin_2; 20 Delay_ms(1000); 21 } 22 23 }
實驗現象:
https://www.bilibili.com/video/BV1uA411j7W6/