找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3749|回复: 7
收起左侧

关于单片机定时器结合1602LCD显示时钟问题

[复制链接]
ID:356940 发表于 2018-7-27 07:51 | 显示全部楼层 |阅读模式
5黑币
我想在1602LCD液晶上第一行显示日期,第二行显示时间,我定时器设置为50ms中断一次,但是当我在中断中写入if(i==20)i清零,秒自增时不是一秒加一次,而是差不多两秒加一次,这是怎么回事?代码如下:

  1. #include<reg52.h>
  2. uchar hours=1,mins=3,ss=0,hourg=9,ming=6,sg=0;   //最后一个字母带s表示十位,g表示个位


  3. void delay1ms(void)   // 1ms
  4. {
  5.     unsigned char a,b,c;
  6.     for(c=1;c>0;c--)
  7.         for(b=142;b>0;b--)
  8.             for(a=2;a>0;a--);
  9. }
  10. void delay5ms(void)   // 5ms
  11. {
  12.     unsigned char a,b;
  13.     for(b=19;b>0;b--)
  14.         for(a=130;a>0;a--);
  15. }
  16. void write_cmd(uchar cmd)
  17. {
  18.   E=0;
  19.   RS=0;                                                                 //RS=0为写命令
  20.   RW=0;                                                                 //当要对1602写时RW=0,表示允许写入
  21.   P0=cmd;
  22.   delay1ms();
  23.   E=1;
  24.   delay5ms();
  25.   E=0;

  26. }

  27. void write_dat(uchar dat)
  28. {
  29.   E=0;
  30.   RS=1;                                                                //RS=1为写数据
  31.   RW=0;                                                                //当要对1602写时RW=0,表示允许写入
  32.   P0=dat;
  33.   delay1ms();
  34.   E=1;
  35.   delay5ms();
  36.   E=0;

  37. }

  38. void init()
  39. {                                                   //(STA7~STA0)(D7~D0)STA7为读写操作使能 1为禁止 2为允许
  40.   E=0;                                           //使能先关闭        为后面使能高脉冲做铺垫                                                   
  41.   write_cmd(0x38);                   //送入 0011 1000   设置16X2显示
  42.   write_cmd(0x0c);                   //光标显示设置 0000 1DCB
  43.                                                    //D=1开显示 C=1显示光标 B=1光标闪烁
  44.   write_cmd(0x06);                   //光标设置     0000 01NS
  45.                                                    //N=1 读R或写W一个字符后地址指针加1,光标自加一;反之N=0 减一
  46.   write_cmd(0x01);                   //01表示显示清屏:数据指针清零 02表示显示回车




  47. }



  48. uchar hours=1,mins=3,ss=0,hourg=9,ming=6,sg=0;

  49. void Time0_init()
  50. {
  51.   TMOD=0x01;
  52.   TH0=(65536-50000)/256;
  53.   TL0=(65536-50000)%256;
  54.   TR0=1;
  55.   EA=1;
  56.   ET0=1;
  57. }

  58. void timer()
  59. {
  60.   if(sg==10)
  61.   {
  62.     sg=0;
  63.         ss++;
  64.         if(ss==6)
  65.         {
  66.           ss=0;
  67.           ming++;
  68.           if(ming==10)
  69.           {
  70.             ming=0;
  71.                 mins++;
  72.                 if(mins==6)
  73.                 {
  74.                  mins=0;
  75.                  hourg++;
  76.                    if(hours==2&&hourg==4)
  77.                    {
  78.                    hours=0;
  79.                    hourg=0;
  80.                    }
  81.                  if(hourg==10)
  82.                  {
  83.                    hourg=0;
  84.                    hours++;
  85.                   

  86.                  }
  87.                 }
  88.           }
  89.         }

  90.   }
  91. }
  92. void main()
  93. {
  94.             
  95.     Time0_init();
  96.         init();
  97.         
  98.         while(1);
  99. }

  100. void Time0() interrupt 1
  101. {         

  102.      uchar i;
  103.          uchar a[]={'2','0','1','8','/','0','7','/','2','6'};
  104.            TH0=(65536-50000)/256;
  105.      TL0=(65536-50000)%256;
  106.          i++;
  107.          if(i==5)
  108.          {
  109.           i=0;
  110.           sg++;
  111.          }
  112.          
  113.             write_cmd(0x80+3);
  114.                 write_dat(a[0]);
  115.                 write_cmd(0x80+4);
  116.                 write_dat(a[1]);
  117.                 write_cmd(0x80+5);
  118.                 write_dat(a[2]);
  119.                 write_cmd(0x80+6);
  120.                 write_dat(a[3]);
  121.                 write_cmd(0x80+7);
  122.                 write_dat(a[4]);
  123.                 write_cmd(0x80+8);
  124.                 write_dat(a[5]);
  125.                 write_cmd(0x80+9);
  126.                 write_dat(a[6]);
  127.                 write_cmd(0x80+10);
  128.                 write_dat(a[7]);
  129.                 write_cmd(0x80+11);
  130.                 write_dat(a[8]);
  131.                 write_cmd(0x80+12);
  132.                 write_dat(a[9]);
  133.                   
  134.                
  135.          
  136.         
  137.          
  138.            
  139.         
  140.         write_cmd(0x80+0x40+4);
  141.         write_dat(0x30+hours);
  142.         write_cmd(0x80+0x40+5);
  143.         write_dat(0x30+hourg);
  144.         write_cmd(0x80+0x40+6);
  145.         write_dat(':');
  146.         write_cmd(0x80+0x40+7);
  147.         write_dat(0x30+mins);
  148.         write_cmd(0x80+0x40+8);
  149.         write_dat(0x30+ming);
  150.         write_cmd(0x80+0x40+9);
  151.         write_dat(':');
  152.         write_cmd(0x80+0x40+10);
  153.         write_dat(0x30+ss);
  154.         write_cmd(0x80+0x40+11);
  155.         write_dat(0x30+sg);
  156.         timer();

  157. }
