DS1302读写程序

合集下载

Ds1302读写详解

Ds1302读写详解

Ds1302读写详解void Write1302(unsigned char dat){unsigned char i;SCLK=0; //拉低SCLK,为写数据做准备delaynus(2); //延时,使硬件做好准备for(i=0;i<8;i++) //写8位二进制位数据{DATA=dat&0x01; //取出dat的第0位数据写入1302delaynus(2); /延时,使硬件做好准备SCLK=1; //上升沿写入数据delaynus(2); //延时,使硬件做好准备SCLK=0; //拉低SCLK,形成脉冲dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位}}void WriteSet1302(unsigned char Cmd,unsigned char dat){RST=0; //禁止数据传递SCLK=0; //写数据前拉低SCLKRST=1; //启动数据传输delaynus(2); //延时,使硬件做好准备Write1302(Cmd); //写入命令字Write1302(dat); //写数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递}unsigned char Read1302(void){unsigned char i,dat;delaynus(2); //延时,使硬件做好准备for(i=0;i<8;i++) //读8个二进制位数据{dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位if(DATA==1) //如果读出的数据是1dat|=0x80; //将1取出,写在dat的最高位SCLK=1; //将SCLK置于高电平,为下降沿读出delaynus(2); //延时SCLK=0; //拉低SCLK,形成脉冲下降沿delaynus(2); //延时}return dat; //将读出的数据返回}unsigned char ReadSet1302(unsigned char Cmd) {unsigned char dat;RST=0; //拉低RSTSCLK=0; //确保写数据前SCLK被拉低RST=1; //启动数据传输Write1302(Cmd); //写入命令字dat=Read1302(); //读出数据SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递return dat; //将读出的数据返回}。

ds1302程序及原理图

ds1302程序及原理图

/**************************************************;文件名:DS1302.c;功能:设置时间,然后将时间读出显示在数码管上;硬件描述:PORTD口接数码管的8个笔段; PORTA 0~2及PORTE 0~2分别接6位数码管的位;RC3接SCK,RC4接SDA,RC2接RST*/#include "pic.h"#define uchar unsigned char#define uint unsigned int#define Hidden 16__CONFIG(HS&WDTDIS&LVPDIS); //配置文件,设置为HS方式振荡,禁止看门狗,低压编程关闭ucharDispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x8 6,0x8E,0xFF};uchar BitTab[]={0xfb,0xfd,0xfe};uchar DispBuf[6];#define LSB 0x01#define WrEnDisCmd 0x8e //写允许/禁止指令代码#define WrEnDat 0x00 //写允许数据#define WrDisDat 0x80 //写禁止数据#define OscEnDisCmd 0x80 //振荡器允许/禁止指令代码#define OscEnDat 0x00 //振荡器允许数据#define OscDisDat 0x80 //振荡器禁止数据#define WrMulti 0xbe //写入多个字节的指令代码#define WrSingle 0x84 //写入单个字节的指令代码#define RdMulti 0xbf //读出多个字节的指令代码#define cClk RC3 //与时钟线相连的PIC16F877A芯片的管脚#define cDat RC4 //与数据线相连的PIC16F877A芯片的管脚#define cRst RC2 //与复位端相连的PIC16F877A芯片的管脚#define SCL_CNT TRISC3 //SCL管脚控制位#define SDA_CNT TRISC4 //SDA管脚控制位#define RST_CNT TRISC2 //RST管脚控制位void mDelay(uint DelayTime){ uint temp;for(;DelayTime>0;DelayTime--){ for(temp=0;temp<270;temp++){;}}}void interrupt Disp(){ static uchar dCount; //用作显示的计数器if(TMR1IF==1&&TMR1IE==1)//Timer 1 inetrrupt{TMR1H=-(8000/256);TMR1L=-(8000%256); //重置定时初值}PORTA|=0x07; //关前面的显示PORTE|=0X07; //关前面的显示PORTD=DispTab[DispBuf[dCount]]; //显示第i位显示缓冲区中的内容if(dCount<3)PORTE&=BitTab[dCount]; //第1~3位是由PORTE控制的elsePORTA&=BitTab[dCount-3]; //第4~6位是由PORTA的低3位控制的dCount++;if(dCount==6)dCount=0;TMR1IF=0; //清中断标志}//数码管位 1 2 3 4 5 6//引脚RE0 RE1 RE2 RA2 RA1 RA0//根据这个表,只要改变PORTA&=0xfe,即可点亮任意一个数码管//例:PORTA&=0xfd //点亮第5位数码管// PORTE&=0xfe //点亮第3位数码管void uDelay(uchar i){ for(;i>0;i--){;}}void SendDat(uchar Dat){ uchar i;for(i=0;i<8;i++){cDat=Dat&LSB; //数据端等于tmp数据的末位值Dat>>=1;cClk=1;uDelay(1);cClk=0;}}/*写入1个或者多个字节,第1个参数是相关命令#define WrMulti 0xbe //写入多个字节的指令代码#define WrSingle 0x84 //写入单个字节的指令代码第2个参数是待写入的值第3个参数是待写入数组的指针*/void WriteByte(uchar CmdDat,uchar Num,uchar *pSend){uchar i=0;SDA_CNT=0; //数据端设为输出cRst=0;uDelay(1);cRst=1;SendDat(CmdDat);for(i=0;i<Num;i++){ SendDat(*(pSend+i));}cRst=0;}/*读出字节,第一个参数是命令#define RdMulti 0xbf //读出多个字节的指令代码第2个参数是读出的字节数,第3个是指收数据数组指针*/void RecByte(uchar CmdDat,uchar Num,uchar *pRec){uchar i,j,tmp;SDA_CNT=0; //数据端设为输出cRst=0; //复位引脚为低电平uDelay(1);cClk=0;uDelay(1);cRst=1;SendDat(CmdDat); //发送命令SDA_CNT=1; //数据端设为输入for(i=0;i<Num;i++){ for(j=0;j<8;j++){ tmp>>=1;if(cDat)tmp|=0x80;cClk=1;uDelay(1);cClk=0;}*(pRec+i)=tmp;}uDelay(1);cRst=0;}/*当写保护寄存器的最高位为0时,允许数据写入寄存器。

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时钟芯片,驱动程序的编写以及实现数字字符在数码管中的显示。

#include<reg52.h>#include <intrins.h>sbit SCK=P3^6; //时钟引脚sbit SDA=P3^4; //数据端口sbit RST = P3^5;// DS1302复位sbit LS138A=P2^2;sbit LS138B=P2^3;sbit LS138C=P2^4;bit ReadRTC_Flag;//定义读DS1302标志unsigned char l_tmpdate[7]={0,0,12,15,5,3,8};//秒分时日月周年08-05-15 12:00:00 unsigned char l_tmpdisplay[8];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 chartable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共阴数码管 0-9 '-' '熄灭‘表/******************************************************************/ /* 函数声明 *//******************************************************************/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 RTCvoid Set_RTC(void); //set RTCvoid InitTIMER0(void);//inital timer0/******************************************************************/ /* 主函数 *//******************************************************************/ void main(void){InitTIMER0(); //初始化定时器0Set_RTC(); //写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽while(1){if(ReadRTC_Flag){ReadRTC_Flag=0;Read_RTC();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;}}}/******************************************************************/ /* 定时器0初始化 *//******************************************************************/ void InitTIMER0(void){TMOD|=0x01;//定时器设置 16位TH0=0xef;//初始化值TL0=0xf0;ET0=1;TR0=1;EA=1;}/******************************************************************/ /* 写一个字节 *//******************************************************************/ 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;}}/******************************************************************/ /* 写入DS1302 *//******************************************************************/ 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; //恢复}/******************************************************************/ /* 读出DS1302数据 *//******************************************************************/unsigned char Read_Ds1302 ( unsigned char address ){unsigned char i,temp=0x00;RST=0;_nop_();_nop_();SCK=0;_nop_();_nop_();RST=1;_nop_();_nop_();Write_Ds1302_Byte(address);for (i=0;i<8;i++) //循环8次读取数据{if(SDA)temp|=0x80; //每次传输低字节SCK=0;temp>>=1; //右移一位_nop_();_nop_();_nop_();SCK=1;}RST=0;_nop_(); //以下为DS1302复位的稳定时间_nop_();RST=0;SCK=0;_nop_();_nop_();_nop_();_nop_();SCK=1;_nop_();_nop_();SDA=0;_nop_();_nop_();SDA=1;_nop_();_nop_();return (temp); //返回}/******************************************************************/ /* 读时钟数据 *//******************************************************************/ void Read_RTC(void) //读取日历{unsigned char i,*p;p=read_rtc_address; //地址传递for(i=0;i<7;i++) //分7次读取秒分时日月周年{l_tmpdate[i]=Read_Ds1302(*p);p++;}}/******************************************************************//* 设定时钟数据 *//******************************************************************/ void Set_RTC(void) //设定日历{unsigned char i,*p,tmp;for(i=0;i<7;i++){ //BCD处理tmp=l_tmpdate[i]/10;l_tmpdate[i]=l_tmpdate[i]%10;l_tmpdate[i]=l_tmpdate[i]+tmp*16;}Write_Ds1302(0x8E,0X00);p=write_rtc_address; //传地址for(i=0;i<7;i++) //7次写入秒分时日月周年{Write_Ds1302(*p,l_tmpdate[i]);p++;}Write_Ds1302(0x8E,0x80);}/******************************************************************/ /* 定时器中断函数 *//******************************************************************/ void tim(void) interrupt 1 using 1//中断,用于数码管扫描{static unsigned char i,num;TH0=0xf5;TL0=0xe0;P0=table[l_tmpdisplay[i]]; //查表法得到要显示数字的数码段switch(i){case 0:LS138A=0; LS138B=0; LS138C=0; break;case 1:LS138A=1; LS138B=0; LS138C=0; break;case 2:LS138A=0; LS138B=1; LS138C=0; break;case 3:LS138A=1; LS138B=1; LS138C=0; break;case 4:LS138A=0; LS138B=0; LS138C=1; break;case 5:LS138A=1; LS138B=0; LS138C=1; break;case 6:LS138A=0; LS138B=1; LS138C=1; break;case 7:LS138A=1; LS138B=1; LS138C=1; break;}i++;if(i==8){i=0;num++;if(10==num) //隔段时间读取1302的数据。

PIC单片机读写时钟芯片DS1302汇编程序

PIC单片机读写时钟芯片DS1302汇编程序
BSF SCLK ;恢复高电平
DECFSZ COUNT1,F
GOTO TR1
BANK1
BCF TRISC,7 ;OUTPUT
BANK0
BCF SCLK ;恢复
RETURN
NOP
PORT_INI
BANK1
MOVLW B'00000000'
MOVWF TRISC
MOVLW B'0'
MOVWF TRISB
MOVLW B'00000111'
MOVWF ADCON1
MOVLW B'00000000'
MOVWF TRISA
BANK0
MOVLW 18H
MOVWF 20H
MOVLW 19H
MOVWF 21H
MOVLW 05H
MOVWF 22H
MOVLW 13H
MOVWF 23H
; 作用:一次接受7个字节的时间数据,突发模式读取
; INPUT:NONE
; OUTPUT:把7个时间数据保存在TIME_RX_ADD开始的7个寄存器里面
;***********************************************
GET_TIME
MOVLW B'10111111'
读秒,可以读任意7个时间,单字节
MOVLW B'10000001'
MOVWF TIME_TX
BSF RST
CALL TIME_WRITE_1
CALL TIME_READ_1
BCF RST
GOTO $

DS1302读写程序

DS1302读写程序

//读 DS1302RAM 字节 unsigned char TimeRamByteRead(unsigned char address) { TimeSpiOpen();//打开 DS1302 TimeSpiReadWrite((address << 1) | 0xc1);//写入 DS1302 命令 address = TimeSpiReadWrite(0xff);//读入 DS1302 数据 TimeSpdress;//返回数据 }
val = TimeByteRead(timereadseg);//读秒数据 val &= 0x7f;//打开晶振 TimeWrieDisbale();//开放 DS1302 写保护 TimeByteWrite(timewriteseg, val);//打开晶振 TimeByteWrite(tricklewrite, 0xa5);//打开充电二极管 TimeWriteEnable();//使能 DS1302 写保护 }
//打开 DS1302 void TimeSpiOpen(void) { TIMECLK = 0; TIMERST = 0;//禁止 DS1302 TIMEIO } //关闭 DS1302 void TimeSpiClose(void) { TIMERST = 0;//禁止 DS1302 TIMEIO } //读写 DS1302 unsigned char TimeSpiReadWrite(unsigned char val) { unsigned char i; ACC = val;//取 8 位数据 for (i = 8;i > 0; i--) { TIMECLK = 0;//时钟下降沿输入数据(DS1302 读) _nop_();//延时 CY = TIMEIO;//接收串行数据到 CY _rrca_();//右移一位数据到 CY(先存后取) TIMEIO = CY;//发送串行数据 TIMECLK = 1;//时钟上升沿打入数据(DS1302 写) TIMEIO } val = ACC; return val; } //读 DS1302 字节 unsigned char TimeByteRead(unsigned char address) { TimeSpiOpen();//打开 DS1302 TimeSpiReadWrite(address);//写入 DS1302 命令 address = TimeSpiReadWrite(0xff);//读入 DS1302 数据 TimeSpiClose();//关闭 DS1302 return address;//返回数据 } = 1;//释放数据总线 = 1;//释放数据总线 TIMECLK = 1; = 1;//释放数据总线 TIMERST = 1;//使能 DS1302

DS1302写入和读取Word版

DS1302写入和读取Word版

#include"ds1302.h"//---DS1302写入和读取时分秒的地址命令---////---秒分时日月周年最低位读写位;-------//uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。

---////---存储顺序是秒分时日月周年,存储格式是用BCD码---//uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13};/****************************************************************************** ** 函数名: Ds1302Write* 函数功能: 向DS1302命令(地址+数据)* 输入: addr,dat* 输出: 无******************************************************************************* /void Ds1302Write(uchar addr, uchar dat){uchar n;RST = 0;_nop_();SCLK = 0;//先将SCLK置低电平。

_nop_();RST = 1; //然后将RST(CE)置高电平。

_nop_();for (n=0; n<8; n++)//开始传送八位地址命令{DSIO = addr & 0x01;//数据从低位开始传送addr >>= 1;SCLK = 1;//数据在上升沿时,DS1302读取数据_nop_();SCLK = 0;_nop_();}for (n=0; n<8; n++)//写入8位数据{DSIO = dat & 0x01;dat >>= 1;SCLK = 1;//数据在上升沿时,DS1302读取数据_nop_();SCLK = 0;_nop_();}RST = 0;//传送数据结束_nop_();}/****************************************************************************** ** 函数名: Ds1302Read* 函数功能: 读取一个地址的数据* 输入: addr* 输出: dat******************************************************************************* /uchar Ds1302Read(uchar addr){uchar n,dat,dat1;RST = 0;_nop_();SCLK = 0;//先将SCLK置低电平。

DS1302程序

DS1302程序

;1.每次上电,必须把秒寄存器高位(第7位)设置为0,时钟才能走时。

;2.如果需要写入数据和时钟日历信息,必须把“写保护”寄存器设置成为0 ;内存数据定义BitCnt data 30h ; 数据位计数器ByteCnt data 31h ; 数据字节计数器Command data 32h ; 命令字节地址RcvDat DATA 40H ; 接收数据缓冲区XmtDat DATA 50H ; 发送数据缓冲区;端口位定义IO_DATA bit P1.1 ; 数据传送总线SCLK bit P1.0 ; 时钟控制总线RST bit P1.2 ; 复位总线RS EQU P1.3;确定具体硬件的连接方式RW EQU P1.4 ;确定具体硬件的连接方式E EQU P1.5 ;确定具体硬件的连接方式ORG 0000HLJMP START;**************************** ;main programORG 0030HSTART: CLR RSTMOV SP,#2AH;------------------------------------初始化1302-------------------------SET1302:LCALL Write_Multiplebyte;初始化1302,将我们要设定的数据写入CG:LCALL Read_Multiplebyte;将我们设定的数据读出来MOV P3,#10000000BLCALL ENABLEMOV P3,#00011100BLCALL ENABLEMOV P3,#00110000BLCALL ENABLEMOV P3,#01100000BLCALL ENABLEMOV P3,#00000001BLCALL ENABLELCALL STLCDJNB P2.4,SETB_TIMELCALL YSLJMP CGSETB_TIME:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#01110011BLCALL ENABLE;调用写入命令子程序JNB P2.4,SETB_TIME1JB P2.5,LJMP_ADDINC 45HLJMP_ADD:JB P2.6,LJMP_SUBBDEC 45HLJMP_SUBB:MOV A,45HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULIMOV A,45HADD A,#6MOV 45H,ACHULI:MOV A,45HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULIMOV A,45HSUBB A,#6MOV 45H,AZAICHULI:LCALL STLCDMOV P3,#01110011BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTTTTLJMP SETB_TIMEOUTPUTTTT:LJMP OUTPUTSETB_TIME1:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#11010011BLCALL ENABLE;调用写入命令子程序JNB P2.4,SETB_TIME2JB P2.5,LJMP_ADD1INC 43HLJMP_ADD1:JB P2.6,LJMP_SUBB1DEC 43HLJMP_SUBB1:MOV A,43HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI1MOV A,43HADD A,#6MOV 43H,ACHULI1:MOV A,43HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI1MOV A,43HSUBB A,#6MOV 43H,AZAICHULI1:LCALL STLCDMOV P3,#11010011BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTLJMP SETB_TIME1SETB_TIME2:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#00010011BLCALL ENABLE;调用写入命令子程序JNB P2.4,SETB_TIME3JB P2.5,LJMP_ADD2INC 44HLJMP_ADD2:JB P2.6,LJMP_SUBB2DEC 44HLJMP_SUBB2:MOV A,44HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI2MOV A,44HADD A,#6MOV 44H,ACHULI2:MOV A,44HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI2MOV A,44HSUBB A,#6MOV 44H,AZAICHULI2:LCALL STLCDMOV P3,#00010011BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTLJMP SETB_TIME2OUTPUT:LCALL Write_Enable;写允许MOV Command,#0BEh ;命令字节为BEhMOV ByteCnt,#8 ;多字节写入模式此模块为8 个MOV R0,#XmtDat;数据地址覆给R0MOV XmtDat,40H ;秒单元内容为59hMOV XmtDat+1,41H ;分单元内容为59hMOV XmtDat+2,42H ;时单元内容为13hMOV XmtDat+3,43H ;日期单元内容为21hMOV XmtDat+4,44H ;月单元内容为06hMOV XmtDat+5,45H ;星期单元内容为03hMOV XmtDat+6,46H ;年单元内容为00hMOV XmtDat+7,#0 ;写保护单元内容为00hLCALL Send_Byte ;调用写入数据子程序LJMP CGSETB_TIME3:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#10100011BLCALL ENABLE;调用写入命令子程序JNB P2.4,SETB_TIME4JB P2.5,LJMP_ADD3INC 46HLJMP_ADD3:JB P2.6,LJMP_SUBB3DEC 46HLJMP_SUBB3:MOV A,46HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI3MOV A,46HADD A,#6MOV 46H,ACHULI3:MOV A,46HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI3MOV A,46HSUBB A,#6MOV 46H,AZAICHULI3:LCALL STLCDMOV P3,#10100011BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTLJMP SETB_TIME3SETB_TIME4:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#11010001BJNB P2.4,SETB_TIME5JB P2.5,LJMP_ADD4INC 40HLJMP_ADD4:JB P2.6,LJMP_SUBB4DEC 40HLJMP_SUBB4:MOV A,40HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI4MOV A,40HADD A,#6MOV 40H,ACHULI4:MOV A,40HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI4MOV A,40HSUBB A,#6MOV 40H,AZAICHULI4:LCALL STLCDMOV P3,#11010001BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTTLJMP SETB_TIME4SETB_TIME5:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#00010001BJNB P2.4,SETB_TIME6JB P2.5,LJMP_ADD5INC 41HLJMP_ADD5:JB P2.6,LJMP_SUBB5DEC 41HLJMP_SUBB5:MOV A,41HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI5MOV A,41HADD A,#6MOV 41H,ACHULI5:MOV A,41HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI5MOV A,41HSUBB A,#6MOV 41H,AZAICHULI5:LCALL STLCDMOV P3,#00010001BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTTLJMP SETB_TIME5OUTPUTT:LJMP OUTPUTSETB_TIME6:LCALL YSMOV P3,#11110000B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV P3,#10100001BLCALL ENABLE;调用写入命令子程序JNB P2.4,SETB_TIMEEJB P2.5,LJMP_ADD6INC 42HLJMP_ADD6:JB P2.6,LJMP_SUBB6DEC 42HLJMP_SUBB6:MOV A,42HMOV B,#16DIV ABMOV A,BCJNE A,#10,CHULI6MOV A,42HADD A,#6MOV 42H,ACHULI6:MOV A,42HMOV B,#16DIV ABMOV A,BCJNE A,#15,ZAICHULI6MOV A,42HSUBB A,#6MOV 42H,AZAICHULI6:LCALL STLCDMOV P3,#10100001BLCALL ENABLE;调用写入命令子程序JNB P2.7,OUTPUTTLJMP SETB_TIME6SETB_TIMEE:LJMP SETB_TIMESend_Byte:CLR RST ;复位引脚为低电平所有数据传送终止NOPCLR SCLK; 清时钟总线NOPSETB RST ;复位引脚为高电平逻辑控制有效NOPMOV A,Command; 准备发送命令字节MOV BitCnt,#08hS_Byte0:RRC A ;将最低位传送给进位位CMOV IO_DATA,C ;位传送至数据总线NOPSETB SCLK ;时钟上升沿发送数据有效NOPCLR SCLK ;清时钟总线DJNZ BitCnt,S_Byte0 ;位传送未完毕则继续NOPS_Byte1: ;准备发送数据MOV A,@R0 ;传送数据过程与传送命令相同MOV BitCnt,#08hS_Byte2:RRC AMOV IO_DATA,CNOPSETB SCLKNOPCLR SCLKDJNZ BitCnt,S_Byte2INC R0 ;发送数据的内存地址加1DJNZ ByteCnt,S_Byte1 ;字节传送未完毕则继续NOPCLR RST ;逻辑操作完毕清RSTRETReceive_Byte:CLR RST ;复位引脚为低电平所有数据传送终止NOPCLR SCLK ;清时钟总线NOPSETB RST ;复位引脚为高电平逻辑控制有效MOV A,Command ;准备发送命令字节MOV BitCnt,#08h ;传送位数为8R_Byte0:RRC A ;将最低位传送给进位位CMOV IO_DATA,C ;位传送至数据总线NOPSETB SCLK ;时钟上升沿发送数据有效NOPCLR SCLK ;清时钟总线DJNZ BitCnt,R_Byte0 ;位传送未完毕则继续NOPR_Byte1: ;准备接收数据CLR A ;清类加器CLR C ;清进位位CMOV BitCnt,#08h ;接收位数为8R_Byte2:NOPMOV C,IO_DATA ;数据总线上的数据传送给CRRC A ;从最低位接收数据SETB SCLK ;时钟总线置高NOPCLR SCLK ;时钟下降沿接收数据有效DJNZ BitCnt,R_Byte2 ;位接收未完毕则继续MOV @R1,A ;接收到的完整数据字节放入接收内存缓冲区INC R1 ;接收数据的内存地址加1DJNZ ByteCnt,R_Byte1 ;字节接收未完毕则继续NOPCLR RST ;逻辑操作完毕清RSTRET;--写保护寄存器操作------------------------------------------ Write_Enable:MOV Command,#8Eh ;命令字节为8EMOV ByteCnt,#1 ;单字节传送模式MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#00h ;数据内容为0 写入允许ACALL Send_Byte ;调用写入数据子程序RET;当写保护寄存器的最高位为1 时禁止数据写入寄存器---------------Write_Disable:MOV Command,#8Eh ;命令字节为8EMOV ByteCnt,#1 ;单字节传送模式MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#80h ;数据内容为80h 禁止写入ACALL Send_Byte ;调用写入数据子程序RET ;返回调用本子程序处;当把秒寄存器的第7 位时钟停止位设置为0 时起动时钟开始---------Osc_Enable:MOV Command,#80h ; 命令字节为80MOV ByteCnt,#1 ; 单字节传送模式MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#00h ;数据内容为0 振荡器工作允许ACALL Send_Byte ;调用写入数据子程序RET ;返回调用本子程序处;当把秒寄存器的第7 位时钟停止位设置为1 时时钟振荡器停止HT1380 进入低功耗方式---------------Osc_Disable:MOV Command,#80h ;命令字节为80MOV ByteCnt,#1 ;单字节传送模式MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#80h ;数据内容为80h 振荡器停止ACALL Send_Byte ;调用写入数据子程序RET ;返回调用本子程序处;写入00 年6 月21 日星期三13 时59 分59---------------------Write_Multiplebyte:MOV Command,#0BEh ;命令字节为BEhMOV ByteCnt,#8 ;多字节写入模式此模块为8 个MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#48h ;秒单元内容为59hMOV XmtDat+1,#14h ;分单元内容为59hMOV XmtDat+2,#09h ;时单元内容为13hMOV XmtDat+3,#16h ;日期单元内容为21h MOV XmtDat+4,#15h ;月单元内容为06hMOV XmtDat+5,#05h ;星期单元内容为03h MOV XmtDat+6,#07 ;年单元内容为00hMOV XmtDat+7,#0 ;写保护单元内容为00h ACALL Send_Byte ;调用写入数据子程序RET ;返回调用本子程序处;读出寄存器0-7 的内容程序设置如下Read_Multiplebyte:MOV Command,#0BFh ;命令字节为BFhMOV ByteCnt,#8 ;多字节读出模式此模块为8 个MOV R1,#RcvDat ;数据地址覆给R1ACALL Receive_Byte; 调用读出数据子程序RET; 返回调用本子程序处SSH:MOV B,#16DIV ABMOV 61H,BMOV 62H,AMOV R1,#62HMOV A,@R1MOV DPTR,#TABMOVC A,@A+DPTRMOV P3,ASETB RSCLR RWCLR ELCALL DELAYSETB EMOV A,@R1MOV DPTR,#TABMOVC A,@A+DPTRMOV P3,ASETB RSCLR RWCLR ELCALL DELAYSETB ERETENABLE:CLR RS ;写入控制命令的子程序CLR RWCLR EACALL DELAYSETB ERETDELAY:MOV P3,#0FFH ;判断液晶显示器是否忙的子程序CLR RSSETB RWCLR ENOPSETB EJB P3.0,DELAY ;如果P1.7为高电平表示忙就循环等待RET;写入8 时12 小时模式程序设置如下Write_Singlebyte:MOV Command,#84h ; 命令字节为84hMOV ByteCnt,#1 ; 单字节传送模式MOV R0,#XmtDat ;数据地址覆给R0MOV XmtDat,#88h ;数据内容为88hACALL Send_Byte ;调用写入数据子程序RET ;返回调用本子程序处MOV P3,#00000001B;显示器开、光标开、光标允许闪烁LCALL ENABLE ;调用写入命令子程序MOV A,#0;显示时间字符MOV R7,#0TIME:MOV DPTR,#TAB2MOVC A,@A+DPTRMOV P3,ALCALL CCFF1INC R7MOV A,R7CJNE A,#5,TIMEMOV A,42HLCALL SSHMOV P3,#10110100BLCALL CCFF1MOV A,41HLCALL SSHMOV P3,#10110100BLCALL CCFF1MOV A,40HLCALL SSHMOV P3,#00000011BLCALL ENABLEMOV A,#0;显示日期字符MOV R7,#0DATE:MOV DPTR,#TAB1MOVC A,@A+DPTRMOV P3,ALCALL CCFF1INC R7CJNE A,#5,DATEMOV A,46HLCALL SSHMOV P3,#10110100B LCALL CCFF1MOV A,44HLCALL SSHMOV P3,#10110100B LCALL CCFF1MOV A,43HLCALL SSHMOV P3,#00000100B LCALL CCFF1MOV A,45HLCALL SSHRETYS:MOV R5,#60D2:MOV R6,#50D1: MOV R7,#66DJNZ R7, $DJNZ R6,D1DJNZ R5,D2RETCCFF1:SETB RSCLR RWCLR ELCALL DELAY SETB ERETTAB:DB00001100B,10001100B,01001100B,11001100B,00101100B,10101100B,01101100B,111 01100B,00011100B,10011100B,01110100B,10110100BTAB2:DB 00101010b,10010110b,10110110b,10100110b,01011100bTAB1:DB 00100010b,10000110b,00101110b,10100110b,01011100bEND。

STM32F103驱动DS1302程序(带注释)

STM32F103驱动DS1302程序(带注释)

1简介主控芯片是STM32F103ZET6,DS1302模块在某宝购买,测试两个小时,发现一个小时大概差1秒钟。

芯片受温度、电压影响较大。

输出结果用串口打印到串口调试助手。

如果要oled或者其他显示需要转换为十进制。

2.代码部分2.1 led部分------------led.h--------------------#ifndef __LED_H#define __LED_H#include "sys.h"void LED_Init(void);//初始化#endif------------led.c--------------------#include "led.h"//LED IO初始化void LED_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);//根据设定参数初始化GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB5 输出高}2.2 usart部分---------------usart.h------------------------#ifndef __USART_H#define __USART_H#include "stdio.h"#include "sys.h"void uart_init(u32 bound);void usart1_send_string(u8 *BuffToSend);void usart1_sendbyte(u8 data);#endif---------------usart.c-----------------------#include "sys.h"#include "usart.h"void uart_init(u32 bound){//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Peri ph_GPIOA, ENABLE); //使能USART1,GPIOA时钟//USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; //抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器//USART 初始化设置USART_ART_BaudRate = bound;//串口波特率USART_ART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_ART_StopBits = USART_StopBits_1;//一个停止位USART_ART_Parity = USART_Parity_No;//无奇偶校验位USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART1, ENABLE); //使能串口1 }//打印字节void usart1_sendbyte(u8 data){USART_SendData(USART1, data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);}//打印字符串void usart1_send_string(u8 *BuffToSend){u8 i=0;while(BuffToSend[i]!='\0'){USART_SendData(USART1, BuffToSend[i]);while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);i++;}}2.3 ds1302部分---------------ds1302.h-----------------------#ifndef __DS1302_H#define __DS1302_H#include "sys.h"//写年月日时间寄存器#define WriteSecond 0x80#define WriteMinute 0x82#define WriteHour 0x84#define WriteDay 0x86#define WriteMonth 0x88#define writeWeek 0x8a#define writeYear 0x8c//读年月日时间寄存器#define ReadSecond 0x81#define ReadMinute 0x83#define ReadHour 0x85#define ReadDay 0x87#define ReadMonth 0x89#define ReadWeek 0x8b#define ReadYear 0x8d//引脚分配 SDA-PC3 SCL-PC4 RST-PC5#define DS_SDA_IN {GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)8<<12;}#define DS_SDA_OUT{GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)3<<12;}#define DS_SDA_DATA GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)//SDA#define DS_SDA_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_3)#define DS_SDA_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_3)#define DS_SCK_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_4)//SCL#define DS_SCK_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_4)#define DS_RST_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_5)//CE#define DS_RST_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_5)void ds1302_init(void);void write_one_byte(u8 data);u8 read_one_byte(void);void ds1302_write_data(u8 reg,u8 data);u8 ds1302_read_data(u8 reg);void time_init(void);void time_read(void);u8 hex_to_bcd(u8 hex_data);u8 bcd_to_hex(u8 bcd_data);#endif---------------ds1302.c-----------------------#include "ds1302.h"#include "delay.h"u8 DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear;u8 time[7]={0x18,0x06,0x10,0x19,0x23,0x59,0x30};//年星期月日时分秒void ds1302_init(){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_ResetBits(GPIOC,GPIO_Pin_5);//CE拉低GPIO_SetBits(GPIOC, GPIO_Pin_3|GPIO_Pin_4); //拉高}//写入一个字节void write_one_byte(u8 data){u8 i;DS_SDA_OUT;for(i=0;i<8;i++){DS_SCK_LOW;if(data&0x01) //从低位开始{DS_SDA_HIGH;}else{DS_SDA_LOW;}delay_us(2);DS_SCK_HIGH;data>>=1;delay_us(2);}}//读一个字节u8 read_one_byte(){u8 i,data;DS_SDA_IN ;for(i=0;i<8;i++){data>>=1;DS_SCK_HIGH;if(DS_SDA_DATA==1){data|=0x80;}else{data&=0x7F;}delay_us(2);DS_SCK_LOW;}return data;}//ds1302写寄存器写数据void ds1302_write_data(u8 reg,u8 data) {DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高 write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;write_one_byte(data); //sck低到高delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;}//读ds1302寄存器数据u8 ds1302_read_data(u8 reg){u8 temp;DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高 delay_us(2);write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;temp=read_one_byte(); //sck由高到低delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;return temp;}u8 hex_to_bcd(u8 hex_data){u8 temp;temp=(hex_data/10*16 + hex_data%10);return temp;}u8 bcd_to_hex(u8 bcd_data){u8 temp;temp=(bcd_data/16*10 + bcd_data%16);return temp;}//time初始化void time_init(){ds1302_write_data(0x8e,0x00);//关闭写保护ds1302_write_data(writeYear ,(time[0]));//写入hex格式数据ds1302_write_data(writeWeek,(time[1]));ds1302_write_data(WriteMonth,(time[2]));ds1302_write_data(WriteDay,(time[3]));ds1302_write_data(WriteHour,(time[4]));ds1302_write_data(WriteMinute,(time[5]));//ds1302_write_data(WriteSecond,(time[6]));//ds1302_write_data(0x8e,0x80);//开启写保护}//读取寄存器时间void time_read(){DSyear=ds1302_read_data(ReadYear);DSweek=ds1302_read_data(ReadWeek);DSmonth=ds1302_read_data(ReadMonth);DSday=ds1302_read_data(ReadDay);DShour=ds1302_read_data(ReadHour);DSminute=ds1302_read_data(ReadMinute);DSsecond=ds1302_read_data(ReadSecond);}2.4主函数---------------main-----------------------#include "sys.h"#include "delay.h"#include "usart.h"#include "led.h"#include "ds1302.h"Extern u8 DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear;int main(void){delay_init();LED_Init();uart_init(115200);ds1302_init();time_init();while(1){time_read();//更新时间usart1_sendbyte(DSyear);usart1_sendbyte(DSmonth);usart1_sendbyte(DSday);usart1_sendbyte(DShour);usart1_sendbyte(DSminute);usart1_sendbyte(DSsecond);usart1_sendbyte(DSweek);GPIO_ResetBits(GPIOB,GPIO_Pin_5); //LED0闪烁delay_ms(250);GPIO_SetBits(GPIOB,GPIO_Pin_5); //delay_ms(250);}}3.结果串口调试助手hex显示,打印的是十六进制数据。

DS1302原理及程序说明

DS1302原理及程序说明

DS1302原理及程序说明DS1302 是DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31字节静态RAM ,通过简单的串行接口与单片机进行通信。

实时时钟/日历电路提供秒、分、时、日、日期、月、年的信息,每月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM 指示决定采用24 或12 小时格式。

DS1302 与单片机之间能简单地采用同步串行的方式进行,DS1302的引脚命名如图1-1所示。

通信仅需用到三根信号线:(1)CE 片选,(2)I/O 数据线,(3)SCLK 串行时钟,DS1302与CPU 的连接如图1-2所示。

时钟/RAM 的读/写数据以一个字节或多字节的字符组方式通信,DS1302工作时功耗很低,保持数据和时钟信息时功率小于1mW 。

DS1302具有双电源管脚,用于主电源和备份电源供应Vcc1,为可编程涓流充电电源附加七个字节存储器,它广泛应用于电话传真便携式仪器以及电池供电的仪器仪表等产品领域。

DS1302主要的性能指标如下:实时时钟具有能计算2100 年之前的秒、分、时、日、日期、星期、月、年的能力,还有闰年调整的能力31× 8 位暂存数据存储RAM 串行I/O 口方式,使得管脚数量最少宽范围工作电压2.0~ 5.5V工作电流2.0V 时,小于300nA读/写时钟或RAM 数据时有两种传送方式:单字节传送和多字节传送字符组方式8 脚DIP 封装或可选的8 脚SOIC 封装根据表面装配简单3 线接口与TTL 兼容Vcc=5V 。

DS1302的读写模式工作时序如图1-3和图1-4所示。

图1-3 单字节读模式图1-4 单字节写模式注:在多字节模式下,SCLK 发出同步脉冲,CS 须持续保持高电平直到多字节操作结束,图1-1 DS1302引脚图1-2 DS1302与CPU 接口DS1302内部寄存器的地址定义如表1-1所示。

表1-1 寄存器的地址及定义实验说明1. DS1302与51单片机的连接IO ——P2.7:串行数据输入/输出引脚SCLK ——P2.6:串行时钟引脚CE ——P2.4:片选CE2. LCD 与单片机连接;************************************************************************* ; LCD Module LMB1602 与单片机连接:;************************************************************************* ; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ;Vss Vdd V o RS R/W E D0 D1 D2 D3 D4 D5 D6 D7 BLA BLK ; 0V +5V 0V P32 P33 P34 ---------------- P1[0..7] ---------------- +5V 0V;*************************************************************************3. LCD 显示功能说明LCD1602显示格式如图1-5所示。

时钟芯片DS1302 的程序

时钟芯片DS1302 的程序

函 数 名:W1302()
功 能:往DS1302写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返 回 值:无
设 计:zhaojunjie 日 期:2002-03-19
***********************************************************************/
uchar RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /*相当于汇编中的 RRC */
函 数 名:R1302()
功 能:读取DS1302某地址的数据
说 明:先写地址,后读命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返 回 值:ucData :读取的数据
设 计:zhaojunjie 日 期:2002-03-19
{
T_IO = ACC0; /*相当于汇编中的 RRC */
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
时钟芯片DS1302 的程序(jyh.h头文件)

ds1302读秒程序

ds1302读秒程序
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--);
}

