ds1302读秒程序

合集下载

实时时钟芯片DS1302设计程序

实时时钟芯片DS1302设计程序

IO EQU P1.0SCLK EQU P1.1RST EQU P1.2RW BIT P1.6RS BIT P1.7E BIT P1.5KEY0 BIT P3.2KEY1 BIT P3.3KEY2 BIT P3.5KEY3 BIT P3.7ORG 0000HAJMP MAINORG 000BHAJMP T0INTORG 0100HMAIN: ACALL LCDINIT ;对LCD进行初始化LOP5:MOV 30H,#8 ;以下为将DS1302的数据存到单片机的40H到46H中MOV R0,#40HMOV R7,#7MOV R6,#81HLOP:CLR P1.2CLR P1.1SETB P1.2MOV B,R6ACALL WRITEACALL READMOV @R0,AINC R0INC R6INC R6DJNZ R7,LOP ;读出DS1302中的数据存到单片机中MOV 30H, 40H ;秒MOV 31H, 41H ;分MOV 32H, #00H ;时缓存MOV 33H, 42H ;时MOV R4, #00H ;控制显示模式MOV R3, #00H ;记录控制信号MOV TMOD, #01HMOV TL0, #0E0HMOV TH0, #0B1HMOV IE, #10000010BMOV R2, #32HSETB TR0MOV A, #83H ;DDRAM的地址进行设置,选择从哪里开始显示ACALL WRCMOV A, #54H ;T的ASCII码ACALL WRDMOV A, #49H ;I的ASCII码ACALL WRDMOV A, #4DH ;M的ASCII码ACALL WRDMOV A, #45H ;E的ASCII码ACALL WRDMOV A, #3AH ;:的ASCII码ACALL WRDMOV A,#0C3H ;对DDRAM地址进行设置CALL WRCMOV A,#58H ;X的ASCII码CALL WRDMOV A,#51H ;Q的ASCII码CALL WRDDEC 45HMOV A,45H ;显示星期ANL A,#0FHADD A,#30HACALL WRDMOV A,#3AH ;:的ASCII码CALL WRDMOV A,#10H ; 的ASCII码CALL WRDMOV A,46H ;显示年ANL A,#0F0HSWAP AADD A,#30HACALL WRDMOV A,46HANL A,#0FHADD A,#30HACALL WRDMOV A,#0CAH ;对DDRAM地址进行设置CALL WRCMOV A,#2DH ;-的ASCII码CALL WRDMOV A,44H ;显示月ANL A,#0F0HSWAP AADD A,#30HACALL WRDMOV A,44HANL A,#0FHADD A,#30HACALL WRDMOV A,#0CDH ;对DDRAM地址进行设置CALL WRCMOV A,#2DH ;-的ASCII码CALL WRDMOV A,43H ;显示日ANL A,#0F0HSWAP AADD A,#30HACALL WRDMOV A,43HANL A,#0FHADD A,#30HACALL WRDDONE: ACALL DISPLAYMOV A,#097H ;DDRAM的地址进行设置,选择从哪里开始显示CALL WRCMOV A,#31H ;1CALL WRDMOV A,#31H ;1CALL WRDMOV A,#30H ;0CALL WRDMOV A,#32H ;2CALL WRDMOV A,#3AH ;:CALL WRDMOV A,#48H ;H的ASCII码CALL WRDMOV A,#41H ;A的ASCII码CALL WRDMOV A,#4EH ;N的ASCII码CALL WRDMOV A,#10H ; 的ASCII码CALL WRDMOV A,#58H ;X的ASCII码CALL WRDMOV A,#49H ; I 的ASCII码CALL WRDMOV A,#41H ; A 的ASCII码CALL WRDMOV A,#4FH ;O的ASCII码CALL WRDMOV A,#10H ; 的ASCII码CALL WRDMOV A,#4EH ;N的ASCII码CALL WRDMOV A,#41H ; A 的ASCII码CALL WRDMOV A,#4EH ;N的ASCII码CALL WRDACALL KEYAJMP DONELCDINIT:MOV A, #01HACALL WRCMOV A, #38HACALL WRCMOV A, #0CHACALL WRCMOV A, #06HACALL WRCRET ;对液晶显示器初始功能设置DISPLAY:MOV R0, #32HMOV R1, #70HMOV R5, #03HMOV A, 33HCJNE A, #12H, LP2LP2: JC LP1MOV A, #9AHCLR CSUBB A, #12HADD A, 33HDA ALP1: MOV 32H, A ;调整显示模式LP3: MOV A, @R0SWAP AANL A, #0FHMOV @R1, AINC R1MOV A, @R0ANL A, #0FHMOV @R1, AINC R1DEC R0MOV @R1, #0AH ;:ASCII码减30H INC R1DJNZ R5, LP3MOV A, #88H ;第二行首地址ACALL WRCMOV R0, #70HLP4: MOV A, @R0ADD A, #30HACALL WRDINC R0RET ;显示时间KEY: JB KEY0, KK1ACALL DELAYJB KEY0, KK1JNB KEY0, $INC R4CJNE R4, #02H, KOENDMOV R4, #00H KOEND: RETKK1:JB KEY1, KK2ACALL DELAYJB KEY1, KK2JNB KEY1, $CLR TR0INC R3CJNE R3, #04H, K1ENDMOV R3, #00HSETB TR0K1END: RETKK2: JB KEY2, KK3ACALL DELAYJB KEY2, KK3JNB KEY2, $MOV A, R3RL AMOV DPTR, #KJMP2JMP @A+DPTRKJMP2: AJMP K2ENDAJMP SINCAJMP MINCAJMP HINCSINC: MOV A, 30HADD A, #01HDA AMOV 30H, ACJNE A, #60H, K2ENDMOV 30H, #00HAJMP K2ENDMINC: MOV A, 31HADD A, #01HDA AMOV 31H, ACJNE A, #60H, K2ENDMOV 31H, #00HAJMP K2ENDHINC: MOV A, 33HADD A, #01HDA AMOV 33H, ACJNE A, #24H, K2ENDMOV 33H, #00HK2END: RET ;增1程序KK3: JB KEY3, K3ENDACALL DELAYJB KEY3, K3ENDJNB KEY3, $MOV A, R3RL AMOV DPTR, #KJMP3JMP @A+DPTRKJMP3: AJMP K3ENDAJMP SDECAJMP MDECAJMP HDECSDEC: MOV A, #9AHCLR CSUBB A, #01HADD A, 30HDA AMOV 30H, ACJNE A, #99H, K3ENDMOV 30H, #59HAJMP K3ENDMDEC: MOV A, #9AHCLR CSUBB A, #01HADD A, 31HDA AMOV 31H, ACJNE A, #99H, K3ENDMOV 31H, #59HAJMP K3ENDHDEC: MOV A, #9AHCLR CSUBB A, #01HADD A, 33HDA AMOV 33H, ACJNE A, #99H, K3ENDMOV 33H, #59HAJMP K3ENDK3END: RET ;减1程序T0INT: PUSH ACCPUSH PSWMOV TL0, #0E0HMOV TH0, #0B1HDJNZ R2, NEXTMOV R2, #32HMOV A, 30HADD A, #01HDA AMOV 30H, ACJNE A, #60H, NEXTMOV 30H, #00HS1: MOV A, 31HADD A, #01HDA AMOV 31H, ACJNE A, #60H, NEXTMOV 31H, #00HS2: MOV A, 32HADD A, #01HDA AMOV 33H, AMOV A, 33HCJNE A, #24H, NEXTMOV 33H, #00HNEXT: POP P SWPOP A CCRETI ;定时器计时WRITE: ;以下全为子程序MOV 30H,#8LOP1:MOV A,BRRC AMOV B,AMOV P1.0,CSETB P1.1CLR P1.1DJNZ 30H,LOP1RET ;写入命令子程序DS1302READ:MOV 30H,#8LOP2:MOV C,P1.0RRC ASETB P1.1CLR P1.1DJNZ 30H,LOP2RET ;读出数据子程序DS1302WRC: CLR RSCLR RWSETB EMOV P2, ACLR EACALL DELAYRET ;写入LCD命令的程序WRD: SETB RSCLR RWSETB EMOV P2, ACLR EACALL DELAYRET ;写入LCD要显示的数据的DELAY: MOV R7, #35HLP5: MOV R6, #3FHDJNZ R6, $DJNZ R7, LP5RET ;延时END ACALL DELAYRET ;写入LCD要显示的数据的DELAY: MOV R7, #35HLP5: MOV R6, #3FHDJNZ R6, $DJNZ R7, LP5RET ;延时 END。

