找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 7278|回復(fù): 12
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)程序設(shè)計(jì)-時(shí)基 通過(guò)定時(shí)器中斷計(jì)數(shù)的方式定時(shí)的實(shí)現(xiàn)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
在一個(gè)程序中的很多地方都需要定時(shí),如LED閃爍、按鍵消抖和通訊等待等。通過(guò)阻塞CPU的方式定時(shí),程序性能極差;通過(guò)硬件定時(shí)器定時(shí),性能好,定時(shí)非常準(zhǔn)確,但定時(shí)器資源有限;通過(guò)定時(shí)器中斷計(jì)數(shù)的方式定時(shí),性能好,定時(shí)較準(zhǔn)確,使用非常靈活。本文主要描述通過(guò)定時(shí)器中斷計(jì)數(shù)的方式定時(shí)的實(shí)現(xiàn)。


2.定時(shí)器中斷計(jì)數(shù)
初始化?個(gè)定時(shí)器,1ms中斷?次。定義?個(gè)uint32_t變量,每中斷?次,變量加1,變量溢出后
變?yōu)?。
定時(shí)器初始化和中斷服務(wù)程序
  1. uint32_t volatile time_base_ms;  //volatile關(guān)鍵字防?編譯器優(yōu)化
  2. void timer_init(void)
  3. {
  4.   //初始化定時(shí)器
  5.   time_base_ms = 0;
  6. }
  7. // 定時(shí)器中斷服務(wù)程序
  8. void Timer_hander(void) interrupt 19
  9. {
  10.   ++time_base_ms;
  11. }
復(fù)制代碼



3.獲取當(dāng)前時(shí)刻
定時(shí)器開(kāi)啟之后,變量time_base_ms開(kāi)始計(jì)數(shù),每加1表示時(shí)間過(guò)去1ms。在訪問(wèn)變量
time_base_ms的 過(guò)程中有可能發(fā)?了中斷,必須特殊處理。?法是,先讀?次,再讀?次并?較?
次,如果相等說(shuō)明兩次讀的過(guò)程都沒(méi)有發(fā)?中斷,數(shù)據(jù)可靠;如果不相等,說(shuō)明兩次讀有?次發(fā)?了
中斷,下?次中斷沒(méi)有那么快到來(lái),再讀?次數(shù)據(jù)?定不會(huì)發(fā)?中斷(系統(tǒng)時(shí)鐘不太慢的情況下)。
  1. uint32_t time_current(void)
  2. {
  3.   uint32_t ret;

  4.   ret = time_base_ms;     // 讀取計(jì)數(shù),該過(guò)程可能中斷

  5.   if(ret != time_base_ms){  // 讀取計(jì)數(shù),該過(guò)程可能中斷;如果不相等,說(shuō)明兩
  6. 個(gè)過(guò)程有?個(gè)發(fā)?過(guò)中斷
  7.     ret = time_base_ms;   // 讀取計(jì)數(shù),該過(guò)程沒(méi)有中斷
  8.   }

  9.   return ret;
  10. }
復(fù)制代碼

4.定時(shí)的計(jì)算
計(jì)算過(guò)去某個(gè)時(shí)刻據(jù)當(dāng)前時(shí)刻的時(shí)間,或者說(shuō)過(guò)去的某個(gè)時(shí)刻據(jù)現(xiàn)在有多久。需要考慮過(guò)去某個(gè)
時(shí)刻到當(dāng)前時(shí)刻變量time_base_ms有沒(méi)有溢出。
  1. uint32_t time_timing_ms(uint32_t moment)
  2. {
  3.   uint32_t current_moment;
  4.   uint32_t ret;

  5.   current_moment = time_current();

  6.   if(current_moment >= moment){
  7.     ret = current_moment - moment;
  8.   }else{
  9.     ret = (0xffffffff - moment) + current_moment + 1;
  10.   }

  11.   return ret;
  12. }
復(fù)制代碼

