STM32F1開發(fā)指南《精英版》庫函數(shù)版---第五章第一,系統(tǒng)init時鐘初始化函數(shù)使用V3.5版本的庫函數(shù),該函數(shù)在系統(tǒng)啟動后自動調(diào)用。
在startup_stm32f10x_xx.s文件中:
; resethandlerreset _ handlerprocexportreset _ handler [ weak ] import _ mainimportsysteminitldrr 0,=system init blx r0 ldr r0
初始化后的狀態(tài): SYSCLK (系統(tǒng)時鐘) 72MHz
AHB總線時鐘(使用SYSCLK ) 72MHz
APB1總線時鐘(PCLK1) 36MHz
APB2總線時鐘(PCLK2) 72MHz
PLL時鐘72MHz
初始化后,可以從變量SystemCoreClock中獲取系統(tǒng)變量。 如果SYSCLK=72MHz,則變量SystemCoreClock=72000000。 二、有Systick滴答計時器1、Systick計時器、CM3、CM4核心芯片。 2、Systick計時器常用于延時或?qū)崟r系統(tǒng)的心跳時鐘
節(jié)約MCU資源,無需浪費計時器。 例如,在UCOS中,時分復(fù)用需要最小的時間戳,一般在STM32 UCOS系統(tǒng)中使用Systick作為UCOS心跳時鐘。
3、Systick計時器是系統(tǒng)滴答的計時器,是24位倒計時計時器。 計數(shù)到0后,從RELOAD寄存器中自動重新加載計時器初始值。 只要不清除Systick控件和狀態(tài)寄存器的使能位,它就不會停止,并在休眠模式下工作。
4、SysTick計時器與NVIC捆綁在一起,用于產(chǎn)生SysTick異常(異常編號: 15 )。 5、也可以設(shè)定Systick中斷的優(yōu)先順序。 6、4個Systick寄存器(參考Cortex M3權(quán)威指南):CTRL SysTick控件和狀態(tài)寄存器
位0:ENABLE有效位:必須設(shè)置1才能使用Systick計時器
是否發(fā)生位1(Tickint )中斷
位2:CLKSOURCE時鐘源(由函數(shù)SysTick_CLKSourceConfig配置) ) ) )
位16 )計數(shù)標(biāo)志)讀取此位時自動清除----避免誤讀
在STM32的情況中,外部時鐘源是HCLK(AHB總線時鐘)的1/8核心時鐘是hclk時鐘。
配置函數(shù): SysTick_CLKSourceConfig (;
):加載棒自動重載除法寄存器
24位重載寄存器即使在32位中也僅24位有效
):VAL SysTick當(dāng)前值寄存器
):CALIB SysTick校準(zhǔn)值寄存器
7、固件庫中的Systick相關(guān)函數(shù):
p style="text-align:left;">??? SysTick_CLKSourceConfig()??? //Systick時鐘源選擇? misc.c文件中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) //初始化systick,時鐘為HCLK,并開啟中斷? ? ?//core_cm3.h/core_cm4.h文件中(兩個中斷時間間隔)
8、Systick中斷服務(wù)函數(shù)
void SysTick_Handler(void);
9、用中斷的方式實現(xiàn)delay延時 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時鐘為HCLK,中斷時間間隔1ms { while (1); } while(1) { Delay(200);//2ms … }} 三、delay延時函數(shù)如果使用中發(fā)現(xiàn)延時不一致,問題一般都是因為不同內(nèi)核時鐘不一樣而已。修改tciks值即可。
void delay_ms(u16 nms){ u32 temp; SysTick->LOAD=(u32)nms*fac_ms;//時間加載(SysTick->LOAD為24bit)SysTick->VAL =0x00;//清空計數(shù)器SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;//開始倒數(shù) do{temp=SysTick->CTRL;}while((temp&0x01)&&!(temp&(1<<16)));//等待時間到達 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;//關(guān)閉計數(shù)器SysTick->VAL =0X00; //清空計數(shù)器 }