DS1302程序

DS1302程序

#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar count_10ms; //定义10ms计数器sbit K1 = P3^2; //定义K1键sbit K2 = P3^3; //定义K2键sbit K3 = P3^4; //定义K3键sbit K4 = P3^5; //定义K4键sbit BEEP=P3^7; //定义蜂鸣器sbit reset = P1^2;sbit sclk = P1^0;sbit io = P1^1;sbit LCD_RS=P2^0;sbit LCD_RW=P2^1 ;sbit LCD_EN=P2^2;bit K1_FLAG=0; //定义按键标志位,当按下K1键时,该位置1,K1键未按下时,该位为0。

uchar code line1_data[] = {"---LCD Clcok---"}; //定义第1行显示的字符uchar code line2_data[] = {"****"}; //定义第2行显示的字符uchar disp_buf[8] ={0x00}; //定义显示缓冲区uchar time_buf[7] ={0,0,0x12,0,0,0,0}; //DS1302时间缓冲区,存放秒、分、时、日、月、星期、年uchar temp [2]={0}; //用来存放设置时的小时、分钟的中间值/********以下是函数声明********/void Delay_ms(uint xms) ;bit lcd_busy();void lcd_wcmd(uchar cmd);void lcd_wdat(uchar dat) ;void lcd_clr() ;void lcd_init() ;void write_byte(uchar inbyte); //写一字节数据函数声明uchar read_byte(); //读一字节数据函数声明void write_ds1302(uchar cmd,uchar indata); //写DS1302函数声明uchar read_ds1302(uchar addr); //读DS1302函数声明void set_ds1302(uchar addr,uchar *p,uchar n); //设置DS1302初始时间函数声明void get_ds1302(uchar addr,uchar *p,uchar n); //读当前时间函数声明void init_ds1302(); //DS1302初始化函数声明/********以下是延时函数********/void Delay_ms(uint xms){uint i,j;for(i=xms;i>0;i--) //i=xms即延时约xms毫秒for(j=110;j>0;j--);}/********以下是LCD忙碌检查函数********/bit lcd_busy(){bit result;LCD_RS = 0;LCD_RW = 1;LCD_EN = 1;_nop_();_nop_();_nop_();_nop_();result = (bit)(P0&0x80);LCD_EN = 0;return result;}/********以下是写指令寄存器IR函数********/void lcd_wcmd(uchar cmd){while(lcd_busy());LCD_RS = 0;LCD_RW = 0;LCD_EN = 0;_nop_();_nop_();P0 = cmd;_nop_();_nop_();_nop_();_nop_();LCD_EN = 1;_nop_();_nop_();_nop_();_nop_();LCD_EN = 0;}/********以下是写寄存器DR函数********/void lcd_wdat(uchar dat){while(lcd_busy());LCD_RS = 1;LCD_RW = 0;LCD_EN = 0;P0 = dat;_nop_();_nop_();_nop_();_nop_();LCD_EN = 1;_nop_();_nop_();_nop_();_nop_();LCD_EN = 0;}/********以下是LCD清屏函数********/void lcd_clr(){lcd_wcmd(0x01); //清除LCD的显示内容Delay_ms(5);}/********以下是LCD初始化函数********/void lcd_init(){Delay_ms(15); //等待LCD电源稳定lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据Delay_ms(5);lcd_wcmd(0x38);Delay_ms(5);lcd_wcmd(0x38);Delay_ms(5);lcd_wcmd(0x0c); //显示开,关光标Delay_ms(5);lcd_wcmd(0x06); //移动光标Delay_ms(5);lcd_wcmd(0x01); //清除LCD的显示内容Delay_ms(5);}/********以下是写一字节数据函数********/void write_byte(uchar inbyte){uchar i;for(i=0;i<8;i++){sclk=0; //写时低电平改变数据if(inbyte&0x01)io=1;elseio=0;sclk=1; //高电平把数据写入DS1302_nop_();inbyte=inbyte>>1;}}/********以下是读一字节数据函数********/uchar read_byte(){uchar i,temp=0;io=1;for(i=0;i<7;i++){sclk=0;if(io==1)temp=temp|0x80;elsetemp=temp&0x7f;sclk=1; //产生下跳沿temp=temp>>1;}return (temp);}/********写DS1302函数, 往DS1302的某个地址写入数据********/ void write_ds1302(uchar cmd,uchar indata){sclk=0;reset=1;write_byte(cmd);write_byte(indata);sclk=0;reset=0;}/********读DS1302函数,读DS1302某地址的的数据********/ uchar read_ds1302(uchar addr){uchar backdata;sclk=0;reset=1;write_byte(addr); //先写地址backdata=read_byte(); //然后读数据sclk=0;reset=0;return (backdata);}/********设置初始时间函数********void set_ds1302(uchar addr,uchar *p,uchar n){write_ds1302(0x8e,0x00); //写控制字,允许写操作for(;n>0;n--){write_ds1302(addr,*p);p++;addr=addr+2;}write_ds1302(0x8e,0x80); //写保护,不允许写}********读取当前时间函数********void get_ds1302(uchar addr,uchar *p,uchar n){for(;n>0;n--){*p=read_ds1302(addr);p++;addr=addr+2;}}********初始化DS1302函数********/void init_ds1302(){reset=0;sclk=0;write_ds1302(0x80,0x00); //写秒寄存器write_ds1302(0x90,0xab); //写充电器write_ds1302(0x8e,0x80); //写保护控制字,禁止写}/*********以下是蜂鸣器响一声函数********/void beep(){BEEP=0; //蜂鸣器响Delay_ms(100);BEEP=1; //关闭蜂鸣器Delay_ms(100);}/********以下是转换函数,负责将走时数据转换为适合LCD显示的数据********/void LCD_conv (uchar in1,in2,in3 )//形参in1、in2、in3接收实参time_buf[2]、time_buf[1]、time_buf[0]传来的小时、分钟、秒数据{disp_buf[0]=in1/10+0x30; //小时十位数据disp_buf[1]=in1%10+0x30; //小时个位数据disp_buf[2]=in2/10+0x30; //分钟十位数据disp_buf[3]=in2%10+0x30; //分钟个位数据disp_buf[4]=in3/10+0x30; //秒十位数据disp_buf[5]=in3%10+0x30; //秒个位数据}/********以下是LCD显示函数,负责将函数LCD_conv转换后的数据显示在LCD上********/void LCD_disp (){lcd_wcmd(0x44 | 0x80); //从第2行第4列开始显示lcd_wdat(disp_buf[0]); //显示小时十位lcd_wdat(disp_buf[1]); //显示小时个位lcd_wdat(0x3a); //显示':'lcd_wdat(disp_buf[2]); //显示分钟十位lcd_wdat(disp_buf[3]); //显示分钟个位lcd_wdat(0x3a); //显示':'lcd_wdat(disp_buf[4]); //显示秒十位lcd_wdat(disp_buf[5]); //显示秒个位}/********以下是按键处理函数********/void KeyProcess(){uchar min16,hour16; //定义16进制的分钟和小时变量write_ds1302(0x8e,0x00); //DS1302写保护控制字,允许写write_ds1302(0x80,0x80); //时钟停止运行if(K2==0) //K2键用来对小时进行加1调整{Delay_ms(10); //延时去抖if(K2==0){while(!K2); //等待K2键释放beep();time_buf[2]=time_buf[2]+1; //小时加1if(time_buf[2]==24) time_buf[2]=0; //当变成24时初始化为0hour16=time_buf[2]/10*16+time_buf[2]%10; //将所得的小时数据转变成16进制数据write_ds1302(0x84,hour16); //将调整后的小时数据写入DS1302}}if(K3==0) // K3键用来对分钟进行加1调整{Delay_ms(10); //延时去抖if(K3==0){while(!K3); //等待K3键释放beep();time_buf[1]=time_buf[1]+1; //分钟加1if(time_buf[1]==60) time_buf[1]=0; //当分钟加到60时初始化为0min16=time_buf[1]/10*16+time_buf[1]%10; //将所得的分钟数据转变成16进制数据write_ds1302(0x82,min16); //将调整后的分钟数据写入DS1302}}if(K4==0) //K4键是确认键{Delay_ms(10); //延时去抖if(K4==0){while(!K4); //等待K4键释放beep();write_ds1302(0x80,0x00); //调整完毕后,启动时钟运行write_ds1302(0x8e,0x80); //写保护控制字,禁止写K1_FLAG=0; //将K1键按下标志位清0}}}/********以下是读取时间函数,负责读取当前的时间,并将读取到的时间转换为10进制数********/void get_time(){uchar sec,min,hour; //定义秒、分和小时变量write_ds1302(0x8e,0x00); //控制命令,WP=0,允许写操作write_ds1302(0x90,0xab); //涓流充电控制sec=read_ds1302(0x81); //读取秒min=read_ds1302(0x83); //读取分hour=read_ds1302(0x85); //读取时time_buf[0]=sec/16*10+sec%16; //将读取到的16进制数转化为10进制time_buf[1]=min/16*10+min%16; //将读取到的16进制数转化为10进制time_buf[2]=hour/16*10+hour%16; //将读取到的16进制数转化为10进制}/********以下是主函数********/void main(void){uchar i;P0 = 0xff;P2 = 0xff;lcd_init(); //LCD初始化函数(在LCD驱动程序软件包中)lcd_clr(); //清屏函数(在LCD驱动程序软件包中)lcd_wcmd(0x00|0x80); //设置显示位置为第1行第0列i = 0;while(line1_data[i] != '\0') //在第1行显示"---LCD Clcok---"{lcd_wdat(line1_data[i]); //显示第1行字符i++; //指向下一字符}lcd_wcmd(0x40|0x80); //设置显示位置为第2行第0列i = 0;while(line2_data[i] != '\0') //在第2行0~3列显示"****"{lcd_wdat(line2_data[i]); //显示第2行字符i++; //指向下一字符}lcd_wcmd(0x4c|0x80); //设置显示位置为第2行第12列i = 0;while(line2_data[i] != '\0') //在第2行12列之后显示"****"{lcd_wdat(line2_data[i]); //显示第2行字符i++; //指向下一字符}init_ds1302(); //DS1302初始化while(1){get_time(); //读取当前时间if(K1==0) //若K1键按下{Delay_ms(10); //延时10ms去抖if(K1==0){while(!K1); //等待K1键释放beep(); //蜂鸣器响一声K1_FLAG=1; //K1键标志位置1,以便进行时钟调整}}if(K1_FLAG==1)KeyProcess(); //若K1_FLAG为1,则进行走时调整LCD_conv(time_buf[2],time_buf[1],time_buf[0]); //将DS1302的小时/分/秒传送到转换函数LCD_disp(); //调LCD显示函数,显示小时、分和秒}}。