應(yīng)用
led1每秒閃爍1次,led2每秒閃爍5次。

  1. void main()
  2. {
  3.   uint32_t led1_moment;
  4.   uint32_t led2_moment;
  5.   //初始化定時(shí)器
  6.   timer_init();
  7.   //記錄當(dāng)前時(shí)刻
  8.   led1_moment = time_current();
  9.   led2_moment = time_current();
  10.   while(1){
  11.     //檢查時(shí)間是否過(guò)去500ms
  12.     if(time_timing_ms(led1_moment) > 500){
  13.       led1 = ~led1;
  14.       led1_moment = time_current();  //記錄當(dāng)前時(shí)刻
  15.     }
  16.     //檢查時(shí)間是否過(guò)去100ms
  17.     if(time_timing_ms(led2_moment) > 100){
  18.       led2 = ~led2;
  19.       led2_moment = time_current();  //記錄當(dāng)前時(shí)刻
  20.     }
  21.    
  22.   }
  23. }
復(fù)制代碼

示例:



評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏9 分享淘帖 頂2 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:798322 發(fā)表于 2023-6-26 21:25 | 只看該作者
void Timer_hander(void) interrupt 19
這個(gè)中斷號(hào)是不是有問(wèn)題,然后時(shí)間應(yīng)該是時(shí)間差比較100 500ms,單片機(jī)的定時(shí)和晶振有關(guān)。
回復(fù)

使用道具 舉報(bào)

板凳
ID:479880 發(fā)表于 2023-6-29 11:03 來(lái)自觸屏版 | 只看該作者
玲瓏紅豆 發(fā)表于 2023-6-26 21:25
void Timer_hander(void) interrupt 19
這個(gè)中斷號(hào)是不是有問(wèn)題,然后時(shí)間應(yīng)該是時(shí)間差比較100 500ms,單 ...

代碼不完全可用,只是用來(lái)說(shuō)明思路
回復(fù)

使用道具 舉報(bào)

地板
ID:475306 發(fā)表于 2023-7-28 10:02 | 只看該作者
小白沒(méi)看懂啊,點(diǎn)亮那個(gè)IO口了?
回復(fù)

使用道具 舉報(bào)

5#
ID:1090778 發(fā)表于 2023-8-5 14:35 | 只看該作者
小白沒(méi)看懂啊,繼續(xù)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

6#
ID:479880 發(fā)表于 2023-8-9 18:32 來(lái)自觸屏版 | 只看該作者
KTTCO 發(fā)表于 2023-7-28 10:02
小白沒(méi)看懂啊,點(diǎn)亮那個(gè)IO口了?

偽代碼
回復(fù)

使用道具 舉報(bào)

7#
ID:303735 發(fā)表于 2023-10-3 14:54 | 只看該作者
KTTCO 發(fā)表于 2023-7-28 10:02
小白沒(méi)看懂啊,點(diǎn)亮那個(gè)IO口了?

初始化把LED1定義到想要輸出的口就行了,
回復(fù)

使用道具 舉報(bào)

8#
ID:1109233 發(fā)表于 2024-2-4 18:53 | 只看該作者
不完全可用,只是用來(lái)說(shuō)明思路
回復(fù)

使用道具 舉報(bào)

9#
ID:627251 發(fā)表于 2024-2-17 22:02 | 只看該作者
這代碼... AI生成的吧
回復(fù)

使用道具 舉報(bào)

10#
ID:1126189 發(fā)表于 2024-6-20 12:57 | 只看該作者
講的非常容易理解
回復(fù)

使用道具 舉報(bào)

11#
ID:1126656 發(fā)表于 2024-9-22 18:01 | 只看該作者
新同學(xué)們慢慢來(lái),逐步成長(zhǎng)!多向大師學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

12#
ID:1112748 發(fā)表于 2025-1-12 18:15 | 只看該作者
新同學(xué)們慢慢來(lái),逐步成長(zhǎng)!多向大師學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表