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

单片机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 C#读写EXCEL文件,不同编译
  • ¥15 如何提取csv文件中需要的列,将其整合为一篇完整文档,并进行jieba分词(语言-python)
  • ¥15 MapReduce结果输出到HBase,一直连接不上MySQL
  • ¥15 扩散模型sd.webui使用时报错“Nonetype”
  • ¥15 stm32流水灯+呼吸灯+外部中断按键
  • ¥15 将二维数组,按照假设的规定,如0/1/0 == "4",把对应列位置写成一个字符并打印输出该字符
  • ¥15 NX MCD仿真与博途通讯不了啥情况
  • ¥15 win11家庭中文版安装docker遇到Hyper-V启用失败解决办法整理
  • ¥15 gradio的web端页面格式不对的问题
  • ¥15 求大家看看Nonce如何配置