找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1676|回复: 1
收起左侧

单片机定时器及中断实现百秒以内正计时程序

[复制链接]
ID:903830 发表于 2022-11-16 15:49 | 显示全部楼层 |阅读模式
定时器及中断设计电路如图所示,可以看到使用两个数码管来显示。实现百秒之内的正计时器(如17秒),到达17秒LED闪一下计时结束,数码管实时显示正计时值。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
图.png

单片机源程序如下:
  1. //名称: 定时器实现数码管倒计时
  2. #include <reg51.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. #define SEG P3

  6. sbit SCON1 = P2^0;
  7. sbit SCON2 = P2^1;
  8. sbit LED = P2^5;

  9. uchar num=0,ge,shi;    //倒计时17秒  7秒    正计时 0
  10. uchar count=0;
  11. uchar flag;

  12. //定义表格存放共阳极LED的点阵码
  13. unsigned char code ledTab[]={
  14.         0xC0, // 1100 0000 数字0
  15.         0xF9, // 1111 1001 数字1
  16.         0xA4, // 1010 0100 数字2
  17.         0xB0, // 1011 0000 数字3
  18.         0x99, // 1001 1001 数字4
  19.   0x92, // 1001 0010 数字5
  20.         0x82, // 1000 0010 数字6
  21.         0xF8, // 1111 1000 数字7
  22.         0x80, // 1000 0000 数字8
  23.         0x90  // 1001 0000 数字9
  24. };  

  25. //毫秒级延时函数
  26. void delay(uint z)
  27. {
  28.         uint x,y;
  29.         for(x = z; x > 0; x--)
  30.                 for(y = 120; y > 0 ; y--);
  31. }


  32. void T0INTinit() //定时器T0初始化
  33. {
  34.         TMOD=0x01;
  35.         TH0=(65536-50000)/256;
  36.         TL0=(65536-50000)%256;  //50ms
  37.         EA=1;  //开总中断
  38.         ET0=1; //开定时器0
  39.         TR0=1; //开始计时
  40. }


  41. void T0INT() interrupt 1
  42. {
  43.         TH0=(65536-50000)/256;
  44.         TL0=(65536-50000)%256;
  45.         flag++;
  46.         if(flag==20)//当定时到1秒时执行
  47.         {
  48.                 flag=0;
  49.                 num++;     //
  50.                 if (num > 17)    //
  51.                 {
  52.                         num = 0;
  53.                         TR0=0;  //停止计时
  54.       SEG=0xff;   //消影 不然会闪烁一下                       
  55.                         LED=0;
  56.                         delay(1000);
  57.                         LED=1;
  58.                         while(1)
  59.                         {
  60.                           SEG=0xff;  //计时结束 熄灭数码管
  61.                         }
  62.                 }
  63.         }
  64. }



  65. void main(){
  66.         T0INTinit();
  67.         while(1)
  68.         {       
  69.                 SEG=0xff; //消影
  70.                 shi = num / 10;
  71.                 ge = num % 10;
  72.                 switch(count)
  73.                 {       
  74.                         case 0: SCON1=0;SCON2=1;SEG=ledTab[ge];break;  //共阳极
  75.                         case 1: SCON1=1;SCON2=0;SEG=ledTab[shi];break;
  76.                 }
  77.                 count++;
  78.                 if(count>1) count=0;
  79.         }
  80. }
复制代码

Keil代码与Proteus8.13版本的仿真下载(注意:不能兼容其他版本 只能用8.13打开):
百秒以内正计时.zip (105.04 KB, 下载次数: 13)


评分

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

查看全部评分

回复

使用道具 举报

ID:491577 发表于 2022-11-16 22:04 | 显示全部楼层
用定时器中断计数可以实现任意时间定时,无论是秒、分钟、小时、天、月都没有问题的。这是基本功。
例如:
void T0INTinit() //定时器T0初始化
{
        TMOD=0x01;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;  //50ms
        EA=1;  //开总中断
        ET0=1; //开定时器0
        TR0=1; //开始计时
}


void T0INT() interrupt 1//50ms定时器中断
{
        static  unsigned int  m,s0,fen0,h0,day0;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        m++;//
        if(m>=20)
        {
          s0++;
          s++;//秒变量,需要定义成全局变量
          m=0;
        }
        if(s0>=60)
        {
          fen0++;
          fen++;//分钟变量,需要定义成全局变量         s0=0;
        }
        if(fen0>=60)
        {
          h0++;
          h++;//小时变量,需要定义成全局变量
          fen0=0;
        }
        if(h0>=24)
        {
          day0++;
          day++;//天变量,需要定义成全局变量
          h0=0;
        }
        if(day0>=30)
        {
          yue++;//月变量,需要定义成全局变量
          day0=0;
        }
  }

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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