ds1302时间读取

ds1302时间读取
{
time[i]=readtime_ds1302(0x81+i*2);
}
}
//*****************************************************************
//往DS1302的地址ds1302_add处写入ds1302_cmd数据或命令
//*****************************************************************
//设置预置时间到DS1302当中
//*****************************************************************
void settime_ds1302()
{
uchar i;
writetime_ds1302(0x8e,0x00); //write enable
//将读到的时间显示在六个数码管上,该子程序只显示分秒时。
//*****************************************************************
void time_display()
{
uchar i;
for(i=0;i<=2;i++)
{
numdis(time[i]&0x0f,i*2 ,20);
// ds1302_clk=1;
ds1302_rst=0;
}
//*****************************************************************
//从DS1302的地址DS1302_ADD处读出时间值

时钟芯片DS1302及其应用

时钟芯片DS1302及其应用

时钟停止标志位
秒控制寄存器
秒寄存器
bit7
秒寄存器的最高位,定义为时钟停止位,当该位置1,时 钟振荡停止,DS1302进入低功耗待机模式;
当该位置0,时钟振荡启动;
初始上电状态是没有定义。
启动时钟示例
uchar val;
val = read_DS1302(0x81); //读秒寄存器到val
val &= 0x7f;
最初通过 8 个时钟周期载入控制字节到移位寄存器。如果 控制指令选择的是单字节模式,后来的连续的 8 个时钟脉冲可 以进行 8 位数据的写或 8 位数据的读操作,SCLK 时钟的上升 沿时,数据被写入 DS1302 , SCLK 脉冲的下降沿读出 DS1302 的数据。
• DS1302的基本操作方式是:先写地址(最 后一位是0),再写数据;或者先写地址(最 后一位是1) ,再读数据。
dat|=0x80;
的低位。
DS1302_CLK=1;
nop;
DS1302_CLK=0;
}
return dat;
}
将上面的写字节和读字节放在一起研究 这是一种方案
写一个字节子程序
void sendbyte(uchar a) {
uchar i; for(i=8;i>0;i--) {
DS1302_IO = a & 0x01; a >>= 1; DS1302_CLK=1; _nop_(); DS1302_CLK=0; _nop_(); } }
复位与时钟控制
所有的数据传输必须从将 RST 置高电平开始;
数据传输时序
复位与时钟控制
所有的数据传输必须从将 RST置高电平开始; 一个时钟周期是由下降沿、上升沿组成的序列; 对于数据输入来说,数据必须在数据必须在时钟的上 升沿到来之前有效, 对于数据输入来说,在时钟的下降沿输出数据位。 如果 RST是低电平,所有的数据传输端和IO引脚都为 高阻态。

