新手求助,用普中51单片机,DS1302制作的时钟,按键key1不灵敏。
#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!
