这个程序是在网上找到的,硬件搭建完成后把程序烧录到单片机,电子钟从00:00开始走,但是按调节按钮后电子钟显示01:01,松开后又进入走时状态,不管是单击,双击,多击,或按住不放等待几秒后都是进入走时状态,不能调节时间,请大家帮忙看一下这程序有什么问题,谢谢
//下载时选择片内RC振荡12M
- #include <reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit din=P3^0; //引脚定义
- sbit clk=P3^1;
- sbit sck=P3^2;
- sbit SDA=P3^3;
- sbit SCL=P3^4;
- sbit set=P3^5;
- bit ack; //应答位
- #define DS3231_WriteAddress 0xD0//器件写地址
- #define DS3231_ReadAddress 0xD1//器件读地址
- #define DS3231_SECOND 0x00//秒
- #define DS3231_MINUTE 0x01//分
- #define DS3231_HOUR 0x02//时
- #define DS3231_WEEK 0x03//星期
- #define DS3231_DAY 0x04//日
- #define DS3231_MONTH 0x05//月
- #define DS3231_YEAR 0x06//年
- //#define bcd_hex(bcd) ((((uchar)bcd) & 0xF0) >> 4) * 10 + (((uchar)bcd) & 0x0F) //8421码转16进制
- //uchar bcd_hex(uchar bcd){return((bcd/16*10)+(bcd&0x0f));}
- //#define hex_bcd(hex) (((u8)hex) % 10) + ((((u8)hex) /10) << 4)//16进制转8421码
-
- void delayus(uint us) {while(--us);}
- void Start_I2C(void){SDA=1;delayus(1);SCL=1;delayus(5);SDA=0;delayus(5);SCL=0;delayus(2);} //I2C开始
- void Stop_I2C(void) {SDA=0;delayus(1);SCL=1;delayus(5);SDA=1;delayus(5);} //I2C停止
- void SendByte_595(uchar date); //74hc595发送字节时序
- void SendByte_3231(uchar date); //ds3231发送字节时序
- uchar write_byte_3231(uchar addr,uchar write_date);//指定地址写入字节
- uchar RcvdByte_3231(void); //ds3231接收字节时序
- void Ack_3231(bit a); // 发送应答与否
- uchar read_current(void);
- uchar read_random(uchar random_addr);
- // uchar date[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- code uchar code_led[]={
- 0x40, // 0
- 0x79, // 1
- 0x24, // 2
- 0x30, // 3
- 0x19, // 4
- 0x12, // 5
- 0x02, // 6
- 0x78, // 7
- 0x00, // 8
- 0x10, // 9
- 0x08, // A
- 0x03, // B
- 0x46, // C
- 0x21, // D
- 0x06, // E
- 0x0E // F
- //0x00
- };
- void main()
- {
- uint d=0;//点闪计时
- uchar i;
- uchar miao,fen,shi,ri,yue,nian;
- uchar w[4];
- //uchar n=20,y=10,r=3,s=14,f=16,m=31;//调整时间用
- while(1){
- ////////////////////////////
-
- d=d+1;
- if(d%1000==0)
- {
- if(miao!=read_random(DS3231_SECOND))
- {
- d=0;
- miao =read_random(DS3231_SECOND);
- fen =read_random(DS3231_MINUTE);
- shi =read_random(DS3231_HOUR);
- ri =read_random(DS3231_DAY);
- yue =read_random(DS3231_MONTH);
- nian =read_random(DS3231_YEAR);
-
- w[0]=code_led[shi/16];w[1]=code_led[shi%16];
- w[2]=code_led[fen/16];w[3]=code_led[fen%16];
- // w[0]=code_led[fen/16];w[1]=code_led[fen%16];
- // w[2]=code_led[miao/16];w[3]=code_led[miao%16];
- for (i=0; i<4; i++) SendByte_595(w[i]); sck=0;delayus(5);sck=1;delayus(5);
- }
- }
- if(d==26000)
- {
- w[1]=code_led[shi%16]^0x80;
- w[2]=code_led[fen/16]^0x80;
- // w[0]=code_led[fen/16];w[1]=code_led[fen%16]^0x80;
- // w[2]=code_led[miao/16]^0x80;w[3]=code_led[miao%16];
- for (i=0; i<4; i++) SendByte_595(w[i]); sck=0;delayus(5);sck=1;delayus(5);
- }
- /////////////////////////////////////
-
- while(set==0)
- {
- w[0]=code_led[yue/16];w[1]=code_led[yue%16];
- w[2]=code_led[ri/16]^0x80;w[3]=code_led[ri%16];
- for (i=0; i<4; i++) SendByte_595(w[i]); sck=0;delayus(5);sck=1;delayus(5);
- // write_byte_3231(DS3231_SECOND,m/10*16+m%10);
- // write_byte_3231(DS3231_MINUTE,f/10*16+f%10);
- // write_byte_3231(DS3231_HOUR,s/10*16+s%10);
- // write_byte_3231(DS3231_DAY,r/10*16+r%10);
- // write_byte_3231(DS3231_MONTH,y/10*16+y%10);
- // write_byte_3231(DS3231_YEAR,n/10*16+n%10);
- }
- }
- }
- void SendByte_595(uchar date){uchar i;for(i=0;i<8;i++){clk=0;delayus(2);date<<=1;din=CY;delayus(5);clk=1;delayus(5);}}//595移位输出
- void SendByte_3231(uchar date) //发送一个字节
- {
- uchar i;
- for (i=0;i<8;i++){date<<=1;SDA=CY;delayus(1);SCL=1;delayus(5);SCL=0;}
- delayus(2);SDA=1;delayus(2);SCL=1;delayus(3);//释放SDA 准备接收应答信号
- if(SDA==1)ack=0;else ack=1; //检测应答信号
- SCL=0; delayus(2);
- }
- uchar RcvdByte_3231(void)//读取一个字节的数据
- {
- uchar i;
- uchar date=0;
- SDA=1;
- for(i=0;i<8;i++)
- {
- delayus(1);
- SCL=0;delayus(5); SCL=1;delayus(3);
- date=date<<1;
- if(SDA==1)date+=1; delayus(2);
- }
- SCL=0;
- delayus(2);
- return(date);
- }
- void Ack_3231(bit a){if(a==0)SDA=0;else SDA=1; delayus(3);SCL=1;delayus(5);SCL=0;delayus(2);} //发送应答与否
- // uchar write_byte_3231(uchar addr,uchar write_date)
- // {
- // Start_I2C();
- // SendByte_3231(DS3231_WriteAddress);//呼叫ds3231传送
- // if(ack==0)return 0;
- // SendByte_3231(addr);//送地址
- // if(ack==0)return 0;// 无应答退出
- // SendByte_3231(write_date);//送数据
- // if(ack==0)return 0;// 无应答退出
- // Stop_I2C();
- // delayus(10);
- // return 1;// 发送成功
- // }
- uchar read_current(void)
- {
- uchar read_date;
- Start_I2C();
- SendByte_3231(DS3231_ReadAddress);
- if(ack==0)return 0;// 无应答退出
- read_date=RcvdByte_3231();
- Ack_3231(1);//接收到一个字节数据后非应答
- Stop_I2C();
- return read_date;
- }
- uchar read_random(uchar random_addr)
- {
- Start_I2C();
- SendByte_3231(DS3231_WriteAddress);//呼叫ds3231传送
- if(ack==0)return 0;// 无应答退出
- SendByte_3231(random_addr);
- if(ack==0)return 0;// 无应答退出
- return (read_current());
- }
复制代码
电路图
补充一下, 单片机用的是STC15L104W,我用的是STC15W104,网上查是可以直接代换的。
|