DS1302基本读写

DS1302基本读写
/*void Timer0_init( void )
{
TMOD |= 0x01; Fra bibliotek/设置定时器0的模式为16位
TH0 = ( 65536-46000 ) / 256;
TL0 = (65536-46000) % 256;
if( EA != 1 )
EA = 1;
ET0 = 1; //打开定时器0的中断
/*****************************************************************
*********** Name: DS1302
***********Date: 2014/12/25
***********Com: FairSun
*********** LOL
/*void Timer0_server( void ) interrupt 1
{
TH0 = (65536-46000) / 256;
TL0 = (65536-46000) % 256;
} */
/************************************************************************
const unsigned char smg_dp_yin[ 16 ] = {0xbf, 0x86, 0xdb, 0xcf, 0xe6, 0xed, 0xfd, 0x87, 0xff, 0xef,
0xf7, 0xfc, 0xb9, 0xde, 0xfb, 0xf1};//0. 1. 2. 3......f.
unsigned char month;
unsigned char date; //一月的几日
};

DS1302时钟程序详解

DS1302时钟程序详解

DS1302 时钟程序详解ds1302 时钟程序详解:DS1302 的控制字如图2 所示。

控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302 中,位6 如果为0,则表示存取日历时钟数据,为1 表示存取RAM 数据;位5 至位1 指示操作单元的地址;最低有效位(位0)如为0 表示要进行写操作,为1 表示进行读操作,控制字节总是从最低位开始输出。

2.3 数据输入输出(I/O)在控制指令字输入后的下一个SCLK 时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0 开始。

同样,在紧跟8 位的控制指令字后的下一个SCLK 脉冲的下降沿读出DS1302 的数据,读出数据时从低位0 位到高位7。

2.4 DS1302 的寄存器DS1302 有12 个寄存器,其中有7 个寄存器与日历、时钟相关,存放的数据位为BCD 码形式,其日历、时间寄存器及其控制字见表1。

此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM 相关的寄存器等。

时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。

DS1302 与RAM 相关的寄存器分为两类:一类是单个RAM 单元,共31 个,每个单元组态为一个8 位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM 寄存器,此方式下可一次性读写所有的RAM 的31 个字节,命令控制字为FEH(写)、FFH(读)。

ds1302 程序流程图3.2 DS1302 实时时间流程图4 示出DS1302 的实时时间流程。

根据此流程框图,不难采集实时时间。

下面结合流程图对DS1302 的基本操作进行编程:根据本人在调试中遇到的问题,特作如下说明:DS1302 与微处理器进行数据交换时,首先由微处理器向电路发送命令字节,命令字节最高位MSB(D7)必须为逻辑1,如果D7=0,则禁止写DS1302,即写保护;D6=0,指定时钟数据,D6=1,指定RAM 数据;D5~D1 指定输入或输出的特定寄存器; 最低位LSB(D0)为逻辑0,指定写操作(输入),D0=1,指定读操作(输出)。

时钟芯片DS1302 的程序(C51程序)

时钟芯片DS1302 的程序(C51程序)模块名称:DS1302.c功能:实时时钟模块时钟芯片型号:DS1302 程序设计:zhaojunjie********************************************************************* /#includesbit T_CLK = P2^7; /*实时时钟时钟线引脚 */ sbit T_IO = P1^4; /*实时时钟数据线引脚 */ sbit T_RST = P1^5; /*实时时钟复位线引脚 */sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;void RTInputByte(uchar); /* 输入 1Byte */uchar RTOutputByte(void); /* 输出?1Byte */void W1302(uchar, uchar);uchar R1302(uchar);void Set1302(uchar *); /* 设置时间 */void Bcd2asc(uchar,uchar *);void Get1302(uchar curtime[]); /* 读取1302当前时间 *//********************************************************************函数名:RTInputByte()功能:实时时钟写入一字节说明:往DS1302写入1Byte数据 (内部函数)入口参数:d 写入的数据返回值:无设计:zhaojunjie********************************************************************* **/void RTInputByte(uchar d){uchar i;ACC = d;for(i=8; i>0; i--){T_IO = ACC0; /*相当于汇编中的 RRC */T_CLK = 1;T_CLK = 0;ACC = ACC >> 1;}}/********************************************************************函数名:RTOutputByte()功能:实时时钟读取一字节说明:从DS1302读取1Byte数据 (内部函数)入口参数:无返回值:ACC设计:zhaojunjie********************************************************************* **/uchar RTOutputByte(void){uchar i;for(i=8; i>0; i--){ACC = ACC >>1; /*相当于汇编中的 RRC */ACC7 = T_IO;T_CLK = 1;T_CLK = 0;}return(ACC);}/********************************************************************函数名:W1302()功能:往DS1302写入数据说明:先写地址,后写命令/数据 (内部函数)调用:RTInputByte() , RTOutputByte()入口参数:ucAddr: DS1302地址, ucData: 要写的数据返回值:无设计:zhaojunjie********************************************************************* **/void W1302(uchar ucAddr, uchar ucDa){T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(ucAddr); /* 地址,命令 */RTInputByte(ucDa); /* 写1Byte数据*/T_CLK = 1;T_RST = 0;}/********************************************************************函数名:R1302()功能:读取DS1302某地址的数据说明:先写地址,后读命令/数据 (内部函数)调用:RTInputByte() , RTOutputByte()入口参数:ucAddr: DS1302地址返回值:ucData :读取的数据设计:zhaojunjie********************************************************************* **/uchar R1302(uchar ucAddr){uchar ucData;T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(ucAddr); /* 地址,命令 */ucData = RTOutputByte(); /* 读1Byte数据 */T_CLK = 1;T_RST = 0;return(ucData);}/********************************************************************函数名:BurstW1302T()功能:往DS1302写入时钟数据(多字节方式)说明:先写地址,后写命令/数据调用:RTInputByte()入口参数:pWClock: 时钟数据地址格式为: 秒分时日月星期年控制8Byte (BCD码)1B 1B 1B 1B 1B 1B 1B 1B返回值:无设计:zhaojunjie********************************************************************* **/void BurstW1302T(uchar *pWClock){uchar i;W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(0xbe); /* 0xbe:时钟多字节写命令 */for (i = 8; i>0; i--) /*8Byte = 7Byte 时钟数据 + 1Byte 控制*/{RTInputByte(*pWClock); /* 写1Byte数据*/pWClock++;}T_CLK = 1;T_RST = 0;}/********************************************************************函数名:BurstR1302T()功能:读取DS1302时钟数据说明:先写地址/命令,后读数据(时钟多字节方式)调用:RTInputByte() , RTOutputByte()入口参数:pRClock: 读取时钟数据地址格式为: 秒分时日月星期年7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B返回值:无设计:zhaojunjie********************************************************************* **/void BurstR1302T(uchar *pRClock){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(0xbf); /* 0xbf:时钟多字节读命令 */for (i=8; i>0; i--){*pRClock = RTOutputByte(); /* 读1Byte数据 */pRClock++;}T_CLK = 1;}/********************************************************************函数名:BurstW1302R()功能:往DS1302寄存器数写入数据(多字节方式)说明:先写地址,后写数据(寄存器多字节方式)调用:RTInputByte()入口参数:pWReg: 寄存器数据地址返回值:无设计:zhaojunjie********************************************************************* **/void BurstW1302R(uchar *pWReg){uchar i;W1302(0x8e,0x00); /* 控制命令,WP=0,写操作*/T_RST = 0;T_CLK = 0;T_RST = 1;RTInputByte(0xfe); /* 0xbe:时钟多字节写命令*/for (i=31; i>0; i--) /* 31Byte 寄存器数据 */{RTInputByte(*pWReg); /* 写1Byte数据*/pWReg++;}T_CLK = 1;T_RST = 0;}/********************************************************************函数名:BurstR1302R()功能:读取DS1302寄存器数据说明:先写地址,后读命令/数据(寄存器多字节方式)调用:RTInputByte() , RTOutputByte()入口参数:pRReg: 寄存器数据地址返回值:无设计:zhaojunjie********************************************************************* **/void BurstR1302R(uchar *pRReg){uchar i;T_CLK = 0;T_RST = 1;RTInputByte(0xff); /* 0xff:时钟多字节读命令 */for (i=31; i>0; i--) /*31Byte 寄存器数据 */{*pRReg = RTOutputByte(); /* 读1Byte数据 */pRReg++;}T_CLK = 1;T_RST = 0;}/********************************************************************函数名:Set1302()功能:设置初始时间说明:先写地址,后读命令/数据(寄存器多字节方式)调用:W1302()入口参数:pClock: 设置时钟数据地址格式为: 秒分时日月星期年7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B返回值:无设计:zhaojunjie********************************************************************* **/void Set1302(uchar *pClock){uchar i;uchar ucAddr = 0x80;W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/for(i =7; i>0; i--){W1302(ucAddr,*pClock); /* 秒分时日月星期年*/pClock++;ucAddr +=2;}W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/}/********************************************************************函数名:Get1302()功能:读取DS1302当前时间说明:调用:R1302()入口参数:ucCurtime: 保存当前时间地址。

DS1302时钟芯片51单片机c语言程序

DS1302时钟芯片51单片机c语言程序#ifndef __DS1302_H__#define __DS1302_H__#define uchar unsigned char#define uint unsigned int#includesbit SCLK = P3^2;sbit IO = P2^4;sbit RST = P3^3;#define R_Second 0x81#define W_Second 0x80#define R_Minute 0x83#define W_Minute 0x82#define R_Hour 0x85#define W_Hour 0x84#define R_Day 0x87#define W_Day 0x86#define R_Month 0x89#define W_Month 0x88#define R_Week 0x8B#define W_Week 0x8A#define R_Year 0x8D#define W_Year 0x8C#define R_Control 0x8F#define W_Control 0x8Evoid DS1302_Write_Byte(uchar Date); uchar DS1302_Read_Byte();void Write_DS1302(uchar Adr,uchar Date); uchar Read_DS1302(uchar Adr);void Init_DS1302();#endif#include "ds1302.h"/************************************************************** 函數名稱:DS1302_Write_Byte(uchar Date)函數功能:单字节写輸入參數:写的字节輸出參數:无備注:**************************************************************/ void DS1302_Write_Byte(uchar Date){uchar i;for(i = 0;i < 8;i++){if(Date & 0x01)IO = 1;elseIO = 0;SCLK = 1;Date = Date >> 1;SCLK = 0;}}/************************************************************** 函數名稱:uchar DS1302_Read_Byte()函數功能:单字节读輸入參數:无輸出參數:读出的数据備注:uchar DS1302_Read_Byte(){uchar i,Temp = 0;for(i = 0;i < 8;i++){Temp = Temp >> 1;SCLK = 0;if(IO == 1)Temp = Temp | 0x80;SCLK = 1;}return Temp;}/************************************************************** 函數名稱:Write_DS1302(uchar Adr,uchar Date)函數功能:写数据輸入參數:写的寄存器地址和数据輸出參數:无備注:**************************************************************/ void Write_DS1302(uchar Adr,uchar Date){RST = 0;SCLK = 0;RST = 1;DS1302_Write_Byte(Adr);DS1302_Write_Byte(Date);RST = 0;}函數名稱:uchar Read_DS1302(uchar Adr)函數功能:读数据輸入參數:写的寄存器地址輸出參數:读出的数据備注:**************************************************************/ uchar Read_DS1302(uchar Adr){uchar Temp = 0;RST = 0;SCLK = 0;RST = 1;DS1302_Write_Byte(Adr);Temp = DS1302_Read_Byte();RST = 0;Temp = Temp / 16 * 10 + Temp % 16;return Temp;}/************************************************************** 函數名稱:Init_DS1302()函數功能:初始化DS1302輸入參數:无輸出參數:无備注:**************************************************************/ void Init_DS1302(){Write_DS1302(W_Control,0x00);Write_DS1302(W_Year,0x11);Write_DS1302(W_Week,0x06); Write_DS1302(W_Month,0x09); Write_DS1302(W_Day,0x10); Write_DS1302(W_Hour,0x16); Write_DS1302(W_Minute,0x11); Write_DS1302(W_Second,0x23); Write_DS1302(W_Control,0x80); }。