复制代码


回复

使用道具 举报

ID:7485 发表于 2018-7-27 10:03 | 显示全部楼层
”uchar i;”位置不对吧?
回复

使用道具 举报

ID:319344 发表于 2018-7-27 10:09 | 显示全部楼层
你这,你看看你发的程序,当i==5时你就给清0了,和你描述的不相符,这让人怎么回答
回复

使用道具 举报

ID:356940 发表于 2018-7-27 11:39 | 显示全部楼层
wenzedong 发表于 2018-7-27 10:09
你这,你看看你发的程序,当i==5时你就给清0了,和你描述的不相符,这让人怎么回答

i=20确实是差不多2-3s秒才+1,我改成i=5看上去就像1s秒+1
回复

使用道具 举报

ID:356940 发表于 2018-7-27 11:42 | 显示全部楼层
ahshmj 发表于 2018-7-27 10:03
”uchar i;”位置不对吧?

不好意思,我的程序分成三块的,第一块主程序,第二块初始化程序,第三块头文件,复制粘贴的时候有点差错,你就当uchar i;放在头文件的下面靠前的位置吧,我编译是没错的,是我复制代码的时候没注意,请谅解
回复

使用道具 举报

ID:356940 发表于 2018-7-27 11:51 | 显示全部楼层
我重新发一遍吧
//第一个(.c)文件 主函数
#include<reg52.h>
#include<lcd1602.h>

uchar hours=1,mins=3,ss=0,hourg=9,ming=6,sg=0;

void Time0_init()
{
  TMOD=0x01;
  TH0=(65536-50000)/256;
  TL0=(65536-50000)%256;
  TR0=1;
  EA=1;
  ET0=1;
}

void timer()
{
  if(sg==10)
  {
    sg=0;
        ss++;
        if(ss==6)
        {
          ss=0;
          ming++;
          if(ming==10)
          {
            ming=0;
                mins++;
                if(mins==6)
                {
                 mins=0;
                 hourg++;
                   if(hours==2&&hourg==4)
                   {
                   hours=0;
                   hourg=0;
                   }
                 if(hourg==10)
                 {
                   hourg=0;
                   hours++;
                  

                 }
                }
          }
        }

  }
}
void main()
{
           
    Time0_init();
        init();
       
        while(1);
}

void Time0() interrupt 1
{         

     uchar i;
         uchar a[]={'2','0','1','8','/','0','7','/','2','6'};
           TH0=(65536-50000)/256;
     TL0=(65536-50000)%256;
         i++;
         if(i==5)
         {
          i=0;
          sg++;
         }
         
            write_cmd(0x80+3);
                write_dat(a[0]);
                write_cmd(0x80+4);
                write_dat(a[1]);
                write_cmd(0x80+5);
                write_dat(a[2]);
                write_cmd(0x80+6);
                write_dat(a[3]);
                write_cmd(0x80+7);
                write_dat(a[4]);
                write_cmd(0x80+8);
                write_dat(a[5]);
                write_cmd(0x80+9);
                write_dat(a[6]);
                write_cmd(0x80+10);
                write_dat(a[7]);
                write_cmd(0x80+11);
                write_dat(a[8]);
                write_cmd(0x80+12);
                write_dat(a[9]);
                  
               
         
       
          
          
       
        write_cmd(0x80+0x40+4);
        write_dat(0x30+hours);
        write_cmd(0x80+0x40+5);
        write_dat(0x30+hourg);
        write_cmd(0x80+0x40+6);
        write_dat(':');
        write_cmd(0x80+0x40+7);
        write_dat(0x30+mins);
        write_cmd(0x80+0x40+8);
        write_dat(0x30+ming);
        write_cmd(0x80+0x40+9);
        write_dat(':');
        write_cmd(0x80+0x40+10);
        write_dat(0x30+ss);
        write_cmd(0x80+0x40+11);
        write_dat(0x30+sg);
        timer();

}
//第二个(.c)文件 用来初始化1602
#include<lcd1602.h>

