微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 新手求助,用普中51单片机,DS1302制作的时钟,按键key1不灵敏。

新手求助,用普中51单片机,DS1302制作的时钟,按键key1不灵敏。

时间:10-02 整理:3721RD 点击:
#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x20};
bit flag;
sbit RS=P2^6;
sbit RW=P2^5;
sbit LCDE=P2^7;
sbit DSIO=P3^4;
sbit SCLK=P3^6;
sbit RST=P3^5;
sbit sda=P2^0;
sbit scl=P2^1;
sbit key1=P1^0;
sbit key2=P1^1;

void i2c_delayms()
{
;;
}
void i2c_star()
{
    sda=1;
        i2c_delayms();
        scl=1;
        i2c_delayms();
        sda=0;
        i2c_delayms();
}
void i2c_stop()
{
    sda=0;
        i2c_delayms();
        scl=1;
        i2c_delayms();
        sda=1;
        i2c_delayms();
}
void i2c_respond()
{
    uchar i;
        scl=1;
        i2c_delayms();
        while((sda==1)&&(i<250))
        i++;
        scl=0;
        i2c_delayms();
}
void i2c_init()
{
    sda=1;
        i2c_delayms();
        scl=1;
        i2c_delayms();
}
void i2c_write(uchar date)
{
    uchar i,temp;
        temp=date;
        for(i=0;i<8;i++)
        {
            temp=temp<<1;
                scl=0;
                i2c_delayms();
                sda=CY;
                i2c_delayms();
                scl=1;
                i2c_delayms();
        }
        scl=0;
        i2c_delayms();
        sda=1;
        i2c_delayms();
}
uchar i2c_read()
{
    uchar i,k;
        scl=0;
        i2c_delayms();
        sda=1;
        i2c_delayms();
        for(i=0;i<8;i++)
        {
            scl=1;
                i2c_delayms();
                k=(k<<1)|sda;
                scl=0;
                i2c_delayms();
        }
        return k;
}
void write_add(uchar address,uchar date)
{
        i2c_star();
        i2c_write(0xa0);
        i2c_respond();
        i2c_write(address);
        i2c_respond();
        i2c_write(date);
        i2c_respond();
        i2c_stop();
}
uchar read_add(uchar address)
{
        uchar date;
        i2c_star();
        i2c_write(0xa0);
        i2c_respond();
        i2c_write(address);
        i2c_respond();
        i2c_star();
        i2c_write(0xa1);
        i2c_respond();
        date=i2c_read();
        i2c_stop();
        return date;
}
void delayms(uint xms)
{
   uint i,j;
   for(i=xms;i>0;i--)
       for(j=110;j>0;j--);
}
void write_com(uchar com)
{
           RS=0;
        RW=0;
        P0=com;
        delayms(10);
        LCDE=1;
        delayms(10);
        LCDE=0;
}
void write_data(uchar dat)
{
   RS=1;
   RW=0;
   P0=dat;
   delayms(10);
   LCDE=1;
   delayms(10);
   LCDE=0;
}
void init()
{
   write_com(0x38);
   write_com(0x0c);
   write_com(0x06);
   write_com(0x01);
   write_com(0x01);
   write_com(0x80);
}
void ds1302_write(uchar add,uchar date)
{
    uchar n;
           RST=0;
        _nop_();
        SCLK=0;
        _nop_();
   RST=1;
   _nop_();
   for(n=0;n<8;n++)
   {
       DSIO=add&0x01;
           add>>=1;
           SCLK=1;
           _nop_();
           SCLK=0;
           _nop_();
   }
   for(n=0;n<8;n++)
   {
       DSIO=date&0x01;
           date>>=1;
           SCLK=1;
           _nop_();
           SCLK=0;
           _nop_();
   }
}
uchar ds1302_read(uchar add)
{
    uchar n,date,date1;
        RST=0;
        _nop_();
        SCLK=0;
        _nop_();
        RST=1;
        _nop_();
        for(n=0;n<8;n++)
        {
            DSIO=add&0x01;
                add>>=1;
                SCLK=1;
                _nop_();
                SCLK=0;
                _nop_();
        }
        _nop_();
        for(n=0;n<8;n++)
        {
            date1=DSIO;
                date=(date>>1) | (date1<<7);
                SCLK=1;
                _nop_();
                SCLK=0;
                _nop_();
        }
        RST=0;
        _nop_();
        SCLK=1;
        _nop_();
        DSIO=0;
        _nop_();
        DSIO=1;
        _nop_();
        return date;
}
void ds1302_init()
{
    uchar n;
        ds1302_write(0x8e,0x00);
       
        for(n=0;n<7;n++)
        {       
            TIME[n]=read_add(n);
            ds1302_write(WRITE_RTC_ADDR[n],TIME[n]);
        }
        ds1302_write(0x8e,0x80);
}
void ds1302_readtime()
{
    uchar n;
        for(n=0;n<7;n++)
        {
            TIME[n]=ds1302_read(READ_RTC_ADDR[n]);
                write_add(n,TIME[n]);
                delayms(100);
        }
}
void display1(uchar add,uchar date)
{
           write_com(add);
        if(add!=0x80+13)
        {
            write_data('0'+date/16);
            write_data('0'+(date&0x0f));
        }
        if(add==0x80+13)
        {
            write_data('0'+(date&0x0f));
        }
}

