主函数用了一个switch 每隔十秒在8位数码管上 交替显示时钟和日历 但0-9秒(10秒)第五秒正常有时钟跳到日历显示 14秒就又由日历跳回时钟显示 按照正常的是10-19秒(10秒)第十九秒由日历跳回时钟的 调试很多次 不知道问题出哪 请高手帮忙解决啊 谢谢了
#include <reg52.h> #include <intrins.h> sbit SCK=P3^6; sbit SDA=P3^4; sbit RST = P3^5; // DS1302复位 unsigned char l_tmpdate[7]={0,0,9,8,6,5,12};//秒分时日月周年08-05-15 12:00:00 unsigned char l_tmpdisplay[8]={0x40,0x40,0x40,0x40,0x40,0x40,0x40,0}; code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位读写位 code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //共阴数码管 0-9 '-' '熄灭‘表 void delay();//延时子函数,5个空指令 void display(unsigned char *lp,unsigned char lc);//数字的显示函数;lp为指向数组的地址,lc为显示的个数 void Write_Ds1302_byte(unsigned char temp); void Write_Ds1302( unsigned char address,unsigned char dat ); unsigned char Read_Ds1302 ( unsigned char address ); void Read_RTC(void);//read RTC void Set_RTC(void); //set RTC void main(void) { Set_RTC(); while(1){ Read_RTC(); switch (l_tmpdate[0]/10) //设计每个5秒 交替显示 年月日 时分秒 { case 0: case 2: case 4:{l_tmpdisplay[0]=l_tmpdate[2]/16; //数据的转换,因我们采用数码管0~9的显示,将数据分开 l_tmpdisplay[1]=l_tmpdate[2]&0x0f; l_tmpdisplay[2]=10; //加入"-" l_tmpdisplay[3]=l_tmpdate[1]/16; l_tmpdisplay[4]=l_tmpdate[1]&0x0f; l_tmpdisplay[5]=10; l_tmpdisplay[6]=l_tmpdate[0]/16; l_tmpdisplay[7]=l_tmpdate[0]&0x0f;break; } case 1: case 3: case 5:{l_tmpdisplay[0]=l_tmpdate[6]/16; l_tmpdisplay[1]=l_tmpdate[6]&0x0f; l_tmpdisplay[2]=10; l_tmpdisplay[3]=l_tmpdate[4]/16; l_tmpdisplay[4]=l_tmpdate[4]&0x0f; l_tmpdisplay[5]=10; l_tmpdisplay[6]=l_tmpdate[3]/16; l_tmpdisplay[7]=l_tmpdate[3]&0x0f;break; } default: break; } display(l_tmpdisplay,8); } } void display(unsigned char *lp,unsigned char lc)//显示 { unsigned char i; //定义变量 P0=0; //端口2为输出 P2=P2&0xF8; //将P2口的前3位输出0,对应138译门输入脚,全0为第一位数码管 for(i=0;i<lc;i++)//循环显示 { P0=table[lp]; //查表法得到要显示数字的数码段 delay(); //延时 P0=0; //清0端口,准备显示下位 if(i==7) //检测显示完8位否,完成直接退出,不让P0口再加1,否则进位影响到第四位数据 break; P2++; //下一位数码管 } } void delay(void) //延时子函数 { unsigned char i=20; //i的值的大小可以决定数码管的亮暗的程度 while(i) i--; } void Write_Ds1302_Byte(unsigned char temp) { unsigned char i; for (i=0;i<8;i++) //循环8次 写入数据 { SCK=0; SDA=temp&0x01; //每次传输低字节 temp>>=1; //右移一位 SCK=1; } } /****************************************************************************/ void Write_Ds1302( unsigned char address,unsigned char dat ) { RST=0; _nop_(); SCK=0; _nop_(); RST=1; _nop_(); //启动 Write_Ds1302_Byte(address); //发送地址 Write_Ds1302_Byte(dat); //发送数据 RST=0; //恢复 } /****************************************************************************/ unsigned char Read_Ds1302 ( unsigned char address ) { unsigned char i,temp=0x00; RST=0; _nop_(); SCK=0; _nop_(); RST=1; _nop_(); Write_Ds1302_Byte(address); for (i=0;i<8;i++) //循环8次 读取数据 { if(SDA) temp|=0x80; //每次传输低字节 SCK=0; temp>>=1; //右移一位 SCK=1; } RST=0; _nop_(); //以下为DS1302复位的稳定时间 RST=0; SCK=0; _nop_(); SCK=1; _nop_(); SDA=0; _nop_(); SDA=1; _nop_(); return (temp); //返回 } /****************************************************************************/ void Read_RTC(void) //读取 日历 { unsigned char i,*p; p=read_rtc_address; //地址传递 for(i=0;i<7;i++) //分7次读取 秒分时日月周年 { l_tmpdate=Read_Ds1302(*p); p++; } } /***********************************************************************/ void Set_RTC(void) //设定 日历 { unsigned char i,*p,tmp; for(i=0;i<7;i++){ //BCD处理 tmp=l_tmpdate/10; l_tmpdate=l_tmpdate%10; l_tmpdate=l_tmpdate+tmp*16; } Write_Ds1302(0x8E,0X00); p=write_rtc_address; //传地址 for(i=0;i<7;i++) //7次写入 秒分时日月周年 { Write_Ds1302(*p,l_tmpdate); p++; } Write_Ds1302(0x8E,0x80); }
读1302的秒寄存器的十位=1、3、5显示时钟;
读1302的秒寄存器的十位=0、2、4显示日期;
欢迎光临 (http://www.51hei.com/bbs/) | Powered by Discuz! X3.1 |