void delay1ms(void)   // 1ms
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=142;b>0;b--)
            for(a=2;a>0;a--);
}
void delay5ms(void)   // 5ms
{
    unsigned char a,b;
    for(b=19;b>0;b--)
        for(a=130;a>0;a--);
}
void write_cmd(uchar cmd)
{
  E=0;
  RS=0;                                                                 //RS=0为写命令
  RW=0;                                                                 //当要对1602写时RW=0,表示允许写入
  P0=cmd;
  delay1ms();
  E=1;
  delay5ms();
  E=0;

}

void write_dat(uchar dat)
{
  E=0;
  RS=1;                                                                //RS=1为写数据
  RW=0;                                                                //当要对1602写时RW=0,表示允许写入
  P0=dat;
  delay1ms();
  E=1;
  delay5ms();
  E=0;

}

void init()
{                                                   //(STA7~STA0)(D7~D0)STA7为读写操作使能 1为禁止 2为允许
  E=0;                                           //使能先关闭        为后面使能高脉冲做铺垫                                                  
  write_cmd(0x38);                   //送入 0011 1000   设置16X2显示
  write_cmd(0x0c);                   //光标显示设置 0000 1DCB
                                                   //D=1开显示 C=1显示光标 B=1光标闪烁
  write_cmd(0x06);                   //光标设置     0000 01NS
                                                   //N=1 读R或写W一个字符后地址指针加1,光标自加一;反之N=0 减一
  write_cmd(0x01);                   //01表示显示清屏:数据指针清零 02表示显示回车

  

  
}
//第三个为(.h)头文件用来调用
#ifndef _lcd1602_H_
#define _lcd1602_H_


#ifndef uchar
#define uchar unsigned char
#endif



#ifndef uint
#define uint unsigned int
#endif
#include<reg52.h>
sbit RW=P2^5;
sbit RS=P2^6;
sbit E=P2^7;
void delay1ms(void);
void delay5ms(void);
void init();
void write_cmd(uchar cmd);
void write_dat(uchar dat);





#endif


//总共是三个文件,第一个是主函数,第二个初始化函数,第三个用来调用第二个的初始化函数的头文件,麻烦帮我看看问题出在哪了?谢谢!
回复

使用道具 举报

ID:7485 发表于 2018-7-27 14:15 | 显示全部楼层
我说的是“i”应该是全局变量。否则假设第一次中断时,i==2,由于不是全局变量,退出本函数,就释放了,第二次进入中断函数时,不一定是2,可能是其他值。
回复

使用道具 举报

ID:356940 发表于 2018-7-27 16:15 | 显示全部楼层
#include<reg52.h>
#include<lcd1602.h>

uchar hours=1,mins=3,ss=0,hourg=9,ming=6,sg=0;
uchar time;
void Time0_init()
{
  TMOD=0x01;
  TH0=(65536-50000)/256;
  TL0=(65536-50000)%256;
  TR0=1;
  EA=1;
  ET0=1;
}

void timer()
{
  if(sg==10)
  {
    sg=0;
        ss++;
        if(ss==6)
        {
          ss=0;
          ming++;
          if(ming==10)
          {
            ming=0;
                mins++;
                if(mins==6)
                {
                 mins=0;
                 hourg++;
                   if(hours==2&&hourg==4)
                   {
                   hours=0;
                   hourg=0;
                   }
                 if(hourg==10)
                 {
                   hourg=0;
                   hours++;
                  

                 }
                }
          }
        }

  }
}
void main()
{
    uchar a[]={'2','0','1','8','/','0','7','/','2','6'};       
    Time0_init();
        init();
        while(1)
        {
        write_cmd(0x80+3);
                write_dat(a[0]);
                write_cmd(0x80+4);
                write_dat(a[1]);
                write_cmd(0x80+5);
                write_dat(a[2]);
                write_cmd(0x80+6);
                write_dat(a[3]);
                write_cmd(0x80+7);
                write_dat(a[4]);
                write_cmd(0x80+8);
                write_dat(a[5]);
                write_cmd(0x80+9);
                write_dat(a[6]);
                write_cmd(0x80+10);
                write_dat(a[7]);
                write_cmd(0x80+11);
                write_dat(a[8]);
                write_cmd(0x80+12);
                write_dat(a[9]);
                  
               
         
       
          
          
       
        write_cmd(0x80+0x40+4);
        write_dat(0x30+hours);
        write_cmd(0x80+0x40+5);
        write_dat(0x30+hourg);
        write_cmd(0x80+0x40+6);
        write_dat(':');
        write_cmd(0x80+0x40+7);
        write_dat(0x30+mins);
        write_cmd(0x80+0x40+8);
        write_dat(0x30+ming);
        write_cmd(0x80+0x40+9);
        write_dat(':');
        write_cmd(0x80+0x40+10);
        write_dat(0x30+ss);
        write_cmd(0x80+0x40+11);
        write_dat(0x30+sg);
        }
}

void Time0() interrupt 1
{         

     
         
           TH0=(65536-50000)/256;
     TL0=(65536-50000)%256;
         time++;
         if(time==20)
         {
          time=0;
          sg++;
         }
         timer();
            
       

}

我自己已经解决了,我把中断中的写地址和写数据函数都提到主函数里,然后一个while(1)加个大括号居然神奇的1s秒+1,谢谢~
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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