微控制器定時器雙擊 關於51微控制器定時器的靈活使用

2021-10-19 23:33:36 字數 4724 閱讀 1538

前段時間,做乙個專案,有串列埠收發指令判斷,按鍵型別判斷,長短按之類,power的定時關電,事件的輪詢掃瞄更新和display的定時掃瞄。這些要求就對定時器提出了要求,但是我的51微控制器只有兩個定時器,其中乙個又有debug口的波特率產生之用。於是乎我可以用的定時器就只剩下了乙個。怎麼辦?可能大家都只能用變數在定時中斷函式去做多了任務就行了,但是我總是感覺這樣會導致**看起來太不具有條理性,而且對於日後的管理不是很容易。思來想去,就想到了linux核心中對於定時器的封裝,那種物件導向的思想。

.h 檔案:

#ifndef __sc_timer_h

#define __sc_timer_h

/* sc_common.**件中包含了對資料型別的定義和包含對應的微控制器的配置標頭檔案,這裡就沒有列出,根據個人所使用情況而定 */

#include "sc_common.h"

#ifdef mode1t

#define t0times(65536-fosc/1000)

#define t1times(65536-10*fosc/1000)

#else

#define t0times(65536-fosc/12/1000)// 0.1ms

#define t1times(65536-10*fosc/12/1000)// 10ms

#endif /*mode1t*/

#define timer_size4

typedef struct

u8 timerid;/* 定時器的id,實則指明了起所在陣列中的位置 */

s8 isruning;/* 表明當前timer是否正在執行 */

u16 curtimes;/* 當前timer時間 */

u16 expiretimes;/* 當前timer的溢位時間 */

u8 existinarry; /* 當前的timer是否存在於陣列之中 */

timerfunc timerfunc; /* 當前timer的指定執行函式 */

} timer;

void inittimer(void);

s8 addtimer(timer *timer);

s8 deltimer(timer *timer);

s8 starttimer(timer *timer);

s8 modifytimer(timer *timer);

s8 stoptimer(timer *timer);

s8 isrunningtimer(timer *timer);

#endif/*__sc_timer_h*/

下面是這部分思想的重點實現,無非就是向timerarray陣列中新增刪除定時器,簡言之,即所謂的增刪改查,還有就是啟動停止定時器,考慮到51微控制器的效能,沒有像linux核心中那樣用鍊錶實現,同時定時器的總數也是有上限要求的。

.c檔案:

#include "sc_timer.h"

#include #include /* 這裡採用陣列的方式管理各個timer結構體 */

timer timerarray[timer_size];

u8 timerused = 0;

void inittimer(void)

tmod |= 0x01;

tl0 = t0times;

th0 = t0times >> 8;

et0 = 1;

tr0 = 1;

timerused = 0;

memset(timerarray, 0, sizeof(timerarray));

s8 addtimer(timer *timer)

if(timerused >= timer_size)

timerused = 0;

/*×ô¶šòåtimeridµäéú³é·œêœ£¬œžžú±íæäôúêý×éöðµäî»öã*/

timer->timerid = timerused;

timerarray[timerused] = *timer;

timerused++;

timer->existinarry = 1;

timer->isruning = 0;

printf("%bu

", timer->timerid);

return 0;

static void del_timer(timer *timerarray, u8 *timerused, u8 pos)

u8 i = 0;

u8 len = *timerused;

for(i=pos; itimerid >= timer_size || timer->timerid < 0 || timer->existinarry == 0)

return -1;

if(timerused <= 0)

return -1;

del_timer(timerarray, &timerused, timer->timerid);

timer->existinarry = 0;

return 0;

s8 starttimer(timer *timer)

if(timer->timerid >= timer_size || timer->timerid < 0 || timer->existinarry == 0)

return -1;

timerarray[timer->timerid].isruning = 1;

return 0;

s8 modifytimer(timer *timer)

if(timer->timerid >= timer_size || timer->timerid < 0 || timer->existinarry == 0)

return -1;

timerarray[timer->timerid].curtimes = timer->curtimes;

timerarray[timer->timerid].expiretimes = timer->expiretimes;

timerarray[timer->timerid].timerfunc = timer->timerfunc;

return 0;

s8 stoptimer(timer *timer)

if(timer->timerid >= timer_size || timer->timerid < 0 || timer->existinarry == 0)

return -1;

timerarray[timer->timerid].isruning = 0;

return 0;

s8 isrunningtimer(timer *timer)

s8 ret = -1;

if(timer->timerid >= timer_size || timer->timerid < 0 || timer->existinarry == 0)

return ret;

ret = timerarray[timer->timerid].isruning;

return ret;

* 定時器的中斷函式負責判斷各個事件的時間是否到達,如果到達呼叫相應的相應函式進行執行

* 由於51微控制器的函式指標是沒有堆疊保護的,所以這裡加入了彙編指令執行堆疊的保護,個人

* 水平有限,這裡希望大家指正是否有錯誤之處,謝謝

void tm0isr(void) interrupt 1

u8 i = 0;

tl0 = t0times;

th0 = t0times >> 8;

for(i=0; i= timerarray[i].expiretimes)

#pragma asm

push acc

push dph

push dpl

#pragma endasm

(*timerarray[i].timerfunc)();

#pragma asm

pop dpl

pop dph

pop acc

#pragma endasm

timerarray[i].curtimes = 0;

本文中的資料型別都是通過typedef轉化過的,為了時時刻刻關於自己的記憶體使用量,呵呵,定義如下

typedef unsigned char u8;

typedef unsigned short int u16;

typedef unsigned long int u32;

typedef signed char s8;

typedef signed short int s16;

typedef signed long int s32;

typedef bit bool;

個人認為這個對於專案後面的能夠有效快速的進行起到了很大的幫助。   典型的用法如下:

timer presskeytimer; /* 這裡的timer請使用全域性變數,大家應該懂的,就是變數的生命週期的問題啦 */

presskeytimer.curtimes = 0;

presskeytimer.expiretimes = 11;

presskeytimer.timerfunc = judgekeytype;

addtimer(&presskeytimer);

starttimer(&presskeytimer);

至此,到規定的時間11msec時,就會呼叫這裡的judekeytype函式,進行輪詢發現是否有按鍵按下,並判斷其型別。

望有改進意見,謝謝高手指正。

51微控制器 定時器

定時 計數器的結構和工作原理 定時 計數器的實質是加1計數器 16位 由高8位和低8位兩個暫存器組成。80c51 微控制器定時 計數器的工作是由兩個特殊功能暫存器控制的。tmod是定時 計數器的工 作方式暫存器,確定工作方式和功能,低四位用於t0,高四位用於t1。t con是控制寄 存器,控制t0和...

51微控制器 定時器

標準的51微控制器內部有t0和t1兩個定時器。定時器的計數值儲存在暫存器中。th0 tl0用於t0,th1 tl1用於t1.定時器儲存暫存器 名稱描述 sfr位址 復位值th0 t0高位元組 0x8c 0x00 tl0t0低位元組 0x8a 0x00 th1t1高位元組 0x8d 0x00 tl1t...

微控制器定時器雙擊 微控制器實現60s定時器

2個定時中斷,2個按鈕中斷 include define seg p2 數碼管 斷碼口 define scanp p1 數碼管 com掃瞄口sbit oc p0 0 定義573鎖存器使能口,我是用的573驅動7段數碼管 sbit pb0 p3 2 按鈕0 sbit pb1 p3 3 按鈕1 第乙個定...