久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6903|回復: 13
打印 上一主題 下一主題
收起左側

基于單片機定時器,實現類似PLC多個軟定時器的MCU編程思路(原創代碼)

  [復制鏈接]
跳轉到指定樓層
樓主
ID:471574 發表于 2020-11-13 15:09 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
       單片機要想實現多個不同時基的控制,除了上系統外,本人采用分時段的方法,結合PLC的控制原理,實現出類似PLC定時器的控制方法,分別有0.01S定時器 12個,0.1MS定時器 10個,1S定時器10個,可以單獨設定,同時使用。如果MCU的程序容量比較大,可以實現更多的定時器,不過一般建議根據實際項目要求來調整。實現過程思路代碼如下(STC89單片機):
//以下程序及算法由本人zyhlove813原創,特別是soft_timer實現算法值得借鑒,適用所有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定時器數組索引上限=12-1=11,因此0.01S定時器的個數=12個
#define T100ms (T10ms+10) //0.1S定時器數組索引上限=22-1=21,因此0.1S定時器的個數=21-11=10個
#define Timers 32   //1S定時器數組索引上限=32-1=31,因此1S定時器的個數=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的狀態
#define GET_BIT(s,b)((s>>b)&0x01)                //宏,獲取某個位的值,返回0或1的狀態
#define SET_EN(b,c) (SET_BIT(timer_en[b/8],b%8,c))  //設置對應定時器使能狀態
#define SET_ON(b,c) (SET_BIT(timer_on[b/8],b%8,c))  //設置對應定時器對應使能狀態
#define GET_EN(b) (GET_BIT(timer_en[b/8],b%8))     //獲取對應定時器對應使能狀態
#define GET_ON(b) (GET_BIT(timer_on[b/8],b%8))     //獲取對應定時器線圈狀態
uint8_t  timer_en[Timers_bit];    //定時器使能狀態緩存
uint8_t  timer_on[Timers_bit];    //定時器線圈狀態緩存
uint32_t  timer_pv[Timers];       //定時器目標值緩存
uint32_t  timer_cv[Timers];       //定時器當前值緩存
uint32_tcount_1ms;               //硬件定時器1MS計數器
sbit LED1=P1^1;                   //測試用的IO1
sbit LED2=P1^2;                     //測試用的IO2
void soft_timer(void);            //聲明函數
void timer0_isr() interrupt 1    //定時器0中斷,每1MS中斷一次
{
   TL0 = T1MS;                     //reloadtimer0 low byte
   TH0 = T1MS>> 8;                //reload timer0 high byte
   soft_timer();                  //調用軟件定時器判斷
}
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)使能無效,停止計時               
     }
   }
}
//軟件定時器的實現
void soft_timer()
{
    uint8_ti;
    uint8_ttemp;
    count_1ms++;        //1MS計數值+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 保障當前值根據使能狀態自動加或清零
             temp=GET_EN(i)*(timer_cv>=timer_pv);   //計算是否到達目標時間,如果使能無效的話,結果是0,如果使能有效的話,而且當前值大于目標值,結果是1
             SET_ON(i,temp);  //更新線圈是否到時狀態
        }
    }
    //以下算法相同
    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計數器重啟
        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, 下載次數: 107)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏18 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:97678 發表于 2020-11-15 09:09 | 只看該作者
好東西!!!
下載來用用看!!!
回復

使用道具 舉報

板凳
ID:240034 發表于 2021-1-15 14:41 | 只看該作者
定時部分程序結構不錯,參考借用下,
回復

使用道具 舉報

地板
ID:878420 發表于 2021-3-3 15:33 來自手機 | 只看該作者
沒有看懂啊
回復

使用道具 舉報

5#
ID:948578 發表于 2021-10-27 18:26 | 只看該作者
s,a,b,c分別是表示啥參數?
回復

使用道具 舉報

6#
ID:471574 發表于 2021-10-30 10:40 | 只看該作者
yjheeqgnui 發表于 2021-10-27 18:26
s,a,b,c分別是表示啥參數?

b表示第幾個軟定時器,c表示ON或為OFF,用于設置定時器EN或ON的狀態
s表示軟定時器變量,因為是數組(timer_en,timer_on),需要計算出索引值,
注意得是timer_en[0]中二進制每個位,對應了軟件定時器0-7的狀態
回復

使用道具 舉報

7#
ID:875095 發表于 2021-10-31 10:21 | 只看該作者
嗯,這幾天也在想定時問題,借鑒一下
回復

使用道具 舉報

8#
ID:346397 發表于 2022-5-30 18:50 | 只看該作者
思路不錯
回復

使用道具 舉報

9#
ID:105206 發表于 2022-7-3 07:49 | 只看該作者
漂亮,感謝樓主分享。
回復

使用道具 舉報

10#
ID:462629 發表于 2022-7-9 15:25 | 只看該作者
這個思路可以,學習了
回復

使用道具 舉報

11#
ID:914666 發表于 2022-7-11 12:50 | 只看該作者
51hei有你更精彩
回復

使用道具 舉報

12#
ID:71535 發表于 2022-7-27 20:27 | 只看該作者
算法思路值得學習,學習分享
回復

使用道具 舉報

13#
ID:137736 發表于 2022-10-31 16:44 | 只看該作者
頂,軟定時器,本人正在學習,編了一個仿Arduno的millis程序,實現多程序非阻塞運行
回復

使用道具 舉報

14#
ID:334781 發表于 2023-1-31 10:35 | 只看該作者
下載過來,研究一下,這個定時的思路不錯!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品久久久久久久久久久免费看 | 美女一级毛片 | 人人干人人玩 | 夜夜干夜夜操 | 一区二区三区视频 | 激情五月综合 | 欧美成人高清 | 国产日韩精品一区 | 一区二区三区视频在线免费观看 | 亚洲精品一区二区在线观看 | 一区二区三区四区在线 | 精品国产一区二区久久 | 亚洲精品在线免费观看视频 | 亚洲一区二区视频 | 中文字幕高清 | 日韩欧美一区二区三区免费观看 | 精品丝袜在线 | 国产精品久久久久久久免费大片 | 亚洲精品一区中文字幕乱码 | 91精品国产91久久久久久吃药 | 天天爽天天操 | 久久人 | 久久美女网 | 中文av字幕 | 国产成人免费视频网站视频社区 | 99视频免费在线观看 | 精品美女在线观看视频在线观看 | 中文字幕免费视频 | 久久久综合久久 | 日本久久视频 | 欧美一级小视频 | 国产日韩久久久久69影院 | 久久久久九九九女人毛片 | 在线观看日韩精品视频 | 国产精品亚洲第一区在线暖暖韩国 | 国产精品一区二区视频 | 天天干天天操 | 久久精品成人 | 午夜精品久久久久久久久久久久 | 国产福利久久 | 成人片网址 |