标题: 学了十多天51单片机,会写时钟程序了,走的不准怎么调啊, [打印本页]

作者: rester    时间: 2015-2-20 23:48
标题: 学了十多天51单片机,会写时钟程序了,走的不准怎么调啊,
程序写了大半天啊,终于搞定了,虽然在 大侠们看来, 实在是小儿科。,但是对于我一个业余爱好者,程序的设计没参照任何人的结构,就能写出来 对于0基础学员来说还是很兴奋的哈,请求 共同爱好单片机的朋友给我指点指点,,



  #include<reg52.h>
  
#define smg P0   //数码管显示 段
sbit LSA=P2^2; //数码管位选
sbit LSB=P2^3;//数码管位选
sbit LSC=P2^4; //数码管位选
   void csh(); //初始化声明
    unsigned int a, b,c,d,e,f,js,j,o;      
  #define ke P1 //键盘接口
unsigned char kee; //存放键盘 键值
    void ys(unsigned int c)  ;//延时声明
    void kep (void);   //键盘声明
    unsigned char kk;  //检测按键是否按下
     void xsss();  //数码管显示声明
unsigned char code sz[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x40,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};//按键1 调 分的个位 按键2调分的十位,按键3调时的个位 按键4调时的十位;
unsigned char u[17];
    void main(void)
   
    {    csh();
   
  while(1){ kep(); xsss();  
         
         
       if(o==10){b++;o=0;}
       if(b==6) {c++;b=0;}
       if(c==10){d++;c=0;}
       if(d==6){e++;d=0;}
       if(e==10){f++;e=0;}
       if(f==2&&e==4){o=0;b=0;c=0;d=o;e=0;f=0;}
       if(kk==1)                                                              
       {  TR0=0;
         switch(kee)
        { case(1):d++;break;   
      case(2):c++;if(c==9){c=0;} break;
      case(3):e++; break;
      case(4):f++;if(f==2){f=0;}break;     
      
      
      
      } }  kk=0;TR0=1;
            
       }
        
   }
  

void csh()        //初始化函数
  {   f=0;e=0;d=0;c=6;b=0;o=0;   
TMOD=0x01;
TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;   

  }      
  
void zd() interrupt  1    //定时ET0的中断函数
{
    TH0=(65536-49972)/256;
    TL0=(65536-49972)%256;

      js++;    if(js==20){o++;js=0;} //如果此条 不放在中断里,有可能因为程序在执行其他程序而超过20,if语句就检测不到js=20了也就不执行此语句;无法为js置0了,js有可能持续增加,
   
}
  void ys(unsigned int c)   
{
    unsigned char a,b;
        for(b=c;b>0;b--)
            for(a=60;a>0;a--);
}

void kep(void)    //键盘函数
{
     char a=0;
      ke=0x0f;
    if(ke!=0x0f){
    ys(30);

     if(ke!=0x0f){   kk=1;
     switch(ke)
     {
       case(0x07):kee=0;break;
    case(0x0b):kee=1;break;
    case(0x0d):kee=2;break;
    case(0x0e):kee=3;break;     
     }
     ke=0xf0;
       switch(ke)
     {      
       case(0x70):kee=kee;break;
    case(0xb0):kee=kee+4;break;
    case(0xd0):kee=kee+8;break;
    case(0xe0):kee=kee+12;break;     
     }
    while((a<50)&&(ke!=0xf0))
   {   ys(50);
   
    a++;
   }
         }
    }  
   
   
   
      
}




void xsss() //数码管 动态显示函数
{  switch(0)  
  {
     
   
   case(0):
     LSA=0;LSB=1;LSC=0; smg=sz[10]; // -
      j=10;      
     while(j--);
    smg=0x00;
   
    LSA=1;LSB=0;LSC=1;smg =sz[10]; // -
      j=10;      
     while(j--);
     smg  =0x00;   
   LSA=0;LSB=0;LSC=0;smg =sz[o]; // 秒
    ys(1);      
     
          smg=0x00;  
     
    LSA=1;LSB=0;LSC=0; smg=sz[b]; //秒的十位
    ys(1);
           smg =0x00;
      
   LSA=1;LSB=1;LSC=0;smg =sz[c];//分的个位
        ys(1);
       smg =0x00;
  LSA=0;LSB=0;LSC=1; smg=sz[d]; // 分的十位
     ys(1);
   smg =0x00;
     LSA=0;LSB=1;LSC=1; smg=sz[e]; // 小时的个位
      ys(1);
   smg=0x00;
      
  LSA=1;LSB=1;LSC=1; smg=sz[f]; // 小时的十位
     ys(1);
    smg =0x00;
         
  }         
      }



