標題: 基于單片機定時器,實現(xiàn)類似PLC多個軟定時器的MCU編程思路(原創(chuàng)代碼) [打印本頁]
作者: zyhlove813 時間: 2020-11-13 15:09
標題: 基于單片機定時器,實現(xiàn)類似PLC多個軟定時器的MCU編程思路(原創(chuàng)代碼)
單片機要想實現(xiàn)多個不同時基的控制,除了上系統(tǒng)外,本人采用分時段的方法,結合PLC的控制原理,實現(xiàn)出類似PLC定時器的控制方法,分別有0.01S定時器 12個,0.1MS定時器 10個,1S定時器10個,可以單獨設定,同時使用。如果MCU的程序容量比較大,可以實現(xiàn)更多的定時器,不過一般建議根據(jù)實際項目要求來調(diào)整。實現(xiàn)過程思路代碼如下(STC89單片機):
//以下程序及算法由本人zyhlove813原創(chuàng),特別是soft_timer實現(xiàn)算法值得借鑒,適用所有MCU,源碼示例請下載附件
#include "reg51.h"
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
/* define constants */
#define true 1
#define false 0
#define FOSC 11059200L //時鐘頻率
#define T1MS (65536-FOSC/12/1000) //1MS定時器設定值
#define T10ms 12 //0.01S定時器數(shù)組索引上限=12-1=11,因此0.01S定時器的個數(shù)=12個
#define T100ms (T10ms+10) //0.1S定時器數(shù)組索引上限=22-1=21,因此0.1S定時器的個數(shù)=21-11=10個
#define Timers 32 //1S定時器數(shù)組索引上限=32-1=31,因此1S定時器的個數(shù)=31-21=10個
#define Timers_bit (Timers/8) //八個定時器為一組,共32/8=4組
#define SET_BIT(s,b,c)(s=(s&(~(1<<b)))+(c<<b)) //宏,設置某個位的值,0或1的狀態(tài)
#define GET_BIT(s,b)((s>>b)&0x01) //宏,獲取某個位的值,返回0或1的狀態(tài)
#define SET_EN(b,c) (SET_BIT(timer_en[b/8],b%8,c)) //設置對應定時器使能狀態(tài)
#define SET_ON(b,c) (SET_BIT(timer_on[b/8],b%8,c)) //設置對應定時器對應使能狀態(tài)
#define GET_EN(b) (GET_BIT(timer_en[b/8],b%8)) //獲取對應定時器對應使能狀態(tài)
#define GET_ON(b) (GET_BIT(timer_on[b/8],b%8)) //獲取對應定時器線圈狀態(tài)
uint8_t timer_en[Timers_bit]; //定時器使能狀態(tài)緩存
uint8_t timer_on[Timers_bit]; //定時器線圈狀態(tài)緩存
uint32_t timer_pv[Timers]; //定時器目標值緩存
uint32_t timer_cv[Timers]; //定時器當前值緩存
uint32_tcount_1ms; //硬件定時器1MS計數(shù)器
sbit LED1=P1^1; //測試用的IO1
sbit LED2=P1^2; //測試用的IO2
void soft_timer(void); //聲明函數(shù)
void timer0_isr() interrupt 1 //定時器0中斷,每1MS中斷一次
{
TL0 = T1MS; //reloadtimer0 low byte
TH0 = T1MS>> 8; //reload timer0 high byte
soft_timer(); //調(diào)用軟件定時器判斷
}
void main()
{
TMOD = 0x01; //set timer0 as mode1 (16-bit)
TL0 = T1MS; //initialtimer0 low byte
TH0 = T1MS>> 8; //initial timer0 high byte
TR0 = 1; //timer0 start running
ET0 = 1; //enable timer0 interrupt
EA = 1; //open global interrupt switch
count_1ms = 0; //initial counter
timer_pv[1]=1; //0.01S定時器(1)的目標值設為1,即10MS
timer_pv[2]=1; //0.01S定時器(2)的目標值設為1,即10MS
timer_pv[12]=5; //0.1S定時器(12)的目標值設為5,即500MS
timer_pv[13]=5; //0.1S定時器(13)的目標值設為5,即500MS
SET_EN(1,1); //0.01S定時器(1)使能有效,開始計時
SET_EN(12,1); //0.1S定時器(12)使能有效,開始計時
while (1)
{
if(GET_ON(1)) //如果0.01S定時器(1)的定時線圈為1,即定時時間到
{
LED1=1; //LED1亮
SET_EN(2,1); //0.01S定時器(2)使能有效,開始計時
SET_EN(1,0); //0.01S定時器(1)使能無效,停止計時
}
if(GET_ON(2)) //如果0.01S定時器(2)的定時線圈為1,即定時時間到
{
LED1=0; //LED1滅
SET_EN(1,1); //0.01S定時器(1)使能有效,開始計時
SET_EN(2,0); //0.01S定時器(2)使能無效,停止計時
}
if(GET_ON(12)) //如果0.1S定時器(12)的定時線圈為1,即定時時間到
{
LED2=1; //LED2亮
SET_EN(13,1); //0.1S定時器(13)使能有效,開始計時
SET_EN(12,0); //0.1S定時器(12)使能無效,停止計時
}
if(GET_ON(13))
{
LED2=0; //LED2滅
SET_EN(12,1); //0.1S定時器(12)使能有效,開始計時
SET_EN(13,0); //0.1S定時器(13)使能無效,停止計時
}
}
}
//軟件定時器的實現(xiàn)
void soft_timer()
{
uint8_ti;
uint8_ttemp;
count_1ms++; //1MS計數(shù)值+1
if(count_1ms%10==0) //判斷是否0.01S時間到
{
for(i=0;i<T10ms;i++) //更新0.01S定時器的當前值
{
timer_cv+=GET_EN(i); //如果EN=1,則當前值+1,否則+0
timer_cv*=GET_EN(i); //如果EN=1,則當前值不變,否則當前值=0 保障當前值根據(jù)使能狀態(tài)自動加或清零
temp=GET_EN(i)*(timer_cv>=timer_pv); //計算是否到達目標時間,如果使能無效的話,結果是0,如果使能有效的話,而且當前值大于目標值,結果是1
SET_ON(i,temp); //更新線圈是否到時狀態(tài)
}
}
//以下算法相同
if(count_1ms%100==0) //判斷是否0.1S時間到
{
for(i=T10ms;i<T100ms;i++)
{
timer_cv+=GET_EN(i);
timer_cv*=GET_EN(i);
temp=GET_EN(i)*(timer_cv>=timer_pv);
SET_ON(i,temp);
}
}
if(count_1ms%1000==0) //判斷是否1S時間到
{
count_1ms=0; //1MS計數(shù)器重啟
for(i=T100ms;i<Timers;i++)
{
timer_cv+=GET_EN(i);
timer_cv*=GET_EN(i);
temp=GET_EN(i)*(timer_cv>=timer_pv);
SET_ON(i,temp);
}
}
}
全部資料51hei下載地址:
SoftTimer.rar
(31.31 KB, 下載次數(shù): 107)
2020-11-13 15:07 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者: jovew 時間: 2020-11-15 09:09
好東西。!
下載來用用看。!
作者: lvlv99 時間: 2021-1-15 14:41
定時部分程序結構不錯,參考借用下,
作者: 51mcu學習 時間: 2021-3-3 15:33
沒有看懂啊
作者: yjheeqgnui 時間: 2021-10-27 18:26
s,a,b,c分別是表示啥參數(shù)?
作者: zyhlove813 時間: 2021-10-30 10:40
b表示第幾個軟定時器,c表示ON或為OFF,用于設置定時器EN或ON的狀態(tài)
s表示軟定時器變量,因為是數(shù)組(timer_en,timer_on),需要計算出索引值,
注意得是timer_en[0]中二進制每個位,對應了軟件定時器0-7的狀態(tài)
作者: hondephy@126.co 時間: 2021-10-31 10:21
嗯,這幾天也在想定時問題,借鑒一下
作者: Juncox 時間: 2022-5-30 18:50
思路不錯
作者: jubaolun 時間: 2022-7-3 07:49
漂亮,感謝樓主分享。
作者: woyaodwn 時間: 2022-7-9 15:25
這個思路可以,學習了
作者: yinds5092 時間: 2022-7-11 12:50
51hei有你更精彩
作者: waerdeng 時間: 2022-7-27 20:27
算法思路值得學習,學習分享
作者: zmc419 時間: 2022-10-31 16:44
頂,軟定時器,本人正在學習,編了一個仿Arduno的millis程序,實現(xiàn)多程序非阻塞運行
作者: yxdz1358 時間: 2023-1-31 10:35
下載過來,研究一下,這個定時的思路不錯!
歡迎光臨 (http://www.torrancerestoration.com/bbs/) |
Powered by Discuz! X3.1 |