預備知識:
對標准庫來說,如果定義了時鍾頻率,則系統會默認初始化該時鍾頻率。
SysTick是CM4的內核外設,是一個24位的向下遞減計數器,每次計數時間是1/SYSCLK,即1/168000000。
SysTick計數時間的計算:t=重裝載值*1/AHB時鍾頻率。1/AHB時鍾頻率即是計數一次的時間。一般把重裝載值定為128000000/100000=1280,則10us中斷一次;一般不設置為1us中斷一次,這樣中斷頻率太高,偏移了程序重心。
正文:
程序源碼:
在main.c中
#include "sys.h" #include "led.h" // "__IO"在Core_cm4.h中被重定義,原型是"volatile" ① __IO uint32_t TimingDelay; // 延時函數 void Delay(__IO uint32_t nTime) { TimingDelay = nTime; while(TimingDelay != 0); } // 主函數 int main(void) { // 初始化LED端口 LED_Init(); // 初始化SysTick ② if(SysTick_Config(SystemCoreClock/1000)) { // Capture error while(1); } // LED閃爍 while(1) { Delay(250); GPIO_SetBits(GPIOF,GPIO_Pin_9); Delay(250); GPIO_ResetBits(GPIOF,GPIO_Pin_9); } } /*------------------------------------------------------------------------------------ 注釋: ①:volatile 的作用就是指示編譯器不要因優化而省略此指令,必須每次都直接讀寫其值。 寫一段測試代碼如下: u8 test; test = 1; test = 2; test = 3; 設置優化級別中級 運行后test會被直接取值為3 只有最后一個語句被編譯 如用volatile: volatile u8 test; test = 1; test = 2; test = 3; 則所有語句都會被編譯。test先后被設置成1、2、3 由此可以看出這個作用在IO操作,寄存器操作,特殊變量,多線程變量讀寫都是很重要。 ②:SysTick_Config的參數,是一個時鍾次數,叫systick重裝定時器的值。意思就是多少個 1/fosc 時間后中斷一下。 這里 SystemCoreClock/1000 為沒過1ms中斷一次,SystemCoreClock為系統時鍾頻率。 計算方法為: SystemCoreClock ÷ timer = 1ms 假設SystemCoreClock為128M,單位為Hz。則: 1ms = 1128MHz ÷ timer = 128M/s ÷ timer 128M ------ timer = 1s ------ 0.001s 128M timer = ------ 1000 ------------------------------------------------------------------------------------*/
在stm32f4xx_it.c中
/* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_it.h" /* 變量定義 ------------------------------------------------------------------*/ // 利用關鍵字extern,可以在一個文件中引用另一個文件中定義的變量或者函數 extern __IO uint32_t TimingDelay; /** * @brief This function handles SysTick Handler. * @param None * @retval None */ void SysTick_Handler(void) { if(TimingDelay != 0x00) { TimingDelay--; } }
注意:
1.在stm32中,中斷函數在stm32f4xx_it.c中,不能像51那樣寫在main.c文件下。
2.關鍵字extern拓展變量作用范圍的用法。
3.__IO == volatile
參考資料:
https://blog.csdn.net/u010834669/article/details/80204195