|
很久没发帖了,那么来一贴,这个项目历时3个半月,因为刚开始也就做着玩。先上图。
- #include <reg52.h>
- #include <intrins.h>
- #include<string.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- P4SW=0xff;
- uchar sec, min, hour, day, month,counter,xingqi,AL1SEC,AL1MIN,AL1HOUR,AL1DAY,AL2MIN,AL2HOUR,AL2DAY,AMZT;
- uchar EDA=7;
- uint year;
- bit ack;
- uint cnt = 0;
- uchar i = 0;
- uchar j = 10;
- sbit leden1 = P0^1;
- sbit leden2 = P0^3;
- sbit leden3 = P0^7;
- sbit leden4 = P2^7;
- sbit leden5 = P0^6;
- sbit led1 = P0^0;
- sbit led2 = P0^2;
- sbit led3 = P0^4;
- sbit led4 = P4^4;
- sbit led5 = P2^6;
- sbit led6 = P2^2;
- sbit led7 = P2^0;
-
- sbit SDA=P2^4; //模拟I2C数据传送位SDA
- sbit SCL=P2^5; //模拟I2C时钟控制位SCL
- #define ADDRTW 0xD0 //器件写地址
- #define ADDRTD 0xD1 //器件读地址
- #define DS3231_SEC 0x00 //秒
- #define DS3231_MIN 0x01 //分
- #define DS3231_HOUR 0x02 //时
- #define DS3231_DAY 0x03 //星期
- #define DS3231_DATE 0x04 //日
- #define DS3231_MONTH 0x05 //月
- #define DS3231_YEAR 0x06 //年
- //闹铃1
- #define DS3231_Al1SEC 0x07 //秒
- #define DS3231_AL1MIN 0x08 //分
- #define DS3231_AL1HOUR 0x09 //时
- #define DS3231_AL1DAY 0x0A //星期/日
- //闹铃2
- #define DS3231_AL2MIN 0x0b //分
- #define DS3231_AL2HOUR 0x0c //时
- #define DS3231_AL2DAY 0x0d //星期/日
- #define DS3231_CONTROL 0x0e //控制寄存器
- #define DS3231_STATUS 0x0f //状态寄存器
- bit ack;
- void ledyinshe( ulong j )
- { led1=1;led2=1;led3=1;led4=1;led5=1;led6=1;led7=1;
-
- switch(j)
- {
- case 0: led1=0;led2=0;led3=0;led4=1;led5=0;led6=0;led7=0; break;
- case 1: led1=1;led2=0;led3=1;led4=1;led5=0;led6=1;led7=1; break;
- case 2: led1=0;led2=1;led3=0;led4=0;led5=0;led6=1;led7=0; break;
- case 3: led1=0;led2=0;led3=1;led4=0;led5=0;led6=1;led7=0; break;
- case 4: led1=1;led2=0;led3=1;led4=0;led5=0;led6=0;led7=1; break;
- case 5: led1=0;led2=0;led3=1;led4=0;led5=1;led6=0;led7=0; break;
- case 6: led1=0;led2=0;led3=0;led4=0;led5=1;led6=0;led7=0; break;
- case 7: led1=1;led2=0;led3=1;led4=1;led5=0;led6=0;led7=0; break;
- case 8: led1=0;led2=0;led3=0;led4=0;led5=0;led6=0;led7=0; break;
- case 9: led1=0;led2=0;led3=1;led4=0;led5=0;led6=0;led7=0; break;
- case 10:led1=1;led2=1;led3=1;led4=1;led5=1;led6=1;led7=0; break;
- case 11:led1=1;led2=1;led3=1;led4=0;led5=1;led6=1;led7=1; break;
- case 12:led1=0;led2=1;led3=1;led4=1;led5=1;led6=1;led7=1; break;
- case 13:led1=1;led2=1;led3=1;led4=1;led5=1;led6=1;led7=1; break;
- default:break;
- }
- }
- void Delay100us() [url=]//@11.0592MHz[/url]
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- i = 2;
- j = 15;
- do
- {
- while (--j);
- } while (--i);
- }
- void delay1ms(uchar j)
- {
- while(j!=0)
- {uchar i;
- for(i=124;i>0;i--); //延时124*8+10=1002us
- j--;
- }
- }
- void delay1(unsigned char i)
- {
- for(i;i>0;i--);
- }
- uchar BCD2HEX(uchar val) //BCD转换为Byte
- { uchar i;
- i= val&0x0f;
- val >>= 4;
- val &= 0x0f;
- val *= 10;
- i+= val;
- return i;
- }
- uchar BCD2HEX2(uchar val) //BCD转换为Byte
- { uchar i;
- i= val&0x0f;
- val >>= 4;
- val &= 0x07;
- val *= 10;
- i+= val;
- return i;
- }
- uchar BCD2HEXAM(uchar val) //BCD转换为Byte
- { uchar i;
- i= val&0x03;
- return i;
- }
- uchar HEX2BCD(uchar val)//B码转换为BCD码
- {
- uchar i,j,k;
- i=val/10;
- j=val%10;
- k=j+(i<<4);
- return k;
- }
- uchar HEX2BCDAM(uchar val)//B码转换为BCD码
- {
- uchar i,j,k;
- i=val/10;
- j=val%10;
- k=j+(i<<4);
- k|=0x80;
- return k;
- }
- void Start()
- {
- SDA=1; //发送起始条件的数据信号
- delay1(1);
- SCL=1;
- delay1(5); //起始条件建立时间大于4.7us,延时
- SDA=0; //发送起始信号
- delay1(5); // 起始条件锁定时间大于4μs
- SCL=0; //钳住I2C总线,准备发送或接收数据
- delay1(2);
- }
- void Stop()
- {
- SDA=0; //发送结束条件的数据信号
- delay1(1); //发送结束条件的时钟信号
- SCL=1; //结束条件建立时间大于4us
- delay1(5);
- SDA=1; //发送I2C总线结束信号
- delay1(4);
- }
- /********************************************************/
- /*******************************************************************
- 字节数据发送函数
- 函数原型: void SendByte(uchar Dat);
- 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
- 此状态位进行操作.(不应答或非应答都使ack=0)
- ack=1 发送数据正常,
- ack=0 被控器无应答或损坏。
- ********************************************************************/
- void SendByte(uchar Dat)
- {
- uchar BitCnt;
- for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位
- {
- if((Dat<<BitCnt)&0x80)
- SDA=1; //判断发送位
- else
- SDA=0;
- delay1(1);
- SCL=1; //置时钟线为高,通知被控器开始接收数据位
- delay1(5); //保证时钟高电平周期大于4μs
- SCL=0;
- }
- delay1(2);
- SDA=1; //8位发送完后释放数据线,准备接收应答位
- delay1(2);
- SCL=1;
- delay1(3);
- if(SDA==1)
- ack=0;
- else
- ack=1; //判断是否接收到应答信号
- SCL=0;
- delay1(2);
- }
- uchar RcvByte() //功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数应答从机。
- {
- uchar retc;
- uchar BitCnt;
- retc=0;
- SDA=1; //置数据线为输入方式
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- delay1(1);
- SCL=0; //置时钟线为低,准备接收数据位
- delay1(5); //时钟低电平周期大于4.7μs
- SCL=1; //置时钟线为高使数据线上数据有效
- delay1(3);
- retc=retc<<1;
- if(SDA==1)
- retc=retc+1; //读数据位,接收的数据位放入retc中
- delay1(2);
- }
- SCL=0;
- delay1(2);
- return(retc);
- }
- void I2CACK(bit a) // 功能: 主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
- {
- if(a==0)
- SDA=0; //在此发出应答或非应答信号
- else
- SDA=1;
- delay1(3);
- SCL=1;
- delay1(5); //时钟低电平周期大于4μs
- SCL=0; //清时钟线,钳住I2C总线以便继续接收
- delay1(2);
- }
- uchar I2CRead() /************从DS3231当前地址读一个字节************/
- {
- uchar read_data;
- Start();
- SendByte(ADDRTD);
- if(ack==0)
- {
- return(0);
- }
- read_data = RcvByte();
- I2CACK(1);
- Stop();
- return read_data;
- }
- uchar I2CReadAdd(uchar addr) /************从DS3231指定地址读一个字节************/
- {
- Start();
- SendByte(ADDRTW);
- if(ack==0)
- {
- return(0);
- }
- SendByte(addr);
- if(ack==0)
- {
- return(0);
- }
- return(I2CRead());
- }
- void Readtime() /*********************读取时间**********************/
- {
- uchar temp;
- temp=I2CReadAdd(DS3231_SEC);//秒
- sec=BCD2HEX(temp);
- temp=I2CReadAdd(DS3231_MIN);//分
- min=BCD2HEX(temp);
- temp=I2CReadAdd(DS3231_HOUR); //时
- hour=BCD2HEX(temp);
- temp=I2CReadAdd(DS3231_DATE); //日
- day=BCD2HEX(temp);
- temp=I2CReadAdd(DS3231_MONTH); //月
- month=BCD2HEX(temp);
- temp=I2CReadAdd(DS3231_YEAR); //年
- year=BCD2HEX(temp);
- year+=2000;
- temp=I2CReadAdd(DS3231_DAY); //星期
- xingqi = BCD2HEX(temp);
- temp=I2CReadAdd(DS3231_AL1MIN ); //星期
- AL1MIN = BCD2HEX2(temp);
- temp=I2CReadAdd(DS3231_AL1HOUR); //星期
- AL1HOUR= BCD2HEX2(temp);
- temp=I2CReadAdd(DS3231_AL2MIN ); //星期
- AL2MIN = BCD2HEX2(temp);
- temp=I2CReadAdd(DS3231_AL2HOUR); //星期
- AL2HOUR= BCD2HEX2(temp);
- temp=I2CReadAdd(DS3231_STATUS ); //星期
- AMZT= BCD2HEXAM(temp);
-
- }
- void InitDS3231() //ds3231初始化
- {SCL=1;
- delay1(5);
- SDA=1;
- delay1(5);
- }
- /*
- void TimeDisplay(uchar Dhour,ucharDmin,uchar Dsec) //时分秒数组赋值
- {
- b[0]=numbr[Dhour / 10]; // 时十位
- b[1]=numbr[Dhour % 10]; // 时个位
- b[4]=numbr[Dmin / 10]; // 分十位
- b[5]=numbr[Dmin % 10]; // 分个位
- b[8]=numbr[Dsec / 10]; // 秒十位
- b[9]=numbr[Dsec % 10]; // 秒个位
-
- }
- */
- /*
- void DateDisplay(uchar Dyear,ucharDmonth,uchar Dday) //年月天数组赋值
- {
-
- a[2]=numbr[Dyear / 10]; // 年十位
- a[3]=numbr[Dyear % 10]; // 年个位
- a[6]=numbr[Dmonth / 10]; // 月十位
- a[7]=numbr[Dmonth % 10]; // 月个位
- a[10]=numbr[Dday / 10]; // 天十位
- a[11]=numbr[Dday % 10]; // 天个位
-
- }
- */
- void Start_I2C()
- {
- SDA=1; //发送起始条件的数据信号
- delay1(1);
- SCL=1;
- delay1(5); //起始条件建立时间大于4.7us,延时
- SDA=0; //发送起始信号
- delay1(5); // 起始条件锁定时间大于4μs
- SCL=0; //钳住I2C总线,准备发送或接收数据
- delay1(2);
- }
- void Stop_I2C()
- {
- SDA=0; //发送结束条件的数据信号
- delay1(1); //发送结束条件的时钟信号
- SCL=1; //结束条件建立时间大于4us
- delay1(5);
- SDA=1; //发送I2C总线结束信号
- delay1(4);
- }
- uchar write_byte(uchar addr, uchar write_data)
- {
- Start_I2C();
- SendByte(ADDRTW); //////*******************************************************************///////////
- if (ack == 0)
- return 0;
- SendByte(addr);
- if (ack == 0)
- return 0;
- SendByte(write_data);
- if (ack == 0)
- return 0;
- Stop_I2C();
- delay1ms(10);
- return 1;
- }
- void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec,uchar xq,uchar AL1DAY,uchar A1HOUR,uchar A1MIN,uchar AL1SEC,uchar AL2DAY,uchar A2HOUR,uchar AL2MIN)
- { uchar temp=0;
- temp=HEX2BCD(yea);
- write_byte(DS3231_YEAR,temp); //修改年
- temp=HEX2BCD(mon);
- write_byte(DS3231_MONTH,temp); //修改月
- temp=HEX2BCD(da); /////////////////////
- write_byte(DS3231_DATE,temp); //修改日
- temp=HEX2BCD(hou);
- write_byte(DS3231_HOUR,temp); //修改时
- temp=HEX2BCD(min);
- write_byte(DS3231_MIN,temp); //修改分
- temp=HEX2BCD(sec);
- write_byte(DS3231_SEC,temp); //修改秒
-
- temp=HEX2BCD(xq);
- write_byte(DS3231_DAY,temp); //修改星期
-
- temp=HEX2BCD(AL1SEC);
- write_byte(DS3231_Al1SEC,temp); //修改星期
- temp=HEX2BCD(A1MIN);
- write_byte(DS3231_AL1MIN,temp); //修改星期
- temp=HEX2BCD(A1HOUR);
- write_byte(DS3231_AL1HOUR,temp); //修改星期
- temp=HEX2BCDAM(AL1DAY);
- write_byte(DS3231_AL1DAY ,temp); //修改星期
-
- temp=HEX2BCD(AL2MIN);
- write_byte(DS3231_AL2MIN,temp); //修改星期
- temp=HEX2BCD(A2HOUR);
- write_byte(DS3231_AL2HOUR,temp); //修改星期
- temp=HEX2BCDAM(AL2DAY);
- write_byte(DS3231_AL2DAY,temp); //修改星期
-
-
- }
- unsigned char str[17] ;
- void main()
- {
- TMOD = 0x01;
- TH0 = 0xFC;
- TL0 = 0x67;
- TR0 = 1;
- EA = 1;
- ET0 = 1;
- InitDS3231();
-
- ModifyTime(17,2,25,14,43,0,6,7,13,19,30,7,13,19); //年月白时分秒星期
- delay1ms(100);
- Readtime();
-
- EDA=HEX2BCD(7);
- write_byte(DS3231_CONTROL ,EDA);
- EDA=HEX2BCD(8);
- write_byte(DS3231_STATUS ,EDA);
-
- delay1ms(100);
- while(1)
- {
-
- Readtime();
- if(cnt >= 1000)
- {
- cnt = 0;
- if(j<=11)j++;else j=10;
-
-
- }
-
-
-
- }
- }
- void jianduan1()
- {
- if(leden1==1)
- {
- leden1=0;
- Delay100us();Delay100us();Delay100us();Delay100us();
- Delay100us(); Delay100us();Delay100us();Delay100us();
- Delay100us(); Delay100us();Delay100us();Delay100us();
- }
- else
- {
- leden1=1;
- }
- }
- void jianduan2()
- {
- if(leden2==1)
- {
- leden2=0;
- Delay100us(); Delay100us();Delay100us();Delay100us();
- Delay100us(); Delay100us();Delay100us();Delay100us();
- Delay100us(); Delay100us();Delay100us();Delay100us();
- }
- else
- {
- leden2=1;
- }
- }
- void InterruptTimer0() interrupt 1
- {
- TH0 = 0xFC;
- TL0 = 0x67;
- cnt++;
-
- led1=1;led2=1;led3=1;led4=1;led5=1;led6=1;led7=1;
- switch(i)
- {
- case 0:jianduan1(); leden2=0; leden3=0;leden4=0;leden5=0;i++; ledyinshe(min%10 );break;
- case 1: leden1=0;jianduan2(); leden3=0;leden4=0;leden5=0;i++; ledyinshe(min/10%10 );break;
- case 2: leden1=0; leden2=0; leden3=1;leden4=0;leden5=0;i++; ledyinshe(j);break;
- case 3: leden1=0; leden2=0; leden3=0;leden4=1;leden5=0;i++; ledyinshe(hour%10);break;
- case 4: leden1=0; leden2=0; leden3=0;leden4=0;leden5=1;i=0; ledyinshe(hour/10%10);break;
-
- default:;break;
-
- }
- }
复制代码
|
|