ds1302操作说明

ds1302操作说明

一、 电路原理图说明
说明:1. 晶振为32.768KHz晶振,晶振参数如下表所示:
二、 寄存器说明
注:1. 上表为:日历时钟寄存器地址和数据位功能说明;
1、单字节读写时序
注:在单字节或多字节读操作时,读出的第一个bit位,必须是在命令发送完后第一个下降沿处取得的,否则,读出的数据会出错。

(如上图所示)
2、多字节读写程序
对于多字节写,需要特别注意的是,在发送0xbe命令并连续完成7字节的时钟数据写入后,必须在rst信号有效的情况下,再追加一个字节的写保护使能字节0x80;否则,无法完成写入操作。

当然,在多字节写之前,也必须先发一条写保护使能关闭命令。

(如上图的N,应该为8,而第8个字节写入的应该是0x80这个值)
四、 程序说明。

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使用说明及其例程

超详细的ds1302使用说明及其例程

寄存器名称
秒寄存器 分寄存器 小时寄存器 日寄存器 月寄存器
7
6
5
432
1
0
RAM/C
1
A4 A3 A2 A1 A0 RD/W
K
1
0
0
000
0
1
0
0
000
1
1
0
0
001
0
1
0
0
001
1
1
0
0
010
0
星期寄存器
1
0
年寄存器
1
0
写保护寄存器
1
0
慢充电寄存器
1
0
时钟突发寄存器 1
0
0
010
1
0
011
0
0
时时钟以及 RAM。虽然数据分成两种,但是对单片机的程序而言,其实是一样的,就是对 特定的地址进行读写操作。
图4 DS1302的内部结构图
DS1302含充电电路,可以对作为后备电源的可充电电池充电,并可选择充电使能和串 入的二极管数目,以调节电池充电电压。不过对我们目前而言,最需要熟悉的是和时钟相关 部分的功能,对于其它参数请参阅数据手册。
for ( i=8; i>0; i-- ) //循环8次移位
{
SCLK = 0;
temp = addr; DIO = (bit)(temp&0x01);
//每次传输低字

addr >>= 1;
//右移一位
SCLK = 1;
}
//发送数据 for ( i=8; i>0; i-- ) { SCLK = 0; temp = dat; DIO = (bit)(temp&0x01); dat >>= 1; SCLK = 1; } CE = 0;