DS1302C程序

#include<reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit dula=P2^6;sbit wela=P2^7;sbit SCK=P3^2;sbit SDA=P2^4;sbit RST=P3^3; // DS1302復位sbit rs=P3^5;sbit lcden=P3^4;sbit wr=P3^6;sbit set=P3^0; //定義按鍵端口sbit s2=P3^1;sbit rd=P3^7;uchar shi,ge,setn=0;bit flag;uchar code time0[]="DATE: - - ";uchar code time1[]="TIME: : : ";uchar time_dat[7]={30,59,23,30,11,2,13}; //秒分時日月周年//可隨時更改uchar write_add[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分時日月周年寫的寄存器地址uchar read_add[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //秒分時日月周年讀的寄存器地址void delayms(uchar ms){uchar j,k;for(j=ms;j>0;j--)for(k=110;k>0;k--);}void delayus(uchar t){while(--t); //12M晶振,t自減一次約2微秒}/**********十進制轉換成十六進制***********/uchar change_to16(uchar x){uchar tep,y;y=x;tep=y/16;y=y%16;y=y+tep*10;return y;}/**********十六進制轉換成十進制***********/uchar change_to10(uchar x){uchar tep,y;y=x;tep=y/10;y=y%10;y=y+tep*16;return y;}/***********往DS1302寫入一個字節********/void write_ds1302_byte(uchar dat){uchar i;for(i=0;i<8;i++){SCK=0;SDA=dat&0x01;dat>>=1;SCK=1;}}/*************往DS1302寄存器寫數據**************/ void write_ds1302(uchar add,uchar dat){RST=0;_nop_();SCK=0;_nop_();RST=1;write_ds1302_byte(add);write_ds1302_byte(dat);RST=0;SCK=0;SDA=1;}/****************讀一個字節****************/uchar Read_Ds1302_Byte(){uchar i,temp;for (i=0;i<8;i++) //循環8次讀取數據{temp>>=1;SCK=0; //先讀出數據,然後才進行判斷SDA是0還是1if(SDA)temp|=0x80; //每次傳輸低字節SCK=1;}return(temp);}/*************從寄存器讀數據***********/uchar Read_Ds1302(uchar add ){uchar date;RST=0;_nop_();SCK=0;_nop_();RST=1;write_ds1302_byte(add);date=Read_Ds1302_Byte();/*for(i=0;i<8;i++){temp>>=1;SCK=0;if(SDA)temp=temp|0x80;SCK=1;}*/RST=0;SCK=0;SDA=1;return date;}/***************設定日曆************/void Set_RTC(void){uchar i,*P;if(Read_Ds1302(0xc1!=0xf0))//讀RAM看是否需要寫入時間{for(i=0;i<7;i++) //BCD處理,將十六進制轉換成十進制{time_dat[i]=change_to10(time_dat[i]);}write_ds1302(0x8e,0x00); //關閉寫保護P=write_add; //傳要寫的寄存器地址for(i=0;i<7;i++) //7次寫入時分秒日月周年{write_ds1302(*P,time_dat[i]);P++;}write_ds1302(0x8e,0x80); //打開寫保護}}/****************讀取日曆****************/void read_rtc(){uchar i,*P;P=read_add;for(i=0;i<7;i++){time_dat[i]=Read_Ds1302(*P);P++;}}void write_com(uchar com){rs=0;lcden=0;P0=com;delayms(5);lcden=1;delayms(5);lcden=0;}void write_date(uchar date){rs=1;lcden=0;P0=date;delayms(5);lcden=1;delayms(5);lcden=0;}void init_1602() //液晶初始化{uchar num;dula=0;wela=0;lcden=0;wr=0;write_com(0x38); //顯示模式設置write_com(0x0c);write_com(0x06);write_com(0x01); //顯示清屏write_com(0x80);for(num=0;num<16;num++){write_date(time0[num]);delayms(3);}write_com(0x80+0x40);for(num=0;num<13;num++){write_date(time1[num]);delayms(3);}}/**************1602寫數據***************/void disp1602(){static uchar i=0;switch(i){case 0: write_com(0x80+0x40+11);break;//鏃華硊case 1: write_com(0x80+0x40+8);break;//煦華硊case 2: write_com(0x80+0x40+5);break;// 華硊case 3: write_com(0x80+11);break;// 華硊case 4: write_com(0x80+8);break;//堎華硊case 5: write_com(0x80+0x0e);break;//陎 華硊case 6: write_com(0x80+5);break;//爛華硊}shi=time_dat[i]/16;ge=time_dat[i]%16;write_date(0x30+shi);write_date(0x30+ge);i++;if(i==7)i=0;}/****************鍵盤掃描****************/void keyscan(){uchar tem[2],i; //存儲要更改的時間數據rd=0;if(set==0){flag=1; //時間停止delayus(500); //去鍵盤按下抖動if(set==0){delayus(500);while(!set);delayus(500); //去鍵盤抬起抖動while(!set);delayus(500);setn++;if(setn==1){write_com(0x80+0x40+12); //將光標移動到秒個位write_com(0x0f); //顯示光標並且閃爍}if(setn==2){write_com(0x80+0x40+9); //將光標移動到分個位write_com(0x0f); //顯示光標並且閃爍}if(setn==3){write_com(0x80+0x40+6); // 將光標移動到時個位write_com(0x0f); // 顯示光標並且閃爍}if(setn==4){write_com(0x80+15);write_com(0x0f);}if(setn==5){write_com(0x80+12);write_com(0x0f);}if(setn==6){write_com(0x80+9);write_com(0x0f);}if(setn==7){write_com(0x80+6);write_com(0x0f);}if(setn==8){setn=0;write_ds1302(0x8e,0x00); //關閉寫保護for(i=0;i<7;i++){write_ds1302(write_add[i],time_dat[i]);}write_ds1302(0x8e,0x80); //打開寫保護flag=0; //時間正常運行write_com(0x0c); //光標停止閃爍}}}if(setn!=0 ) //更改時間{/*if(s1==0) //增加時間{delayus(5000);if(s1==0){while(!s1);delayus(5000); //去鍵盤抬起時抖動while(!s1);if(setn==1){time_dat[0]=change_to16(time_dat[0]);time_dat[0]++;if(time_dat[0]>=60)time_dat[0]=0;{ //將秒增加後的值轉換後寫入DS1302秒寄存器time_dat[0]=change_to10(time_dat[0]);//write_ds1302(0x8e,0X00); //關閉寫保護//write_ds1302(write_add[0],time_dat[0]);//write_ds1302(0x8e,0x80); //打開寫保護}write_com(0x80+0x40+11); //將秒增加後的值轉換後寫入1602秒位置tem[0]=time_dat[0]/16;tem[1]=time_dat[0]&0x0f; //數據的轉換write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+0x40+12);}if(setn==2){time_dat[1]=change_to16(time_dat[1]);time_dat[1]++;if(time_dat[1]==60)time_dat[1]=0;{time_dat[1]=change_to10(time_dat[1]);//write_ds1302(0x8e,0X00); //關閉寫保護//write_ds1302(write_add[1],time_dat[1]);//write_ds1302(0x8e,0x80); //打開寫保護}write_com(0x80+0x40+8);tem[0]=time_dat[1]/16; //數據的轉換tem[1]=time_dat[1]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+0x40+9);}if(setn==3){time_dat[2]=change_to16(time_dat[2]);time_dat[2]++;if(time_dat[2]>=24)time_dat[2]=0;{time_dat[2]=change_to10(time_dat[2]);//write_ds1302(0x8e,0X00); //關閉寫保護//write_ds1302(write_add[2],time_dat[2]);//write_ds1302(0x8e,0x80); //打開寫保護}write_com(0x80+0x40+5);tem[0]=time_dat[2]/16; //數據的轉換tem[1]=time_dat[2]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+0x40+6);}if(setn==4){time_dat[5]=change_to16(time_dat[5]);time_dat[5]++;if(time_dat[5]==8)time_dat[5]=1;{time_dat[5]=change_to10(time_dat[5]);//write_ds1302(0x8e,0X00); //關閉寫保護//write_ds1302(write_add[5],time_dat[5]);//write_ds1302(0x8e,0x80);//打開寫保護}write_com(0x80+14);tem[0]=time_dat[5]/16; //數據的轉換tem[1]=time_dat[5]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+15);}if(setn==5){time_dat[3]=change_to16(time_dat[3]);time_dat[3]++;if(time_dat[3]==32)time_dat[3]=0;{time_dat[3]=change_to10(time_dat[3]);//write_ds1302(0x8E,0X00); //關閉寫保護//write_ds1302(write_add[3],time_dat[3]);//write_ds1302(0x8E,0x80); //打開寫保護}write_com(0x80+11);tem[0]=time_dat[3]/16; //數據的轉換tem[1]=time_dat[3]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+12);}if(setn==6){time_dat[4]=change_to16(time_dat[4]);time_dat[4]++;if(time_dat[4]==13)time_dat[4]=0;write_com(0x80+8);{time_dat[4]=change_to10(time_dat[0]);//write_ds1302(0x8E,0X00); //關閉寫保護//write_ds1302(write_add[4],time_dat[4]);//write_ds1302(0x8E,0x80); //打開寫保護}tem[0]=time_dat[4]/16; //數據的轉換tem[1]=time_dat[4]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+9);}if(setn==7){time_dat[6]=change_to16(time_dat[6]);time_dat[6]++;if(time_dat[6]==100)time_dat[6]=0;write_com(0x80+5);{time_dat[6]=change_to10(time_dat[0]);//write_ds1302(0x8E,0X00); //關閉寫保護//write_ds1302(write_add[6],time_dat[6]);//write_ds1302(0x8E,0x80); //打開寫保護}tem[0]=time_dat[6]/16; //數據的轉換tem[1]=time_dat[6]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+6);}}}*/if(s2==0) //減少時間{delayus(5000);if(s2==0){while(!s2);delayus(5000); //去鍵盤抬起時抖動while(!s2);if(setn==1){time_dat[0]=change_to16(time_dat[0]);if(time_dat[0]==0)time_dat[0]=60;time_dat[0]--;{time_dat[0]=change_to10(time_dat[0]);}write_com(0x80+0x40+11);tem[0]=time_dat[0]/16; //數據的轉換tem[1]=time_dat[0]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+0x40+12);}if(setn==2){time_dat[1]=change_to16(time_dat[1]);time_dat[1]--;if(time_dat[1]==-1)time_dat[1]=59;{time_dat[1]=change_to10(time_dat[1]);}write_com(0x80+0x40+8);tem[0]=time_dat[1]/16; //數據的轉換tem[1]=time_dat[1]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+0x40+9);}if(setn==3){time_dat[2]=change_to16(time_dat[2]);if(time_dat[2]!=0)time_dat[2]--;if(time_dat[2]==0)time_dat[2]=23;{time_dat[2]=change_to10(time_dat[2]);}write_com(0x80+0x40+5);tem[0]=time_dat[2]/16; //數據的轉換tem[1]=time_dat[2]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+0x40+6);}if(setn==4){time_dat[5]=change_to16(time_dat[5]);if(time_dat[5]!=0)time_dat[5]--;if(time_dat[5]==0)time_dat[5]=7;{time_dat[5]=change_to10(time_dat[5]);}write_com(0x80+14);tem[0]=time_dat[5]/16; //數據的轉換tem[1]=time_dat[5]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+15);}if(setn==5){time_dat[3]=change_to16(time_dat[3]);if(time_dat[3]!=0)time_dat[3]--;if(time_dat[3]==0)time_dat[3]=31;{time_dat[3]=change_to10(time_dat[3]);}write_com(0x80+11);tem[0]=time_dat[3]/16; //數據的轉換tem[1]=time_dat[3]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+12);}if(setn==6){time_dat[4]=change_to16(time_dat[4]);if(time_dat[4]!=0)time_dat[4]--;if(time_dat[4]==0)time_dat[4]=12;write_com(0x80+8);{time_dat[4]=change_to10(time_dat[4]);}tem[0]=time_dat[4]/16; //數據的轉換tem[1]=time_dat[4]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+9);}if(setn==7){time_dat[6]=change_to16(time_dat[6]);if(time_dat[6]!=0)time_dat[6]--;if(time_dat[6]==0)time_dat[6]=99;write_com(0x80+5);{time_dat[6]=change_to10(time_dat[6]);}tem[0]=time_dat[6]/16; //數據的轉換tem[1]=time_dat[6]&0x0f;write_date(0x30+tem[0]);write_date(0x30+tem[1]);write_com(0x80+6);}}}//}}/*******************************************************/ void main(void){dula=0;wela=0;init_1602();Set_RTC();//在第一次使用時給ds1302賦初值while(1){if(flag==0){read_rtc();disp1602();}keyscan();}}。

