STM32-自學筆記(8.使用STM32的SysTick定時器控制LED燈閃爍)
阿新 • • 發佈:2018-12-15
SysTick定時器,被稱為“系統節拍時鐘”。SysTick屬於ARM Cortex-M3核心的一個內設,STM32也帶有SysTick定時器。
SysTick定時器的基本結構
SysTick工作原理:
- SysTick從時鐘源介面獲得時鐘驅動
- 從重灌暫存器將重灌值讀入當前計數暫存器中,並在時鐘驅動下進行減一計數。
- 當SysTick發生下溢時,將計數標誌位置位,並且觸發SysTick溢位中斷,同時進行一次重灌值載入操作。
實驗說明:
使用STM32的SysTick定時器產生長度為1s的時間間隔,並以此時間間隔閃爍LED燈。
硬體電路
GPIOA.4引腳接LED燈,再接一個限流電阻,最後接地。如圖
軟體設計(程式設計):
需要注意幾點:
- 配置RCC暫存器組,使用PLL作為系統時鐘源,並輸出72MHz時鐘頻率。
- 開啟GPIOA時鐘,設定GPIOA.4引腳為推輓輸出功能。
- 配置SysTick,選擇經過8分頻後的系統時鐘源作為驅動時鐘。
- 配置SysTick,寫入預重灌值,使SysTick產生1s 時間間隔。
重點在於根據不同的時鐘頻率計算SysTick的重灌值。
- 假設選擇PLL輸出的72MHz作為STM32的主時鐘,並將器8分頻(72MHz/8=9MHz)後作為SysTick的驅動時鐘。
- SysTick的驅動時鐘為:f=72MHz/8=9MHz
- SysTick定時器進行一次“減一計數”所需要是的時間:T=1/f
- 那麼1s所需的“減1計數”次數為:N=1/T=9000000
- 這就是重灌值
程式
主函式 main.c
#include "stm32f10x_lib.h" void RCC_Configuartion (void); void GPIO_Configuartion (void); void Systick_Configuration (viod); void Delay_Second (void); int main(void) { RCC_Configuartion (); //設定系統時鐘 GPIO_Configuartion (); //設定GPIO埠 Systick_Configuration (); //設定Systick定時器 while(1) { GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_4))); //翻轉GPIO.4電平 Delay_Second(); //延時1s } }
設定系統各部分時鐘 RCC_Configuration
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus; //定義列舉型別變數 HSEStartUpStatus
RCC_DeInit(); //復位系統時鐘設定
RCC_HSEConfig(RCC_HSE_ON); //開啟HSE
HSEStatrtUpStatus=RCC_WaitForHSEStartUp(); //等待HSE起振並穩定
if(HSEStatrtUpStatus==SUCCESS) //判斷HSE是否起振成功,是則進入if()內部
{
RCC_HCLKConfig(RCC_SYSCLK_Div1); //選擇HCLK(AHB)時鐘源為SYSCLK分頻
RCC_PCLK2Config(RCC_HCLK_Div1); //選擇PCLK2時鐘源為HCLK(AHB)1分頻
RCC_PCLK1Config(RCC_HCLK_Div2); //選擇PCLK1時鐘源為HCLK(AHB)2分頻
FLASH_SetLatency(FLASH_Latency_2); //設定Flash延時週期數為2
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能Flash預取快取
//選擇PLL時鐘源為 HSE 1 分頻,倍頻數為9,則PLL=8MHz *9=72MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
RCC_PLLCmd(ENABLE); //使能PLL
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET); //等待PLL輸出穩定
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //選擇SYSCLK時鐘源為PLL
while(RCC_GetSYSCLKSource()!=0x08); //等待PLL成為SYSCLK時鐘源
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //開啟APB2總線上的GPIOA時鐘
}
設定各GPIO埠功能 GPIO_Configuration
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//設定GPIOA.4為推輓輸出,最大翻轉頻率為50MHz
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
設定Systick定時器,重灌載時間為1s Systick_Configuartion
void Systick_Configuartion (void)
{
SysTick_CounterCmd(SysTick_Counter_Disable); //失能Systick定時器
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //選擇HCLK為SysTick時鐘源
SysTick_CounterCmd(SysTick_Counter_Clear); //清除Systick計數器
SysTick_SetReload(9000*1000); //主頻為72/8MHz,配置計數值為9000*1000可以得到1s定時間隔
}
1s定時 Delay_Second
void Delay_Second (void)
{
SysTick_CounterCmd(SysTick_Counter_Enable); //啟動Systick計數
while(SysTick_GetFlagStatus(SysTick_FLAG_COUNT)==0); //等待Systick計數至0
SysTick_CounterCmd(SysTick_Counter_Disable); //失能Systick定時器
SysTick_CounterCmd(SysTick_Counter_Clear); //清除Systick計數器
}
下一篇部落格寫本篇程式碼使用到的庫函式。