1. 程式人生 > >STM32-自學筆記(8.使用STM32的SysTick定時器控制LED燈閃爍)

STM32-自學筆記(8.使用STM32的SysTick定時器控制LED燈閃爍)

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計數器

}

下一篇部落格寫本篇程式碼使用到的庫函式。