void main()
{        
    uchar s1=0;
    init();
        i2c_init();
        ds1302_init();
        write_com(0x80);
        write_data('2');
        write_data('0');
        write_com(0x80+4);
        write_data('-');
        write_com(0x80+7);
        write_data('-');
        write_com(0x80+0x40+3);
        write_data(':');
        write_com(0x80+0x40+6);
        write_data(':');
       
        while(1)
        {
             
                if(flag==0)
                {
                ds1302_readtime();
                        display1(0x80+0x40+1,TIME[2]);   //时
                        display1(0x80+0x40+4,TIME[1]);   //分
                        display1(0x80+0x40+7,TIME[0]);   //秒
                        display1(0x80+2,TIME[6]);                //年
                        display1(0x80+5,TIME[4]);            //月
                        display1(0x80+8,TIME[3]);             //日
                        display1(0x80+13,TIME[5]);             //星期
                }
               
            if(key1==0)
            {       
                    flag=1;
                    ds1302_write(0x8e,0x00);
                    delayms(100);
                        if(key1==0)
                        {
                        while(!key1);
            ds1302_write(0x8e,0x00);
                       
                s1++;          
                    if(s1==1)
                    {
                        write_com(0x80+0x40+8);
                            write_com(0x0f);
                    }
                    if(s1==2)
                    {
                        write_com(0x80+0x40+5);
                            write_com(0x0f);
                    }
                    if(s1==3)
                     {
                        write_com(0x80+0x40+2);
                            write_com(0x0f);
                    }
                    if(s1==4)
                    {
                        write_com(0x80+13);
                              write_com(0x0f);
                    }
                    if(s1==5)
                    {
                        write_com(0x80+9);
                            write_com(0x0f);
                    }
                    if(s1==6)
                    {
                        write_com(0x80+6);
                            write_com(0x0f);
                    }
                     if(s1==7)
                    {
                        write_com(0x80+3);
                            write_com(0x0f);
                    }
                   if(s1==8)
                    {
                            flag=0;
                        s1=0;
                                ds1302_write(0x8e,0x80);
                            write_com(0x0c);
                                ds1302_init();
                    }
                        }
            }
                if(s1!=0)
                {
                    if(key2==0)
                        {
                            delayms(100);
                                if(s1==1)
                                {
                                    TIME[0]++;
                                        if(TIME[0]%16==10)
                                        {
                                            TIME[0]=TIME[0]+6;
                                        }
                                        if(TIME[0]>90)
                                        {
                                             TIME[0]=0;
                                        }
                                       
                                        display1(0x80+0x40+7,TIME[0]);//秒
                                        write_com(0x80+0x40+8);
                                        write_add(0,TIME[0]);
                                                                                 
                                }
                                if(s1==2)
                                {
                                    TIME[1]++;
                                        if(TIME[1]%16==10)
                                        {
                                            TIME[1]=TIME[1]+6;
                                        }
                                        if(TIME[1]>90)
                                        {
                                             TIME[1]=0;
                                        }
                                       
                                        display1(0x80+0x40+4,TIME[1]);   //分
                                        write_com(0x80+0x40+5);
                                        write_add(1,TIME[1]);       
                                                                 
                                }
                                if(s1==3)
                                {
                                    TIME[2]++;
                                        if(TIME[2]%16==10)
                                        {
                                            TIME[2]=TIME[2]+6;
                                        }
                                        if(TIME[2]>35)
                                        {
                                             TIME[2]=0;
                                        }
                                       
                                        display1(0x80+0x40+1,TIME[2]);   //时
                                        write_com(0x80+0x40+2);
                                        write_add(2,TIME[2]);
                                }
                                if(s1==4)
                                {
                                    TIME[5]++;
                                        if(TIME[5]%16==10)
                                        {
                                            TIME[5]=TIME[5]+6;
                                        }
                                        if(TIME[5]>7)
                                        {
                                             TIME[5]=1;
                                        }
                                       
                                        display1(0x80+13,TIME[5]);             //星期
                                        write_com(0x80+13);
                                        write_add(5,TIME[5]);
                                }
                                if(s1==5)
                                {
                                    TIME[3]++;
                                        if(TIME[3]%16==10)
                                        {
                                            TIME[3]=TIME[3]+6;
                                        }
                                        if(TIME[3]>49)
                                        {
                                             TIME[3]=1;
                                        }
                                       
                                        display1(0x80+8,TIME[3]);             //日
                                        write_com(0x80+9);
                                        write_add(3,TIME[3]);
                                }
                                if(s1==6)
                                {
                                    TIME[4]++;
                                        if(TIME[4]%16==10)
                                        {
                                            TIME[4]=TIME[4]+6;
                                        }
                                        if(TIME[4]>18)
                                        {
                                             TIME[4]=1;
                                        }
                                       
                                        display1(0x80+5,TIME[4]);            //月
                                        write_com(0x80+6);
                                        write_add(4,TIME[4]);
                                }
                                if(s1==7)
                                {
                                    TIME[6]++;
                                        if(TIME[6]%16==10)
                                        {
                                            TIME[6]=TIME[6]+6;
                                        }
                                        if(TIME[6]>150)
                                        {
                                             TIME[6]=0;
                                        }
                                       
                                        display1(0x80+2,TIME[6]);                //年
                                        write_com(0x80+3);
                                        write_add(6,TIME[6]);
                                }
                        }
                }
        }
}


