SysTick_Init()函數
SysTick_Init 函數代碼如下:
/*************************************************************************
* 函 數 名 : SysTick_Init
* 函數功能 : SysTick 初始化,SYSTICK 的時鐘固定為 AHB 時鐘的 1/8
* 輸 入 : SYSCLK:系統時鐘頻率
* 輸 出 : 無
**************************************************************************/
void SysTick_Init(u8 SYSCLK)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us=SYSCLK/8; //SYSCLK的8分頻 保存1us所需的計數次數
fac_ms=(u16)fac_us*1000; //每個 ms 需要的 systick 時鐘數
}
SysTick_Init 函數形參 SYSCLK 表示的系統時鐘大小,默認配置我們使用的系統時鐘是 72M,所以調用這個函數時,形參值即為 72。函數內部調用了一個庫函數 SysTick_CLKSourceConfig,此函數用來對 SysTick 定時器時鐘的選擇,我們使用的SysTick定時器時鐘是系統時鐘的8 頻 ,所以參數是SysTick_CLKSource_HCLK_Div8。如果使用系統時鐘作為 SysTick 定時器時鐘,那么參數即為 SysTick_CLKSource_HCLK。這個函數在 misc.c 庫文件內,如何查找我們前面介紹過方法。
下面的兩條語句是用來求取SysTick定時器在1us時間內和1ms時間內的計數次數。
delay_us()函數
delay_us 函數代碼如下:
/**********************************************************************
* 函 數 名 : delay_us
* 函數功能 : us 延時,
* 輸 入 : nus:要延時的 us 數
注 意 :nus 的 值 , 不 要 大 于 798915us( 最 大 值 即
2^24/fac_us@fac_us=21)
* 輸 出 : 無
**********************************************************************/
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //時間加載
SysTick->VAL=0x00; //清空計數器
SysTick->CTRL|=0x01 ; //開始倒數
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待時間到達
SysTick->CTRL&=~0x01; //關閉計數器
SysTick->VAL =0X00; //清空計數器
}
①將需要延時多少 us 的計數值加載到 SysTick 的 LOAD 寄存器中,fac_us值是延時 1us 所需的計數值。
②清空當前計數值寄存器 VAL。
③打開 SysTick 定時器,定時器開始向下遞減計數。
④CTRL 寄存器的第 16 位是 SysTick 遞減到 0 的標志位,如果遞減到 0,此為置 1,通過讀取該位來判斷延時是否完成,從而退出 while 循環。
⑤關閉 SysTick 定時器。
⑥清空當前計數值寄存器 VAL。
delay_ms()函數
delay_ms 函數代碼如下:
/*************************************************************
* 函 數 名 : delay_ms
* 函數功能 : ms 延時,
* 輸 入 : nms:要延時的 ms 數
注意:nms 的值,SysTick->LOAD 為 24 位寄存器,
不要大于 0xffffff*8*1000/SYSCLK
對 72M 條件下,nms<=1864ms
* 輸 出 : 無
**************************************************************/
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; // 時 間 加 載
(SysTick->LOAD 為 24bit)
SysTick->VAL =0x00; //清空計數器
SysTick->CTRL|=0x01 ; //開始倒數
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待時間到達
SysTick->CTRL&=~0x01; //關閉計數器
SysTick->VAL =0X00; //清空計數器
}
此函數功能與 delay_us 基本一樣,只不過這里是延時 ms。要注意的是,SysTick 定 時 器 是 24 位 的 , 其 計 數 最 大 值 為 0xffffff , 時 間 為nms<=0xffffff*8*1000/SYSCLK,SYSCLK 是系統時鐘為 72M,所以最大延時為1864ms。如果需要延時大于 1.864S,可以調用多個 delay_ms 函數即可。
主函數
在 main.c 文件中前面引入了工程中所需的頭文件,可以打開工程查看,這里我們主要看下 main 函數,代碼如下:
/**************************************************************
* 函 數 名 : main
* 函數功能 : 主函數
* 輸 入 : 無
* 輸 出 : 無
***************************************************************/
int main()
{
SysTick_Init(72);
LED_Init();
while(1)
{
led1=0;
led2=1;
delay_ms(500); //精確延時 500ms
led1=1;
led2=0;
delay_ms(500); //精確延時 500ms
}
}
主函數實現的功能比較簡單,首先對 SysTick 定時器進行初始化配置,選擇系統時鐘 8 分頻作為 SysTick 的時鐘,然后初始化 LED,這個初始化過程前面已經介紹過,大家也可以進入這個函數內查看。最后進入 while 循環語句,對 PC0和 PC1 管腳進行位操作,里面也調用了 delay_ms 延時函數,這時候的延時是非常精確的。
將工程程序編譯下載到開發板內, 可以看到 LED 模塊的 2 個指示燈實現了流水燈效果。
-
led
+關注
關注
242文章
23370瀏覽量
663319 -
流水燈
+關注
關注
21文章
433瀏覽量
59837 -
Systick
+關注
關注
0文章
62瀏覽量
13151
原文標題:STM32實例-SysTick實現2個LED流水燈效果
文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
【RA-Eco-RA2L1-48PIN-V1.0開發板試用】——點亮流水燈操作
![](https://file1.elecfans.com/web3/M00/06/8B/wKgZPGeMmWOARA_ZABWWIm7cbUA445.jpg)
【正點原子STM32H7R3開發套件試用體驗】流水燈
【RA-Eco-RA4E2-64PIN-V1.0開發板試用】RA4E2 實現流水燈操作
【RA-Eco-RA4E2-64PIN-V1.0開發板試用】MDK+點燈+流水燈
FPGA 實驗一:流水燈模塊
【紫光同創盤古PGX-Nano教程】——(盤古PGX-Nano開發板/PG2L50H_MBG324第三章)鍵控流水燈實驗例程
【紫光同創盤古PGX-MINI-4K教程】——(盤古PGX-MINI-4K開發板/PGC4KD-6ILPG144第二章)LED 流水燈實驗例程
利用systick計時器對LED等延時的時候,for循環中的ms和systick–>LOAD的值為什么不是同一個?
如何實現SysTick中斷的嵌套自身?
【紫光同創盤古PGX-Lite 7K教程】——(盤古PGX-Lite 7K開發板/PGC7KD-6IMBG256第二章)?LED 流水燈實驗例程
51單片機流水燈制作
![51單片機<b class='flag-5'>流水燈</b>制作](https://file1.elecfans.com/web2/M00/C1/E3/wKgaomXb8VyASKTsAACFYv8Crn0012.png)
評論