DS1302时钟程序详解

DS1302 时钟程序详解ds1302 时钟程序详解:DS1302 的控制字如图2 所示。

控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302 中,位6 如果为0,则表示存取日历时钟数据,为1 表示存取RAM 数据;位5 至位1 指示操作单元的地址;最低有效位(位0)如为0 表示要进行写操作,为1 表示进行读操作,控制字节总是从最低位开始输出。

2.3 数据输入输出(I/O)在控制指令字输入后的下一个SCLK 时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0 开始。

同样,在紧跟8 位的控制指令字后的下一个SCLK 脉冲的下降沿读出DS1302 的数据,读出数据时从低位0 位到高位7。

2.4 DS1302 的寄存器DS1302 有12 个寄存器,其中有7 个寄存器与日历、时钟相关,存放的数据位为BCD 码形式,其日历、时间寄存器及其控制字见表1。

此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM 相关的寄存器等。

时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。

DS1302 与RAM 相关的寄存器分为两类:一类是单个RAM 单元,共31 个,每个单元组态为一个8 位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM 寄存器,此方式下可一次性读写所有的RAM 的31 个字节,命令控制字为FEH(写)、FFH(读)。

ds1302 程序流程图3.2 DS1302 实时时间流程图4 示出DS1302 的实时时间流程。