作者: heicad    时间: 2015-2-21 00:04
电路图呢
作者: rester    时间: 2015-2-21 00:12
电路图刚才忘记了,现在上传

HC6800-ES V2.0.pdf

759.08 KB, 下载次数: 51, 下载积分: 黑币 -5

电路图


作者: rester    时间: 2015-2-21 00:12
heicad 发表于 2015-2-21 00:04
电路图呢

恩,已经上传了,刚才忘记了
作者: ahshmj    时间: 2015-2-21 12:54
你的晶振是多少呢?
误差了多少呢?
也可以修改下面式子里面的减数。不知道你的式子里面的“49972”是不是仿真时调的?这个数越小走时越慢。


void zd() interrupt  1    //定时ET0的中断函数
{
    TH0=(65536-49972)/256;
    TL0=(65536-49972)%256;
作者: 1420079051    时间: 2015-2-22 21:00
好羡慕啊,我也是0开始的初学者啊,刚看了第1课,正在进行第2课啊
作者: zrb5688    时间: 2015-2-22 23:46
楼主进步好快啊
作者: rester    时间: 2015-2-23 17:02
ahshmj 发表于 2015-2-21 12:54
你的晶振是多少呢?
误差了多少呢?
也可以修改下面式子里面的减数。不知道你的式子里面的“49972”是不 ...

TH0=(65536-49972)/256;
    TL0=(65536-49972)%256; 里面的数 是越小越快啊, 我怎么调 都不行 走 一两个小时 不是 快 几秒 就是慢几秒,我就怕 让他运行久了 就偏离的更多,谢谢
作者: rester    时间: 2015-2-23 17:04
1420079051 发表于 2015-2-22 21:00
好羡慕啊,我也是0开始的初学者啊,刚看了第1课,正在进行第2课啊

共同进步啊,刚开始用学 边学 边写,只要用心 我感觉很快的我们
作者: rester    时间: 2015-2-23 17:06
zrb5688 发表于 2015-2-22 23:46
楼主进步好快啊

放假 不用上班了,有时间啊,
作者: miuifen    时间: 2015-2-25 11:46
用  单片机精灵  算初值  要用12MMHz的才没有误差的
作者: fontex    时间: 2015-2-25 11:55
好羡慕,好妒忌!
作者: 一生何求1989    时间: 2015-3-3 00:36
楼主QQ多少啊 我的:2715860322  交流下啊
作者: wamgweix    时间: 2015-3-6 16:07
用时钟芯片如DS1302 或DS3231 DS3234,1302用外部晶振,精度较差。3231晶振内置,内部温度补偿,精度比较高,但价格也高
作者: lmn2005    时间: 2015-3-6 18:02
这个很好用!

单片机小精灵mcuelf_v1.3.rar

998.07 KB, 下载次数: 15, 下载积分: 黑币 -5


作者: sydaxia    时间: 2015-4-26 18:44
添加一个自动校正程序
作者: 8055    时间: 2015-4-26 21:13
本帖最后由 8055 于 2015-4-26 21:21 编辑

2-3个方法能改变你这个方式的时钟精度
1、定时器改自动重装方式。
2、不使用自动重装时,计算出一个合适的装载值,保证低位能有至少4个0,比如0xe0。
3、运行一段时间(1-7天)算出误差大小,用软件定时处理误差值。

我刚学习那会儿弄的那个时钟,连续用了2年多,好像一年才快不到2分钟,就一个普通的12M晶体,忘记了是30PPM还是100PPM的,反正一热一冷的,一年四季综合起来其实误差也没多大。我用的是软件校正,好像是每3000秒减小定时器几个数(实验几天得出来的差值,我也记不清了)。

作者: qianfz    时间: 2015-4-27 10:39
miuifen 发表于 2015-2-25 11:46
用  单片机精灵  算初值  要用12MMHz的才没有误差的

12M误差才大吧
作者: miuifen    时间: 2015-4-29 13:23
qianfz 发表于 2015-4-27 10:39
12M误差才大吧

为什么  我到知道用通讯 是有误差   延迟  还大   请教  谢谢了




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1