wskiko 2021-11-09 22:49 采纳率: 100%
浏览 370
已结题

单片机AT89C52定时器中断在lcd1602上实现六十秒倒计时(精确到两位小数)

在keil中编译好代码后,我用proteus仿真。
仿真结果是倒计时的代码我能实现。
但屏幕上的60秒倒计时实际上花了七十多秒。

(三个灯是用定时器中断实现不同闪烁周期,不用管)
(lcd的第二行我打了一串数字,也不用管)
(时间的误差应该主要是以为print()函数调用的延时函数,但我不知道有什么改的方法。)

#include<reg52.h>
sbit RS=P2^0;
sbit RW=P2^1;
sbit E=P2^2;
bit fg_1s=0;
sbit led1=P2^3;
sbit led2=P2^4;
sbit led3=P2^5;
    int num,t;//定义秒数,倒计时个位
    static n=6;//定义倒计时的十位
    static unsigned char time_1s=0;
    void delay()//延时函数
    { int i,j;
        for(i=0;i<1;++i)
        {
            for(j=0;j<1;++j)
            {
                ;
            }
        }
    }
     void lcd_writecom(unsigned char com)//lcd写入指令
    {
        RS=0;
        RW=0;
        E=0;
        P0=com;
        delay();
        E=1;
        delay();
        E=0;
    }
    void lcd_writedata(unsigned char dat)//lcd写入数据
    {
        RS=1;
        RW=0;
        E=0;
        P0=dat;
        delay();
        E=1;
      delay();
        E=0;
    }
    void lcd_init()//lcd初始化
    {
        lcd_writecom(0x38);
        delay();
        lcd_writecom(0x38);//开启显示模式
        lcd_writecom(0x0C);//开显示不显示光标
        lcd_writecom(0x06);//指针自动加一
        lcd_writecom(0x01);//清屏
        lcd_writecom(0x80);//设置数据指针起点
    }
    void print(unsigned char a,unsigned char t)//写入指令,数据
    {
        lcd_writecom(a|0x80);
        lcd_writedata(t);
    }
    void initT0()//定时器T0初始化
    {
        TMOD=0X01;//T0工作方式2
        TH0=(65536-9216)/256;//装入初值
        TL0=(65536-9216)%256;//溢出周期为10ms
        EA=1;//打开总中断
        ET0=1;//打开定时器T0中断
        TR0=1;//T0开始计数
    }
    void main()//主函数运算
    { lcd_init();//lcd初始化
        initT0();//定时器T0初始化
        while(1)//稳定
        {    
        if(fg_1s==1)
                    {
                        fg_1s=0;
                        num++;//统计秒数
              t=1-num%10;//倒计时个位
       if(t<0)//防止负数情况
       {
         t=t+10;
             }
       if(num%10==2)//让十位退位
       {
                 n--;
             }
            print(0x80,n+0x30);//显示倒计时
              print(0x81,t+0x30);
              print(0x40,2+0x30);//显示学号
                print(0x41,0+0x30);
                print(0x42,2+0x30);
                print(0x43,1+0x30);
                print(0x44,2+0x30);
                print(0x45,1+0x30);
                print(0x46,6+0x30);
                print(0x47,7+0x30);
                print(0x48,8+0x30);
                print(0x49,7+0x30);
                 
             
                    }
         
    }
}
            
    
        

    void timer0() interrupt 1
        {static  time_200ms=0;//定义静态变量
         static  time_500ms=0;
         static  time_1000ms=0;
            
            
         TH0=(65536-9216)/256;//重新装入初值
         TL0=(65536-9216)%256;//溢出周期为10ms
            time_1s++;//计时器计数
            time_200ms++;//变量计数加1
          time_500ms++;
          time_1000ms++;
            if(time_200ms==20)//时间达到200ms
         {
             time_200ms=0;
             led1=~led1;
         }
         if(time_500ms==50)//时间达到500ms
         {
             time_500ms=0;
             led2=~led2;
         }
         if(time_1000ms==100)//时间达到1000ms
         {
             time_1000ms=0;
             led3=~led3;
         }
            if(time_1s==100)//1s
            {
                time_1s=0;
                fg_1s=1;
              
        if(num==61)//到达60秒
            {
                
                while(1)
                {
                
        lcd_writecom(0x01);//清屏
                }                    
            }
        }
    }
             

  • 写回答

2条回答 默认 最新

  • 老皮芽子 2021-11-10 08:59
    关注

    timer0 中断程序需要重写,计时逻辑混乱。lcd_writecom 不该在定时器中断中调用,应该放在 main 中。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 11月18日
  • 已采纳回答 11月10日
  • 创建了问题 11月9日

悬赏问题

  • ¥15 请提供一个符合要求的网页链接。
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码