找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3957|回复: 1
打印 上一主题 下一主题
收起左侧

单片机时间片轮询法(数码管显示—中断消抖)源程序

[复制链接]
跳转到指定楼层
楼主
时间片轮询法(数码管显示——中断消抖)
    本文章是关于运用时间片轮询法(前后台系统),完成对时钟的简单控制,同时通过中断完成对按键的消失抖,显示程序中静态变量变量的定义是关键,
    对按键消抖应该是未按下(抬起——1)——按下(0)——抬起(1),之间需要20ms左右的延时消抖。假如按键按下(k1 = 0),同时由于(keydelay<<1)|k1,16ms之后keydelay = 0x00;如果按键未按下(k1 = 1),(keydelay<<1)|k1,16ms之后keydelay = oxff,及k1一直都未按下。

电路原理图如下:

主函数
  1. #include "reg52.h"

  2. //#include "Delay.h"
  3. #include "Display.h"
  4. #include "Timer.h"
  5. void main()
  6. {
  7.     Timer0Init(); //中断初始化  
  8.     while(1)
  9.     {     
  10.      Datapros();
  11.        TaskProcess();
  12.      KeyProcess();
  13.     }
  14.    
  15. }
  16. Displsy.c模块函数
  17. #include "Display.h"
  18. //#include "Delay.h"
  19. #include "Timer.h"
  20. unsigned char Bit_Selection[8]={0xfe,0Xfd,0Xfb,0Xf7,0Xef,0Xdf,0Xbf,0x7f};   //位选
  21. unsigned char smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段选0123456789
  22. unsigned char hour = 20,min = 51,sec = 58; //定义变量
  23. unsigned char DisplayData[8];
  24. bit keyback = 1;//按键之前的状态
  25. bit keystay = 1;   //按键现在的状态
  26. void DigDisplay()
  27. {
  28.    static unsigned char i;   //定义静态变量

  29.        P0 = 0x00;            //消影
  30.       P2 = Bit_Selection[i];  //位选
  31.       P0 = DisplayData[i];    //段选         
  32.                      
  33.        i++;
  34.         if(i==8)
  35.         {
  36.          i = 0;
  37.         }
  38. }
  39. void Datapros()
  40. {   
  41.     DisplayData[0]=smgduan[hour/10];
  42.     DisplayData[1]=smgduan[hour%10];
  43.     DisplayData[2]=0x40;
  44.     DisplayData[3]=smgduan[min/10];
  45.     DisplayData[4]=smgduan[min%10];
  46.     DisplayData[5]=0x40;
  47.     DisplayData[6]=smgduan[sec/10];
  48.     DisplayData[7]=smgduan[sec%10];
  49.   
  50.    
  51. }
  52. void Clock_Chang()//时间自加函数
  53. {  
  54.     sec++;        //每一秒钟执行一次
  55.     if(sec==60)
  56.    {
  57.     sec = 0;
  58.     min++;
  59.     if(min==60)
  60.      {
  61.       min = 0;
  62.       hour++;
  63.      if(hour==24)
  64.          hour = 0;
  65.      }        
  66.    }
  67.         
  68. }
  69. void KeyProcess()
  70. {
  71. static unsigned char keymin;
  72.      keymin=min;
  73.     if(keystay!=keyback)//判断按键现在状态与之前状态是否有变化
  74.    {  
  75.         if(keyback==0)   //如果之前状态是零,则说明按键有触发
  76.     {
  77.          keymin++;
  78.       if(keymin==60)
  79.        keymin=0;
  80.     }      
  81.    }
  82.     min=keymin;
  83.    keyback = keystay;  //按键状态赋值
  84. }
  85. void Keyscan()//按键扫描,在中断中处理
  86. {  
  87.     static unsigned char keydelay=0xff;
  88.     keydelay=(keydelay<<1)|k1;  //通过Keydelay移位延时,每2ms移动一位
  89.     //keydelay=(keydelay<<1)|k2;
  90.     //keydelay=(keydelay<<1)|k3;
  91.     if(keydelay==0x00)  //如果16ms后keydelay=0x00,则按键状态置为0(按下)
  92.    {
  93.       keystay = 0;
  94.    }
  95.    if(keydelay==0xff)
  96.    {      
  97.        keystay = 1;
  98.    }

  99. }
  100. void ClockProcess()//闹钟判断函数
  101. {   
  102.    unsigned char nhour = 20,nmin = 52,nsec = 1; //定义变量
  103.    if((nsec==sec)&&(nmin==min)&&(nhour==hour))
  104.   {         
  105.      beep=~beep;   
  106.       D1 = 0;         
  107.   }
  108.   if(sec==nsec+2)//两秒钟之后在发生变化
  109.   {            
  110.     beep=~beep;   
  111.       D1 = 1;
  112.   }
  113.   
  114. }
  115. Timer.c模块函数
  116. #include "Timer.h"
  117. #include "Display.h"
  118. //#include "Delay.h"  
  119. typedef struct SUSPEND_VARIABLE
  120. {
  121.      unsigned char Flag;                 // 程序运行标记:0-不运行,1运行
  122.      unsigned long Time;              // 计时器

  123.         unsigned long ItvTime;              // 任务运行间隔时间
  124.   
  125.      void (*Function)(void);    // 要运行的任务函

  126. }VARIABLE;
  127. VARIABLE TaskCount[] =
  128. {
  129.                     {0,5,5,DigDisplay},//显示
  130.                     {0,1000,1000,Clock_Chang},//时钟秒自加
  131.           {0,1000,1000,ClockProcess},//闹钟
  132.           {0,2,2,Keyscan},//按键扫描
  133. };//声明
  134. void Timer0Init()
  135. {   
  136.     TMOD = 0X01;   //选择为定时器0模式,工作方式1,仅用TR0打开启动。
  137.     TH0 = 0Xfc;  //给定时器赋初值,定时100us
  138.     TL0 = 0X18;  //给定时器赋初值如何是FF,定时1us
  139.     ET0 = 1;     //打开定时器0中断允许
  140.     EA = 1;     //打开总中断
  141.     TR0 = 1;    //打开定时器   
  142. }
  143. void Timer0() interrupt 1     
  144. {
  145.     unsigned char i;[align=left][color=#007000][backcolor=transparent][font=Tahoma,&][size=14px]               [/size][/font][/backcolor][/color][/align][align=left][color=#007000][backcolor=transparent][font=Tahoma,&][size=14px]//#define COUNT 4    //中断函数运行函数数量 [/size][/font][/backcolor][/color][/align]
  146.     TH0 = 0Xfc;                             //给定时器赋初值,定时100us
  147.     TL0 = 0x18;
  148.     for(i = 0;i<COUNT;i++)              //循环扫描,判断哪一个任务定时时间已到
  149.     {
  150.      if(TaskCount[i].Time)
  151.     {
  152.       TaskCount[i].Time--;             //如果定时时间已到则清零,标记置一
  153.       if(TaskCount[i].Time==0)
  154.        {
  155.        TaskCount[i].Flag = 1;
  156.        TaskCount[i].Time = TaskCount[i].ItvTime;       // 恢复计时器值,从新下一次
  157.        }
  158.     }
  159.    }   
  160. }
  161. void TaskProcess()   //处理函数
  162. {
  163.      unsigned char i;  
  164.     for (i=0; i<COUNT; i++)           // 循环判断那一个任务需要运行,逐个任务时间处理
  165.    {
  166.       if (TaskCount[i].Flag)               // 时间不为0
  167.          {
  168.              TaskCount[i].Function();         // 运行任务
  169.              TaskCount[i].Flag = 0;          // 标志清0
  170.            }
  171.    }   
  172. }
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:95059 发表于 2021-4-9 23:29 | 只看该作者
没有贴出来原程序啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表