根据此流程框图,不难采集实时时间。

下面结合流程图对DS1302 的基本操作进行编程:根据本人在调试中遇到的问题,特作如下说明:DS1302 与微处理器进行数据交换时,首先由微处理器向电路发送命令字节,命令字节最高位MSB(D7)必须为逻辑1,如果D7=0,则禁止写DS1302,即写保护;D6=0,指定时钟数据,D6=1,指定RAM 数据;D5~D1 指定输入或输出的特定寄存器; 最低位LSB(D0)为逻辑0,指定写操作(输入),D0=1,指定读操作(输出)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
uchar sz[2];
uchar sec,n,n10;
sbit CLK =P3^5;
sbit IO =P3^6;
sbit RST =P3^7;
int qw,bw,sw,gw,a,b,c,i,k,j;
b=12;
void delay()//延时程序
{uchar j;
for(j=250;j>0;j--);
{
wr_com(0x8b);
n10=read1302(0x85);
n=read1302(0x85)&0x0f;//时
n10=n10>>4;
wr_data(n10+48);//注意是映射码,液晶中是写入的内部规定的映射表
wr_data(n+48);
display(":");
n10=read1302(0x83);//分
{
uchar i;
for(i=8;i>0;i--)
{
IO=(bit)(ucda&0x01);
CLK=1;
CLK=0;
ucda>>=1;
}
}
//--------------ReadOneByteData-----------------/
uchar ReadByte(void)
{
uchar i,a;
for(i=8;i>0;i--)
}
del() /*延时0.2秒*/
{
unsigned char i,j,k;
for(i=20;i>0;i--)
for(j=20;j>0;j--)
for(k=248;k>0;k--);
}
//--------------WriteOneByteData-----------------/
void WriteByte(uchar ucda)
RST=0;
CLK=0;
RST=1;
WriteByte(Addr);
Data=ReadByte();
CLK=1;
RST=0;
return(Data);
}
////////////////ds1302初始化//////////////////调整时间时用
void csh1302(void)
{
CLK=0;
write1302(0x84,0x15);//预置时
write1302(0x86,0x13);//预置日期
write1302(0x88,0x05);//预置月
write1302(0x8a,0x02);//预置星期
write1302(0x8c,0x08);//预置年
////////////////////////////////////////////////
CLK=0;
RST=1;
WriteByte(Addr);
WriteByte(Data);
CLK=1;
RST=0;
}
//--------------WriteAddrFirst,ThenReadData-----------------/
uchar read1302(uchar Addr)
{
uchar Data;
code uchar tab[10]={0xFB,0x68,0xDD,0xFC,0x6E,0xBE,0xBF,0xE8,0xFF,0xFE};
//uchar str1[]="date of today is:";
uchar init[]={0x00,0x00,0x21,0x21,0x10,0x01,0x04};//秒,分,时,日,月,星期,年
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//写的时候,是低电平改变数据,上升沿送入数据
//读的时候,是低电平读入数据,下降沿使得从设备把数据放到总线上
//读的时候,是低电平读,但没有读出,提供下降沿使得从设备把数据放到总线上
//SBUF=sec;
SBUF=tab[sz[c]];
while(!TI);
TI=0;
}
}
//////////////////////////////////////////////
//////////////////////////////////////////////
/*
show_time()
RST=0;
write1302(0x8e,0x00);//打开写保护
write1302(0x90,0x06);//禁止充电
/////////////////////////////////////////////////
write1302(0x80,0x00);//预置秒
write1302(0x82,0x32);//预置分
wr_data(n10+48);
wr_data(n+48);
}
*/
void xianshi(void)
{
n10=read1302(0x81);//秒
n=read1302(0x81)&0x0f;
n10=n10>>4;
n10=n10&0x07;
sw=sz[1]=n10;
gw=sz[0]=n;
disp();
write1302(0x80,0x00);//启动时钟
write1302(0x8e,0x80);//关闭写保护
}
//////////////////////////////////////////////
void disp(void)
{
for(c=1;c>=0;c--)
{
//sec=read1302(0x81);
n=read1302(0x83)&0x0f;
n10=n10>>4;
n10=n10&0x07;
wr_data(n10+48);
wr_data(n+48);
display(":");
n10=read1302(0x81);//秒
n=read1302(0x81)&0x0f;
n10=n10>>4;
n10=n10&0x07;
{
a>>=1;
if(IO)a|=0x80;
CLK=1;
CLK=0;
}
return(a);
}
//--------------WriteAddrFist,ThenWriteData-----------------/
void write1302(uchar Addr,uchar Data)
{
RST=0;
}
main()
{
//b++;
//csh1302(); //初始化
//disp();
while(1)
{
del();
xianshi();
//disp(); //读秒//读秒
}
}
相关文档
最新文档