你的void ds1302_readtime()
{
    uchar n;
        for(n=0;n<7;n++)
        {
            TIME[n]=ds1302_read(READ_RTC_ADDR[n]);
                write_add(n,TIME[n]);
                delayms(100);
        }
}
这些地方的delay等待的时间太久了。你的按键按下的时候还没有执行到 if(key1==0)这句话,所以你要长按才能响应。巧了的话那些delay正好执行完,可以立即响应 if(key1==0)这句话。总之就是有时灵有时不灵吧。解决方法就是,尽量不要使用那些占用CPU资源的语句,可以考虑使用定时器。论坛里面你可以参考一下吴坚鸿的代码风格,他有教怎么使用定时器。

学习学习学习学习学习

在while(!keyi1)后面加个延时就行了,大概10ms

不行啊,大神。还是老样子----需要长按才可以进入功能选项,进去之后就正常了

如果硬件没问题的话,那可能是程序在其他地方占用太多时间了,导致按下按键的时候没有执行按键判断程序,CPU还在执行其他程序。

代码在写的时候,类似
void delayms(uint xms)
{
   uint i,j;
   for(i=xms;i>0;i--)
       for(j=110;j>0;j--);
}
这种的代码尽量少用,太占用CPU 的时间了,执行的时候相当于CPU是停在这里了,其他地方都执行不到。完全可以借助定时器来释放CPU的速度,让单片机飞速的跑起来。

好强大啊 那么长的程序编码 想了多久啊

问题解决,感谢大神

分为好几个模块,把每个模块分别加进去就行了

同学,这个程序是参照谁的视频的,求!然后可以加我创的普中单片机群,一起交流, 493434578!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top