第48节:利用DS1302做一个实时时钟
时间:11-22
来源:互联网
点击:
- y_short(1);
- SCLK_dr=0; //清零时钟总线
- delay_short(1);
- DS1302_CE_dr = 1; //CE引脚为高,逻辑控制有效
- delay_short(1);
- //发送地址
- for ( i=0; i<8; i++ ) //循环8次移位
- {
- DIO_dr_sr = 0;
- temp = addr;
- if(temp&0x01)
- {
- DIO_dr_sr =1;
- }
- else
- {
- DIO_dr_sr =0;
- }
- delay_short(1);
- addr >>= 1; //右移一位
- SCLK_dr = 1;
- delay_short(1);
- SCLK_dr = 0;
- delay_short(1);
- }
- //发送数据
- for ( i=0; i<8; i++ ) //循环8次移位
- {
- DIO_dr_sr = 0;
- temp = dat;
- if(temp&0x01)
- {
- DIO_dr_sr =1;
- }
- else
- {
- DIO_dr_sr =0;
- }
- delay_short(1);
- dat >>= 1; //右移一位
- SCLK_dr = 1;
- delay_short(1);
- SCLK_dr = 0;
- delay_short(1);
- }
- DS1302_CE_dr = 0;
- delay_short(1);
- }
- //读取Ds1302时间的驱动 ,注意,此处读取的是BCD码,
- unsigned char Read1302 ( unsigned char addr )
- {
- unsigned char i,temp,dat1;
- DS1302_CE_dr=0; //单片机驱动DS1302属于SPI通讯方式,根据我的经验,不用关闭中断
- delay_short(1);
- SCLK_dr=0;
- delay_short(1);
- DS1302_CE_dr = 1;
- delay_short(1);
- //发送地址
- for ( i=0; i<8; i++ ) //循环8次移位
- {
- DIO_dr_sr = 0;
- temp = addr;
- if(temp&0x01)
- {
- DIO_dr_sr =1;
- }
- else
- {
- DIO_dr_sr =0;
- }
- delay_short(1);
- addr >>= 1; //右移一位
- SCLK_dr = 1;
- delay_short(1);
- SCLK_dr = 0;
- delay_short(1);
- }
- /* 注释二:
- * 51单片机IO口的特点,在读取数据之前必须先输出高电平,
- * 如果是PIC,AVR等单片机,这里应该把IO方向寄存器设置为输入
- */
- DIO_dr_sr =1; //51单片机IO口的特点,在读取数据之前必须先输出高电平,
- temp=0;
- for ( i=0; i<8; i++ )
- {
- temp>>=1;
- if(DIO_dr_sr==1)
- {
- temp=temp+0x80;
- }
- DIO_dr_sr =1;//51单片机IO口的特点,在读取数据之前必须先输出高电平
- delay_short(1);
- SCLK_dr = 1;
- delay_short(1);
- SCLK_dr = 0;
- delay_short(1);
- }
- DS1302_CE_dr=0;
- delay_short(1);
- dat1=temp;
- return (dat1);
- }
- unsigned char bcd_to_number(unsigned char ucBcdTemp)//BCD转原始数值
- {
- unsigned char ucNumberResult=0;
- unsigned char ucBcdTemp10;
- unsigned char ucBcdTemp1;
- ucBcdTemp10=ucBcdTemp;
- ucBcdTemp10=ucBcdTemp10>>4;
- ucBcdTemp1=ucBcdTemp;
- ucBcdTemp1=ucBcdTemp1&0x0f;
- ucNumberResult=ucBcdTemp10*10+ucBcdTemp1;
- return ucNumberResult;
- }
- unsigned char number_to_bcd(unsigned char ucNumberTemp) //原始数值转BCD
- {
- unsigned char ucBcdResult=0;
- unsigned char ucNumberTemp10;
- unsigned char ucNumberTemp1;
- ucNumberTemp10=ucNumberTemp;
- ucNumberTemp10=ucNumberTemp10/10;
- ucNumberTemp10=ucNumberTemp10<4;
- ucNumberTemp10=ucNumberTemp10&0xf0;
- ucNumberTemp1=ucNumberTemp;
- ucNumberTemp1=ucNumberTemp1%10;
- ucBcdResult=ucNumberTemp10|ucNumberTemp1;
- return ucBcdResult;
- }
- //日调整 每个月份的日最大取值不同,有的最大28日,有的最大29日,有的最大30,有的最大31
- unsigned char date_adjust(unsigned char ucYearTemp,unsigned char ucMonthTemp,unsigned char ucDateTemp) //日调整
- {
- unsigned char ucDayResult;
- unsigned int uiYearTemp;
- unsigned int uiYearYu;
- ucDayResult=ucDateTemp;
- switch(ucMonthTemp)//根据不同的月份来修正不同的日最大值
- {
- case 2://二月份要计算是否是闰年
- uiYearTemp=2000+ucYearTemp;
- uiYearYu=uiYearTemp%4;
- if(uiYearYu==0) //闰年
- {
- if(ucDayResult>29)
- {
- ucDayResult=29;
- }
- }
- else
- {
- if(ucDayResult>28)
- {
- ucDayResult=28;
- }
- }
- break;
- case 4:
- case 6:
- case 9:
- case 11:
- if(ucDayResult>30)
- {
- ucDayResult=30;
- }
- break;
- }
- return ucDayResult;
- }
- void ds1302_alarm_service(void) //ds1302出错报警
- {
- if(ucDs1302Error==1)//备用电池的电量用完了报警提示
- {
- if(uiDs1302Cnt>const_ds1302_0_5s)//大概0.5秒钟蜂鸣器响一次
- {
- ucDs1302Lock=1;//原子锁加锁
- uiDs1302Cnt=0; //计时器清零
- ucDs1302Lock=0;//原子锁解锁
- ucVoiceLock=1;//原子锁加锁,保护主函数与中断函数的共享变量uiVoiceCnt
- uiVoiceCnt=const_voi
DS1302实时时 相关文章:
- 如何实现DS1302实时时钟表显示在1602LCD液晶(11-18)
- LCD1602液晶显示DS1302实时时钟Proteus仿真(11-13)
- AT89C2051+LCD1602+DS1302实时时钟设计(c51)(11-10)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)