DS1302时钟芯片C语言程序

DS1302时钟芯片C语言程序

void ds1302set() //设置初始时间 {
uchar i; ds1302write(0x8e,0x00); //关写保护 for(i=0;i<7;i++) { ds1302write(0x80+i+i,time_date[i]); //将初始时间数 据写入 1302 对应的寄存器里 delay(5); }
}
}
lcdwrite_data('0'+((time_date[1]&0xf0)>>4)); // 显示分
lcdwrite_data('0'+(time_date[1]&0x0f)); lcdwrite_data(':'); lcdwrite_data('0'+((time_date[0]>>4)&0x0f)); // 显示秒 lcdwrite_data('0'+((time_date[0]&0x0f)));
ds1302write(0x8e,0x80); //开写保护 }
void ds1302get() //读取当前时间 {
uchar i; for(i=0;i<7;i++) { time_date[i]=ds1302read(0x81+i+i); 数据从 1302 对应的寄存器里读出来 delay(5); }
main() { lcdinit(); //初始化 1602
ds1302init(); //初始化 1302 ds1302set(); //设置初始时间
while(1) {
ds1302get();//读取当前时间 lcdwrite_com(0x80); lcdwrite_data('0'+((time_date[6]&0xf0)>>4)); // 显 示年 lcdwrite_data('0'+(time_date[6]&0x0f)); lcdwrite_data('/'); lcdwrite_data('0'+((time_date[4]&0xf0)>>4));// 显 示 月 lcdwrite_data('0'+(time_date[4]&0x0f)); lcdwrite_data('/'); lcdwrite_data('0'+((time_date[3]&0xf0)>>4));// 显 示 日 lcdwrite_data('0'+(time_date[3]&0x0f)); lcdwrite_data(' '); lcdwrite_data('0'+((time_date[5]&0xf0)>>4)); //显 示星期 lcdwrite_data('0'+(time_date[5]&0x0f)); lcdwrite_com(0x80+0x40); lcdwrite_data('0'+((time_date[2]&0xf0)>>4)); // 显 示时 lcdwrite_data('0'+(time_date[2]&0x0f)); lcdwrite_data(':');
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<p24FJ64GA006.h>#include"p24Fxxxx.h"#define uchar unsigned char#define uint unsigned int/////////////////////////////////////////////#define USER_DEINED_1 0x00#define USER_DEINED_2 0x02#define USER_DEINED_3 0x04#define USER_DEINED_4 0x06#define RS TD5//串口时为CS 2^6;#define RW TD7//串口为SID 2^5;#define E TF0 //串口为时钟SCLK 2^4; #define PSB TD6#define RST TB5 // P2^0;#define Lcm_Data LATE////////////////////////////////////////////unsigned char jicunqi,jicun,second,min,hour;uchar table_shizhong[7];#define RST_1302 TD11#define SCLK TD9//#define IO TD10#define IO PORTDbits.RD10void delay(void){unsigned int i=10000;while(i--);}void delay_us(void){unsigned int i=1000;while(i--);}//////////////////////////////////////////////void Delay_1ms(uint x)//1ms延时{unsigned char j;while(x--){for(j=0;j<125;j++){;}}}void Lcm_Delay(void){uchar i=100;while(i--);}void Lcm_Rd_Status(void) //读忙状态{RS=0;RW=1;E=0;Lcm_Delay();E=1;Lcm_Data=(LATE&0xFF00);while(PORTEbits.RE7==1);//while(1)//{//break;//}}void Lcm_Wr_Data(uchar wrdata) //写数据{Lcm_Rd_Status();RS=1;RW=0;Lcm_Data=wrdata;E=1;Lcm_Delay();E=0;}void Lcm_Wr_Command(uchar wrcommand) //写指令{Lcm_Rd_Status();RS=0;RW=0;Lcm_Data=wrcommand;E=1;Lcm_Delay();E=0;}void Wr_Cgram(uchar addr,uchar *table){uchar i;Lcm_Wr_Command(addr); //设定CGRAM地址for(i=0;i<32;i++)Lcm_Wr_Data(*table++);}//选定坐标void Lcm_GotoXY(uchar pos_X,uchar pos_y){uchar addr;if((pos_X>7)||(pos_y>3))return;if(pos_y==0)addr=0x80+pos_X;else if(pos_y==1)addr=0x90+pos_X;else if(pos_y==2)addr=0x88+pos_X;else if(pos_y==3)addr=0x98+pos_X;Lcm_Wr_Command(addr);//设定DDRAM地址}//显示字符串void Lcm_Disp_String(uchar *string){while (*string != '\0')Lcm_Wr_Data(*string++);}void Wr_Gdram(uchar pos_x,uchar pos_y,uint length,uchar width,uchar *table) {uchar i,j;Lcm_Wr_Command(0x34);//选择扩充指令Lcm_Wr_Command(0x36);for(j=pos_y;j<pos_y+width;j++){Lcm_Wr_Command(0x80+j); //Y总坐标,即第几行Lcm_Wr_Command(0x80+pos_x);//X坐标,16个点进1for(i=0;i<length/8;i++)//Lcm_Wr_Data(*table++);}Lcm_Wr_Command(0x30);//返回基本指令}//显示单个字符void Lcm_Disp_Onechar(uchar onechar) {Lcm_Wr_Data(onechar);}//显示自定义的字符void Disp_Cgram(uchar addr_data) {Lcm_Wr_Data(0x00);Lcm_Wr_Data(addr_data);}//清除GDRAMvoid Clean_Gdram(void){uchar i,j;Lcm_Wr_Command(0x34);for(j=0;j<32;j++){Lcm_Wr_Command(0x80+j);Lcm_Wr_Command(0x80);for(i=0;i<32;i++)Lcm_Wr_Data(0);}Lcm_Wr_Command(0x36);Lcm_Wr_Command(0x30);}void fill_full_Gdram(void){uchar i,j;Lcm_Wr_Command(0x34);for(j=0;j<32;j++){Lcm_Wr_Command(0x80+j);Lcm_Wr_Command(0x80);for(i=0;i<32;i++)Lcm_Wr_Data(0xff);}Lcm_Wr_Command(0x36);Lcm_Wr_Command(0x30);}//开显示,设置,清屏void Lcm_Init(void){Delay_1ms(50);RST=1;Delay_1ms(10);RST=0;Delay_1ms(10);RST=1;Lcm_Wr_Command(0x30);Delay_1ms(5);Lcm_Wr_Command(0x30);Delay_1ms(5);Lcm_Wr_Command(0x0c); //开显示及光标设置Delay_1ms(5);Lcm_Wr_Command(0x01); //显示清屏Delay_1ms(10);Lcm_Wr_Command(0x06); //显示光标移动设置Delay_1ms(5);}///////////////////////////////////////////////void write_DS1302(uchar Date){uchar i;for(i = 0;i < 8;i++){IO = 0;SCLK = 0;if(Date & 0x01)IO = 1;elseIO = 0;Date = Date >> 1;SCLK = 1;}SCLK = 0;}////////////////////////////////////////////uchar read_DS1302(){uchar i,Temp = 0;TRISDbits.TRISD10=1;for(i = 0;i < 8;i++){SCLK = 0;Temp = Temp >> 1;if(IO == 1)Temp = Temp | 0x80;SCLK = 1;}TRISDbits.TRISD10=0;SCLK = 0;Temp = Temp / 16 * 10 + Temp % 16;return Temp;}////////////////////////////////////////////////// void init_1302(void){SCLK = 0;RST_1302=0;RST_1302=1;write_DS1302(0x8e);write_DS1302(0x00);RST_1302=0;}void set_time(){SCLK = 0;RST_1302=0;RST_1302=1;write_DS1302(0xbe);write_DS1302(0x00);write_DS1302(0x58);write_DS1302(0x12);write_DS1302(0x08);write_DS1302(0x03);write_DS1302(0x06);write_DS1302(0x06);write_DS1302(0x00);RST_1302=0;}void get_time(void){uchar i;SCLK = 0;RST_1302=0;RST_1302=1;write_DS1302(0xbf);for(i=0;i<7;i++){table_shizhong[i]=read_DS1302();}RST_1302=0;}lcd_display(void){uchar i,a;for(i=0;i<7;i++){a=table_shizhong[i];Lcm_GotoXY(0,i);Lcm_Disp_Onechar(a/100+'0');Lcm_Disp_Onechar(a%100/10+'0');Lcm_Disp_Onechar(a%100%10+'0');}}lcd_display1(void){uchar i,a,a_baiwei,a_shiwei,a_gewei;for(i=0;i<7;i++){a=table_shizhong[i];Lcm_GotoXY(0,3+i);Lcm_Disp_String("a");}}void main(void){uchar i;TRISDbits.TRISD9=0; //RF3 SDO1 shuchu TRISDbits.TRISD11=0; //RF6 SCK1 shuchu TRISDbits.TRISD10=0; //RF6 SDI1 shuru ODCDbits.ODD10=1;/////////////////////////////////////////////////// TRISE=0x00;TRISDbits.TRISD5=0;TRISDbits.TRISD6=0;TRISDbits.TRISD7=0;TRISBbits.TRISB5=0;TRISFbits.TRISF0=0;Lcm_Init();Clean_Gdram();////////////////////////////////////////////////// init_1302();delay();set_time();///////////////////////////////////////////////// while(1){get_time();lcd_display();}}。

相关文档
最新文档