DS1302数码管显示程序
ds1302数码管显示应用
scanbuff[2]=buff/16;//十位
scanbuff[3]=buff%16;//个位
buff=ReadByte(Read_Sec); //秒
scanbuff[4]=buff/16;//十位
scanbuff[5]=buff%16;//个位
void WriteDS1302(void);//向DS1302写入时间。
void ReadDS1302(void);//读取DS1302中的年,月,日,星期几,小时,分钟和秒.
void SendCmd(unsigned char cmd);//传送地址
void delayus(unsigned char tt);
}
//读取地址RCmd的时间/数据
unsigned char ReadByte(unsigned char RCmd)
{
unsigned char valu=0x00,temp;
CE=0;//初使化
SCLK=0;//初使化,并为rise edge做准备
CE=1;//初使化,传输开始。The SCLK must be low when CE is driven to high level.
#defineRead_Mon0x89
#defineRead_Day0x8b
#defineRead_Yea0x8d
#define CLK_BurstW0xbf//时钟突发模式写
#define CLK_BurstR0xbf//时钟突发模式读
#define Write_RAM_Begin0xc0//RAM第一个字节写指令
sbit _74hc154_D = P1^3;
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应用刚学单片机,好多好奇,所以想做个简单的时钟。
下面是PROTEUS仿真电路和电路图,简单易懂。
文笔不好,说了多余。
下面是程序。
#include<reg52.h>#include<intrins.h>#include<ds1302.h>#define uint unsigned int#define uchar unsigned char#define BCDTUAN(str) (str/10*16+str%10) //定义宏,将要写入DS1302的时间转化为BCD码#define Write_Sec 0x80#define Write_Min 0x82#define Write_Hou 0x84#define Write_Dat 0x86#define Write_Mon 0x88#define Write_day 0x8a#define Write_Yea 0x8c#define Write_WP 0x8e //写保护位#define Write_TCR 0x90#define Read_Sec 0x81#define Read_Min 0x83#define Read_Hou 0x85#define Read_Dat0x87#define Read_Mon 0x89#define Read_Day 0x8b#define Read_Yea 0x8d#define CLK_BurstW 0xbf //时钟突发模式写#define CLK_BurstR 0xbf //时钟突发模式读#define Write_RAM_Begin 0xc0 //RAM第一个字节写指令#define Read_RAM_Begin 0xc1 //RAM第一个字节读指令#define RAM_BurstW 0xfe //突发模式写RAM#define RAM_BurstR 0xff //突发模式读RAMsbit _74hc154_A = P1^0;sbit _74hc154_B = P1^1;sbit _74hc154_C = P1^2;sbit _74hc154_D = P1^3;sbit CE =P1^6;sbit SCLK=P1^5;sbit IO =P1^4;uchar code scan[][4]={{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},{0,1,0,0},{0,1,0,1},{0,1,1,0},{0,1,1,1},{1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1},{1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1}};uchar scanbuff[]={0,0,0,0,0,0,0,0,0,0,0,0};uchar code dispdate[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};void WriteDS1302(void); //向DS1302写入时间。
DS1302+AT89S51单片机时钟C程序(六位共阳数码管显示)
DS1302+AT89S51单片机时钟C程序(六位共阳数码管显示)DS1302+A T89S51单片机时钟C程序(六位共阳数码管显示)//DS1302时钟芯片程序#include#define uchar unsigned char#define uint unsigned intsbit CLK=P2^3; //定义口sbit IO=P2^4;sbit RST=P2^5;sbit ACC7=ACC^7;sbit ACC0=ACC^0;uchara[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}, //定义数码管显示码b[8]={0x00,0x00,0x12,0x23,0x11,0x07,0x08,0xbe},//写入时钟数据,最后be突发访问c[7],s,s1,ml1,mh1,ml2,mh2,ml3,mh3; //c存放读.出时钟数据void delay(uint z) // 延时{uint i;uchar j;for(i=z;i>0;i--)for(j=200;j>0;j++);}// 显示子程序void display(uchar mh1,uchar ml1,uchar mh2,uchar ml2,uchar mh3,uchar ml3){uchar x,k,r;for(k=0;k<80;k++){for(r=0;r<8;r++){x=P2&0XF8; P2=x+r ;if(r==2||r==5) { P0=0XBF; delay(3); }//------秒------- if(r==0) {P0=a[ml1] ;delay(3) ;}if(r==1){P0=a[mh1] ; delay(3) ;}//------fen--------- if(r==3) {P0=a[ml2] ; delay(3) ;}if(r==4){P0=a[mh2] ; delay(3) ;}//-----shi---------if(r==6){P0=a[ml3] ;delay(3) ;}if(r==7){P0=a[mh3] ;delay(3) ;}delay(3);}}}//********DS1302读写程序************ void w(uchar u) //写入1位字节{uchar i;ACC = u;for(i=8; i>0; i--){IO = ACC0;CLK = 1;CLK = 0;ACC = ACC >> 1;}}uchar r(void) //读出1位字节{uchar i;for(i=8; i>0; i--){ACC = ACC >>1;ACC7 = IO;CLK = 1;CLK = 0;}return(ACC);}void W1302(uchar ucAddr, uchar ucDa){RST = 0;CLK = 0;RST = 1;w(ucAddr); // 地址,命令w(ucDa); //写1Byte数据CLK = 1;RST = 0;}void wclock(uchar *p) //写入时钟多字节数据{uchar i;// W1302(0x80,0x00); //停止时钟W1302(0x8e,0x00); // 允许写RST=0;CLK=0;RST=1;w(0xbe); //写多字节命令for(i=8;i>0;i--){w(*p); //按数组指针逐个写入,写入数据在主函数调用时指向b数组p++;}W1302(0x00,0x50); //启动定时器CLK=1;RST=0;}void rclock(uchar *p) //读出时钟多字节数据{uchar i;RST=0;CLK=0;RST=1;w(0xbf);for(i=7;i>0;i--){*p=r();p++;}CLK=1;RST=0;}void main(void){uchar mh,ml,fh,fl,sh,sl,z,v,q,e,y,t,k; wclock(b);while(1){rclock(c);mh=(c[0]&0xf0)>>4;ml=c[0]&0x0f;fh=(c[1]&0xf0)>>4;fl=c[1]&0x0f;sh=(c[2]&0xf0)>>4;sl=c[2]&0x0f;display(mh,ml,fh,fl,sh,sl);if(mh==3&&ml==0) { for(k=0;k<3;k++) {z=(c[3]&0xf0)>>4; v=c[3]&0x0f;q=(c[4]&0xf0)>>4; e=c[4]&0x0f;y=(c[6]&0xf0)>>4; t=c[6]&0x0f; display(z,v,q,e,y,t); } }}}。
ds1302时钟程序详解,ds1302程序流程图(C程序)
ds1302时钟程序详解,ds1302程序流程图(C程序)ds1302时钟程序详解DS1302 的控制字如图2所示。
控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。
数据输入输出(I/O)在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。
同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
DS1302的寄存器DS1302有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式,其日历、时间寄存器及其控制字见表1。
此外,DS1302 还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。
时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。
DS1302与RAM相关的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。
ds1302程序流程图DS1302实时时间流程图4示出DS1302的实时时间流程。
根据此流程框图,不难采集实时时间。
下面结合流程图对DS1302的基本操作进行编程:根据本人在调试中遇到的问题,特作如下说明:DS1302 与微处理器进行数据交换时,首先由微处理器向电路发送命令字节,命令字节最高位MSB(D7)必须为逻辑1,如果D7=0,则禁止写DS1302,即写保护;D6 =0,指定时钟数据,D6=1,指定RAM数据;D5~D1指定输入或输出的特定寄存器;最低位LSB(D0)为逻辑0,指定写操作(输入),D0=1,指定读操作(输出)。
DS1302时钟程序(完整版),液晶显示
#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar table0[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //液晶显示数字0——9代码sbit SCLK=P1^0;sbit DATA=P1^1;sbit CE=P1^2;sbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit FB=P0^7;sbit start=P1^4;sbit stop=P1^5;uchar i;/*******************延时n微秒函数*****************/void delaynus(uchar n) //n us延时函数{// uchar i;for(i=n;i>0;i--);}/*******************写数据函数*****************/void write1302(uchar add,uchar dat){CE=0;SCLK=0;CE=1;for(i=0;i<8;i++) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=0;i<8;i++) //写入数据{DATA=dat&0x01;SCLK=1;SCLK=0;dat>>=1;}SCLK=1;CE=0;}/*******************读数据函数*****************/uchar read1302(uchar add){uchar dat;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=8;i>0;i--) //读出数据/********************为神马???**************************/{dat>>=1;if(DATA==1)dat=dat|0x80;SCLK=1;SCLK=0;}SCLK=1;CE=0;return dat;}/*******************DS1302初始化函数*****************/void init1302(){uchar flag;flag=read1302(0x81);if(flag&0x80){write1302(0x8e,0x00);write1302(0x80,0x00);write1302(0x82,(((1/10)<<4)|(1%10)));write1302(0x84,(((20/10)<<4)|(20%10)));write1302(0x86,(((19/10)<<4)|(19%10)));write1302(0x88,(((7/10)<<4)|(7%10)));write1302(0x8a,((2/10)<<4)|(2%10));write1302(0x8c,(((11/10)<<4)|(11%10)));write1302(0x90,0xa5); //充电。
电子万年历(DS1302)(LCD1602显示)程序
LCD1602_E = 1;//写入时序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
LCD1602_DATAPINS = dat << 4; //写入低四位
Lcd1602_Delay1ms(1);
LCD1602_E = 1;//写入时序
LCD1602_DATAPINS = com;//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
Lcd1602_Delay1ms(1);
LCD1602_E = 1;//写入时序
Lcd1602_Delay1ms(5);
LCD1602_E = 0;
//Lcd1602_Delay1ms(1);
LCD1602_DATAPINS = com << 4; //发送低四位
* 函数功能: 主函数
* 输入 : 无
* 输出: 无
*******************************************************************************/
void main()
{
unsigned char i;
Int0Configuration();
LcdWriteData('-');
LcdWriteData('0'+TIME[4]/16);//月
LcdWriteData('0'+(TIME[4]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[3]/16);//日
DS1302汇编数码管显示8位
/*****************************************电路P1口接74HC573锁存4位数码管位远,P0接4位数码管段选。
P2.5,p2.6,p2.7接DS1302. *****************************************/ORG 0000HAJMP STARTORG 000BHAJMP TIM0SCLK EQU P2^7IO EQU P2^6RST EQU P2^5ALL_FLAG EQU 31H ;标志位SEC EQU 32H ;秒MIN EQU 33H ;分HOUR EQU 34H ;时DAY EQU 35H ;日MON EQU 36H ;月WEEK EQU 37H ;星期YEAR EQU 38H ;年DS_DAT EQU 39HDS_ADD EQU 3AHDS_DATA EQU 3BHS1 EQU r7ORG 70HSTART:MOV TMOD ,#00000001BMOV TH0 ,#HIGH(65536-1000);HIGH和LOW写反了会错MOV TL0 ,#LOW(65536-1000)SETB EASETB ET0SETB TR0LCALL DS_INITLOOP2:CALL DELAYCALL DELAYCALL DELAYCALL DELAYCALL DELAYCALL DELAYLCALL DS_R_TIMEsjmp LOOP2DELAY:MOV R1,#10 ;1ms延时子程序D0: MOV R2,#248DJNZ R2,$DJNZ R1,D0RET/***************************************** DS1302写字节函数*****************************************/ DS_W_BYTE:MOV R0,#08MOV A,DS_DATDS_W1:RRC AMOV IO,CNOPSETB SCLKnopCLR SCLKDJNZ R0,DS_W1RET/***************************************** DS1302读字节函数*****************************************/ DS_R_BYTE:SETB IOMOV A,#00HMOV R0,#08DS_R1:MOV C,IORRC ASETB SCLKNOPCLR SCLKNOPDJNZ R0,DS_R1MOV DS_DA T,ARET/***************************************** DS1302读数据函数入口地址存至DS_ADD;读取到的数据存入DS_DA T *****************************************/ DS_R_DAT:CLR RSTNOPCLR SCLKNOPSETB RSTNOPMOV DS_DA T,DS_ADDLCALL DS_W_BYTELCALL DS_R_BYTESETB SCLKCLR RSTNOPNOPSETB SCLKNOPNOPCLR IONOPNOPsetb IONOPNOPRET/***************************************** DS1302写数据函数入口地址DS_ADD,入口数据DS_DA TA*****************************************/ DS_W_DAT:CLR RSTNOPCLR SCLKNOPSETB RSTNOPMOV DS_DA T,DS_ADDLCALL DS_W_BYTEMOV DS_DA T,DS_DATALCALL DS_W_BYTEMOV DS_DA T,ASETB SCLKCLR RSTNOPNOPSETB SCLKNOPNOP ;加了延时CLR IONOPNOPsetb IONOPNOPRET/*****************************************DS1302读时间函数入口地址DS_ADD,*****************************************/DS_R_TIME:MOV DS_ADD,#81HLCALL DS_R_DATMOV SEC,DS_DATMOV DS_ADD,#83HLCALL DS_R_DATMOV MIN,DS_DATMOV DS_ADD,#85HLCALL DS_R_DATMOV HOUR,DS_DATMOV DS_ADD,#87HLCALL DS_R_DATMOV DAY,DS_DATMOV DS_ADD,#89HLCALL DS_R_DATMOV MON,DS_DATMOV DS_ADD,#8BHLCALL DS_R_DATMOV WEEK,DS_DATMOV DS_ADD,#8DHLCALL DS_R_DATMOV YEAR,DS_DATRET/*****************************************DS1302写时间函数入口地址DS_ADD,入口数据*****************************************/DS_W_TIME:CLR RSTCLR SCLKMOV DS_ADD,#8EH ;语序写MOV DS_DATA,#00HLCALL DS_W_DA TMOV DS_ADD,#80HMOV DS_DATA,SECLCALL DS_W_DA TMOV DS_ADD,#82HMOV DS_DATA,MINLCALL DS_W_DA TMOV DS_ADD,#84HMOV DS_DATA,HOURLCALL DS_W_DA TMOV DS_ADD,#86HMOV DS_DATA,DAYLCALL DS_W_DA TMOV DS_ADD,#88HMOV DS_DATA,MONLCALL DS_W_DA TMOV DS_ADD,#8AHMOV DS_DATA,WEEKLCALL DS_W_DA TMOV DS_ADD,#8CHMOV DS_DATA,YEARLCALL DS_W_DA TMOV DS_ADD,#8EH ;写保护MOV DS_DATA,#80HLCALL DS_W_DA TRET/*****************************************DS1302初始化*****************************************/DS_INIT:CLR RSTCLR SCLKMOV DS_ADD,#8EH ;允许写MOV DS_DATA,#00HLCALL DS_W_DA TMOV DS_ADD,#90HMOV DS_DATA,0xa5LCALL DS_W_DA TMOV DS_ADD,#80HMOV DS_DATA,#00HLCALL DS_W_DA TMOV DS_ADD,#82HMOV DS_DATA,#00HLCALL DS_W_DATMOV DS_ADD,#84HMOV DS_DATA,#23HLCALL DS_W_DA TMOV DS_ADD,#86HMOV DS_DATA,#16HLCALL DS_W_DA TMOV DS_ADD,#88HMOV DS_DATA,#12HLCALL DS_W_DA TMOV DS_ADD,#8aHMOV DS_DATA,#02HLCALL DS_W_DA TMOV DS_ADD,#8cHMOV DS_DATA,#14HLCALL DS_W_DA TMOV DS_ADD,#8EH ;写保护MOV DS_DATA,#80HLCALL DS_W_DA TRETTIM0:PUSH ACCPUSH PSWPUSH DPHPUSH DPLPUSH BMOV TH0 ,#HIGH(65536-1000) MOV TL0 ,#LOW(65536-1000) MOV A ,SECMOV B,#16DIV ABMOV 50H ,BMOV 51H, AMOV A,MINMOV B,#16DIV ABMOV 52H,BMOV 53h,AMOV A,HOURMOV B ,#16DIV ABMOV 54H,BMOV 55H,AINC S1MOV DPTR,#TABMOV P1,#0HCJNE S1,#1H,Z1NOPNOPMOV A ,50HMOVC A,@A+DPTRMOV P0,ASETB P1.0SJMP LOOPZ1:CJNE S1,#02H,Z2MOV A,51H MOVC A,@A+DPTRMOV P0,ASETB P1.1SJMP LOOPZ2:CJNE S1,#03H,Z3MOV P0,#0BFH SETB P1.2SJMP LOOPZ3:CJNE S1,#04H,Z4MOV A,52H MOVC A,@A+DPTRMOV P0,ASETB P1.3SJMP LOOPZ4:CJNE S1,#05H,Z5MOV A,53H MOVC A,@A+DPTRMOV P0,ASETB P1.4SJMP LOOPZ5:CJNE S1,#06H,Z6MOV P0,#0BFHSETB P1.5SJMP LOOPZ6:CJNE S1,#07H,Z7MOV A,54HMOVC A,@A+DPTRMOV P0,ASETB P1.6SJMP LOOPZ7:CJNE S1,#08H,Z8MOV A,55HMOVC A,@A+DPTRMOV P0,ASETB P1.7MOV S1,#0HSJMP LOOPZ8:LJMP 00HLOOP:POP BPOP DPLPOP DPHPOP PSWPOP ACCRETITAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFHEND。
DS1302显示时钟的C程序
#include<reg52.h> //包含单片机寄存器的头文件#include<intrins.h> //包含_nop_()函数定义的头文件#define uint unsigned int#define uchar unsigned charunsigned char code digit[10]={"0123456789"}; //定义字符数组显示数字sbit SCLK=P1^0; //位定义1302芯片的接口,时钟输出端口定义在P1.0引脚sbit DATA=P1^1; //位定义1302芯片的接口,数据输出端定义在P1.1引脚sbit RST=P1^2; //位定义1302芯片的接口,复位端口定义在P1.2引脚/*****************************************************函数功能:延时若干微秒入口参数:n***************************************************/void delay(uint i){ unsigned char j;while(i--){for(j=110;j>0;j--){;}}}/*****************************************************函数功能:向1302写一个字节数据入口参数:x***************************************************/void Write1302(unsigned char dat){unsigned char i;SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备delay(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续写8个二进制位数据{DATA=dat&0x01; //取出dat的第0位数据写入1302 低位在前,高位在后delay(2); //稍微等待,使硬件做好准备SCLK=1; //上升沿写入数据delay(2); //稍微等待,使硬件做好准备SCLK=0; //重新拉低SCLK,形成脉冲dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位}}/*****************************************************函数功能:根据命令字,向1302写一个字节数据入口参数:Cmd,储存命令字;dat,储存待写的数据***************************************************/void WriteSet1302(unsigned char Cmd,unsigned char dat){RST=0; //禁止数据传递SCLK=0; //确保写数居前SCLK被拉低RST=1; //启动数据传输delay(2); //稍微等待,使硬件做好准备Write1302(Cmd); //写入命令字Write1302(dat); //写数据SCLK=1; //将时钟电平置于高电平状态RST=0; //禁止数据传递}/*****************************************************函数功能:从1302读一个字节数据入口参数:x***************************************************/ unsigned char Read1302(void){unsigned char i,dat;delay(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续读8个二进制位数据{ dat>>=1;if(DATA==1) //如果读出的数据是1dat|=0x80; //将1取出,写在dat的最高位SCLK=1; //将SCLK置于高电平,为下降沿读出delay(2); //稍微等待SCLK=0; //拉低SCLK,形成脉冲下降沿delay(2); //稍微等待}return dat; //将读出的数据返回}/*****************************************************函数功能:根据命令字,从1302读取一个字节数据入口参数:Cmd***************************************************/ 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; //将读出的数据返回}/*****************************************************函数功能:1302进行初始化设置***************************************************/void Init_DS1302(void){unsigned char flag;flag= ReadSet1302(0x81);if(flag&0x80) { //判断时钟芯片是否关闭WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值WriteSet1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((18/10)<<4|(18%10))); //根据写日寄存器命令字,写入日的初始值WriteSet1302(0x88,((6/10)<<4|(6%10))); //根据写月寄存器命令字,写入月的初始值WriteSet1302(0x8c,((9/10)<<4|(9%10))); //根据写年寄存器命令字,写入年的初始值WriteSet1302(0x90,0xa5); //打开充电功能选择2K电阻充电方式WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令}}//如果不想每次都初始化时间,也就是掉电后还想让时钟继续走时的话就用上面的语句/*--------------------这是每次都初始化的语句-----------------*//*WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令WriteSet1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值WriteSet1302(0x82,((59/10)<<4|(59%10))); //根据写分寄存器命令字,写入分的初始值WriteSet1302(0x84,((23/10)<<4|(23%10))); //根据写小时寄存器命令字,写入小时的初始值WriteSet1302(0x86,((18/10)<<4|(18%10))); //根据写日寄存器命令字,写入日的初始值WriteSet1302(0x88,((6/10)<<4|(6%10))); //根据写月寄存器命令字,写入月的初始值WriteSet1302(0x8c,((9/10)<<4|(9%10))); //根据写年寄存器命令字,写入年的初始值WriteSet1302(0x90,0xa5); //打开充电功能选择2K电阻充电方式WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令*//****************************************************************************** *以下是对液晶模块的操作程序******************************************************************************* /sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^2; //使能信号位,将E位定义为P2.2引脚sbit BF=P0^7; //忙碌标志位,,将BF位定义为P0.7引脚/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。
DS1302显示时钟程序
#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit k1=P1^0; //开关的位置sbit k2=P1^1;sbit k3=P1^2;sbit k4=P1^3;sbit clk=P3^6; //时钟线sbit en=P3^5; //使能端sbit io=P3^4; //DS1302的IO口sbit lcden=P2^7; //液晶使能端sbit lcdrd=P2^6; //数据命令端sbit lcdwr=P2^5; //读写选择端sbit beep=P2^4; //蜂鸣器位置bit flag; //按键标志位uchar code t[]="LCD LOCK"; //第一行显示字符uchar code b[]="****"; //第二行显示字符uchar c[8] ={0x00}; //定义显示缓冲区uchar d[7] ={0,0,0x12,0,0,0,0}; //DS1302时间缓冲区,存放秒、分、时、日、月、uchar e[2]={0}; //用来存放分钟小时的中间值void delay(uint x) //延时函数{ uint i,j;for(i=0;i<x;i++)for(j=0;j<115;j++); //延时X*MS}void write_com(uchar com) //命令函数{ lcdrd=0; //选择命令端P0=com; //要写的命令送到P0口delay(5);lcden=1; //开启使能端delay(5);lcden=0; //关闭使能端}void write_data(uchar dat) //数据函数{ lcdrd=1; //数据选择端P0=dat;delay(5);lcden=1; //开使能delay(5);lcden=0;}bit busy() //忙碌检查函数{ bit result;lcdrd=0;lcdwr=1;lcden=1;_nop_(); //延时几微秒_nop_();_nop_();_nop_();result=(bit)(P0&0x80);lcden=0;return result;}void lcdclr() //LCD清屏函数{ write_com(0x01); //清零显示,数据指针清零delay(5);}void init() //初始化函数{ delay(15);write_com(0x38); //16*2显示,5*7点阵,8位数据delay(15);write_com(0x38);write_com(0x06); //写一个字符地址指针加1 delay(5);write_com(0x0c); //设置显示,不显示光标delay(5);write_com(0x01); //显示清零,数据指针清零}void write_byte(uchar date) //写一个字节函数{ uchar i;for(i=0;i<8;i++){ clk=0; //低电平改变数据if(date&0x01)io=1;elseio=0;clk=1; //高电平写入1302_nop_();date=date>>1;}}uchar read_byte() //读一个字节函数{uchar i,temp=0;io=1;for(i=0;i<7;i++){clk=0;if(io==1)temp=temp|0x80;elsetemp=temp&0x7f;clk=1; //产生下跳沿temp=temp>>1;}return temp;}void write1302(uchar com,uchar dat) //写1302函数在某个地址写数据{ clk=0;en=1;write_byte(com);write_byte(dat);clk=0;en=0;}uchar read1302(uchar add) //读1302函数,从地址读数据{ uchar d;clk=0;en=1;write_byte(add); //先写地址d=read_byte(); //后读数据clk=0;en=0;return d;}void set1302(uchar add,uchar *p,uchar n) //时间初始化{ write1302(0x80,0x00); //写控制,允许写操作for(;n>0;n--){ write1302(add,*p);p++;add=add+2;}write1302(0x8e,0x80); //写保护,不允许写操作}void get1302(uchar add,uchar *p,uchar n) //读取当前数据{ for(;n>0;n--){ *p=read1302(add);p++;add=add+2;}}void init1302() //初始化1302函数{ en=0;clk=0;write1302(0x80,0x00); //写秒寄存器write1302(0x90,0xab); //写充电器write1302(0x8e,0x80); //写保护,禁止写}void BEEP() //蜂鸣器函数{ beep=0; //响蜂鸣器delay(100); //响0.1sbeep=1;delay(100);}void lcdcon(uchar m1,m2,m3) //将数据转化成适合LCD显示的数据{ c[0]=m1/10+0x30; //小时十位数据c[1]=m1%10+0x30; //小时个位数据c[2]=m2/10+0x30; //分钟十位数据c[3]=m2%10+0x30; //分钟个位数据c[4]=m3/10+0x30; //秒十位c[5]=m3%10+0x30; //秒个位}void lcddis() //LCD显示函数{ write_com(0x44|0x80); //第二行第四列write_data(c[0]); //小时十位write_data(c[1]); //小时个位write_data(':'); //显示:write_data(c[2]); //显示分钟十位write_data(c[3]); //显示分钟个位write_data(':');write_data(c[4]); //显示秒十位write_data(c[5]); //显示秒个位}void keyscan() //按键函数{ uchar fen,shi; //定义两个16位分钟和小时write1302(0x8e,0x00); //1302写保护,允许写write1302(0x80,0x80); //时钟停止运行if(k2==0) //按键2被按下{ d elay(10); //去抖动if(k2==0) //确认被按下{ while(!k2); //等待按键释放BEEP(); //蜂鸣器函数d[2]=d[2]+1; //小时加1if(d[2]==24) //满24清零d[2]=0;shi=d[2]/10*16+d[2]%10; //将小时转化成16进制write1302(0x84,shi); //调整后写入1302}}if(k3==0) //按键3被按下{ delay(10); //抖动if(k3==0) //确认被按下{ while(!k3); //等待按键放开BEEP(); //蜂鸣器函数d[1]=d[1]+1; //分钟加1if(d[1]==60) //满60清零d[1]=0;fen=d[1]/10*16+d[1]%10; //将分钟转化为16进制write1302(0x82,fen); //调整后,写入1302}}if(k4==0) //按键4被按下{ d elay(10); //去抖动if(k4==0) //确认被按下{ while(!k4); //等待按键释放BEEP(); //蜂鸣器函数write1302(0x80,0x00); //调整后,启动时钟运行write1302(0x8e,0x80); //写保护,禁止写flag=0; //按键1标志位清零}}}void gettime() //读取当前时间,转化为10进制{ uchar miao,fen,shi;write1302(0x8e,0x00); //控制命令,0表示允许写write1302(0x90,0xab); //电流控制miao=read1302(0x81); //读取秒fen=read1302(0x83); //读取分shi=read1302(0x85); //读取小时d[0]=miao/16*10+miao%16; //转化为10进制d[1]=fen/16*10+fen%16; //转化为10进制d[2]=shi/16*10+shi%16; //转换为10进制}void main() //主函数{ uchar i;P0=0xff;P2=0xff;init1302(); //1302初始化函数lcdclr(); //1302清屏函数write_com(0x00|0x80); //第一行第0列i=0;while(t[i]!=0){ write_data(t[i]); //第一个字符显示i++;}write_com(0x40|0x80); //第二行显示第0列i=0;while(b[i]!=0);{ write_data(b[i]);i++;}init1302();while(1){ gettime();if(k1==0) //按键1按下{ delay(10); //去抖动if(k1==0) //确认按下{ while(!k1); //等待按键释放BEEP(); //蜂鸣器函数flag=1; //按键1标志位置位,进行时钟调整}}if(flag==1) //如为1,则进行调整keyscan();lcdcon(d[2],d[1],d[0]); //将1302的数据送到函数转换lcddis(); //调整LCD显示,显示小时,分钟,秒}}。
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
/#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit beep=P3^5;sbit ds1302_RST=P2^5;sbit ds1302_IO=P2^6;sbit ds1302_SCLK=P2^7;sbit ACC0=ACC^0;sbit ACC7=ACC^7;void init();void delay_50us(uint t);void display();uchar read_Byte();void write_Byte(uchar tdata);void write_data_ds1302(uchar taddr,uchar tdata);uchar read_data_ds1302(uchar taddr);void set_ds1302(uchar *P1302);void get_ds1302() ;void init_ds1302();uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};uchar initial_time[]={0x00,0x00,0x12};// 秒分时日月周年uchar data now_time[3];/******************************************//* 主函数*//******************************************/void main(){init();init_ds1302();set_ds1302(initial_time);while(1){get_ds1302();display();}}/******************************************/ /* 延时子程序*/ /******************************************/ void delay_50us(uint t){uchar j;for(;t>0;t--)for(j=19;j>0;j--);}/******************************************/ /* 初始化子程序*/ /******************************************/ void init(){P0=0xff;P2=0xff;P1=0x00;}/******************************************/ /* 数码管显示子程序*/ /******************************************/ void display(){uchar i;P1=0x01;i=now_time[0]%16; //显示秒个P0=table[i];delay_50us(20);P1=0x02;i=now_time[0]/16; //显示秒十P0=table[i];delay_50us(20);P1=0x04;P0=table[10];//显示"-"delay_50us(20);P1=0x08;i=now_time[1]%16; //显示分个P0=table[i];delay_50us(20);P1=0x10;i=now_time[1]/16; //显示分十P0=table[i];delay_50us(20);P1=0x20;P0=table[10]; //显示"-"delay_50us(20);P1=0x40;i=now_time[2]%16; //显示时个P0=table[i];delay_50us(20);P1=0x80;i=now_time[2]/16; //显示时十P0=table[i];delay_50us(10);}/*ds1302模块部分*//******************************************//* 读数据*//******************************************/uchar read_Byte(){uchar i;for(i=8;i>0;i--){ACC=ACC>>1;ACC7=ds1302_IO;//由于ds1302读数据的时候,第一个数据读取在发一个Byte命令后,在第八位的下降沿ds1302_SCLK=1;ds1302_SCLK=0;//产生下降沿输出一位数据}return(ACC);}/******************************************//* 写字节*//******************************************/void write_Byte(uchar tdata){uchar i;ACC=tdata;for(i=8;i>0;i--){ds1302_IO=ACC0;ds1302_SCLK=1;ds1302_SCLK=0;//产生上升沿输入数据ACC=ACC>>1;}}/******************************************//* 写数据*//******************************************/void write_data_ds1302(uchar taddr,uchar tdata){ds1302_RST=0;ds1302_SCLK=0;ds1302_RST=1;write_Byte(taddr);write_Byte(tdata);ds1302_RST=0;ds1302_SCLK=1;}/******************************************//* 读数据*//******************************************/uchar read_data_ds1302(uchar taddr){uchar tdata;ds1302_RST=0;ds1302_SCLK=0;ds1302_RST=1;write_Byte(taddr);tdata=read_Byte();ds1302_RST=0;ds1302_SCLK=1;return(tdata);}/******************************************//* 设置初始时间*//******************************************/void set_ds1302(uchar *P1302){uchar i;uchar taddr = 0x80;write_data_ds1302(0x8e,0x00); /* 控制命令,WP=0,写操作*/ for(i =3; i>0; i--){write_data_ds1302(taddr,*P1302); /* 秒分时日月星期年*/P1302++;taddr+=2;}write_data_ds1302(0x8e,0x80); /* 控制命令,WP=1,写保护*/}/*********************************************************************函数名:get_ds1302()*功能描述:设置初始时间*函数说明:先写地址,后读命令/数据*调用函数:*全局变量:*输入:now_time[];*返回:***********************************************************************/void get_ds1302(){uchar k;uchar taddr = 0x81;for (k=0; k<3.; k++){now_time[k] = read_data_ds1302(taddr);/*格式为: 秒分时日月星期年*/taddr+= 2;}}/******************************************//* 1302初始化*//******************************************/void init_ds1302(){ds1302_RST=0;ds1302_SCLK=0;write_data_ds1302(0x8e,0x00);write_data_ds1302(0x90,0xa5);//打开充电二级管一个二级管串联一个2K电阻}。
ds1302显示在12864的c语言程序
dat2 = dat % 10;
dat2 = dat2 + dat1 * 16;
return dat2;
}
//BCD码转换为数据
uchar BCD_Chg_Dat(uchar dat)
{
uchar dat1, dat2;
dat1 = dat / 16;
dat2 = dat % 16;
TSCLK = 1;//拉高时钟总线,产生上升沿数据被DS1302读走
cmd >>=1;//右移一位
}
for(i = 0; i < 8; i++)//每次写1位,写8次
{
TSCLK = 0;//拉低时钟总线
TIO = dat & 0x01; //写1位数据,从最低位开始写
TSCLK = 1;//拉高时钟总线,产生上升沿数据被DS1302读走
{
uchar i;
TRST = 0; //拉低使能端
TSCLK = 0;//拉低数据总线
TRST = 1; //拉高使能端,产生上升沿开始写数据
for(i = 0; i < 8; i++)//每次写1位,写8次
{
TSCLK = 0;//拉低时钟总线
TIO = cmd & 0x01; //写1位数据,从最低位开始写
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define MAIN_Fosc11059200UL//宏定义主时钟HZ
DS1302程序及连接图
/****************************************************************************** ** 标题: 试验数码管显示时钟**** 通过本例程了解DS1302时钟芯片的基本原理和使用,理解并掌握DS1302时钟芯片** 驱动程序的编写以及实现数字字符在数码管中的显示。
** 注意:JP1302跳线冒要短接。
** 请学员认真消化本例程,懂DS1302在C语言中的操作******************************************************************************** */#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:00unsigned 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 char table[]={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的数据。
超详细的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时钟数码管显示
DS1302时钟数码管显示DS1302时钟芯片,大家都知道是什么来的。
不懂的百度下就知道了。
这个只是读取出时间,其它功能没有写出来,用了四位共阳数码管显示。
具体电路和仿真可以到中国电子DIY之家论坛搜索/*********************************** DS1302简单时间显示** 数码管显示************************************/#include#define uchar unsigned char#define uint unsigned int#define W P2 //位选#define D P0 //段选sbit IO=P1^0; //数据口sbit SCLK=P1^1; //控制数据时钟sbit RST=P1^2; //使能端、复位端/************按键引脚定义***********/sbit s1=P1^5; //按键加sbit s2=P1^6; //按键减sbit s3=P1^7; //按键选择char knum=0,snum,fnum;/***********写时分秒地址************/#define write_shi 0x84#define write_fen 0x82#define write_miao 0x80/***********读时分秒地址************/#define read_shi 0x85#define read_fen 0x83#define read_miao 0x81char shi,fen,miao; //读出数据存储变量uchard[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90}; //不带小数点uchardd[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; //带小数点void delay(uint z) //延时函数,z的取值为这个函数的延时ms数,如delay(200);大约延时200ms.{ //delay(500);大约延时500ms.uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}uchar read_1302(uchar add) //读函数{uchar i,date;RST=0; //禁止读写数据for(i=0;i<8;i++){RST=1;SCLK=0;IO=add&0x01;add>>=1;SCLK=1;}for(i=0;i<8;i++){if(IO)date=date|0x80;elsedate=date|0x00;SCLK=1;date>>=1;SCLK=0;}RST=0;date=date/16*10+date%16; //进制转换16转10进制IO=0; //数据读完后,IO口必须为0,不然小时一直显示85 return date;}void write_1302(uchar add,uchar dat) //写函数{uchar i;RST=0; //禁止读写数据// SCLK=0;for(i=0;i<8;i++) //写地址{RST=1; //允许读写数据SCLK=0;IO=add&0x01;add>>=1;SCLK=1;}for(i=0;i<8;i++) //写数据{RST=1; //允许读写数据SCLK=0;IO=dat&0x01;dat>>=1;SCLK=1;}RST=0;}void init_1302() //初始化函数设置时间{write_1302(0x8e,0x00); //保护取消,可以进行读写操作write_1302(write_miao,0x56);write_1302(write_fen,0x49);write_1302(write_shi,0x14);write_1302(0x8e,0x80); //保护启动,不能进行读写操作}void display(uchar shi,uchar fen,uchar miao) //显示函数{if(knum==0){snum=30;fnum=30;}if(knum==1){fnum++;snum=30;}if(knum==2){snum++;fnum=30;}if(snum>=30){W=0x01; //位选D=d[shi/10]; //段选delay(5);D=0XFF; //消隐if(miao%2==0) //小数点闪烁{W=0x02;D=dd[shi%10];delay(5);D=0XFF; //消隐}else{W=0x02;D=d[shi%10];delay(5);D=0XFF; //消?}if(snum==60)snum=0;}if(fnum>=30){W=0x04;D=d[fen/10];delay(5);D=0XFF; //消隐W=0x08;D=d[fen%10];delay(5);D=0XFF; //消隐if(fnum==60)fnum=0;}}void read_sf(){shi=read_1302(read_shi);fen=read_1302(read_fen);miao=read_1302(read_miao);display(shi,fen,miao);}void keyscan() //按键扫描函数{if(s3==0) //选择按键按下{delay(10);if(s3==0){while(!s3)display(shi,fen,miao); //加上这句,按键按下就不会闪knum++; if(knum==1) //分闪烁{write_1302(0x8e,0x00); //保护取消write_1302(write_miao,0x80);}if(knum==3) //时钟启动{knum=0;write_1302(write_miao,0x00);write_1302(0x8e,0x80); //保护启动}}}if(knum==1) //分钟调节{if(s1==0) //加{delay(10);if(s1==0){while(!s1)display(shi,fen,miao); //加上这句,按键按下就不会闪fen++; fen=fen/10*16+fen%10; //转为16进制if(fen==0x60)fen=0x00;write_1302(write_fen,fen); //写入1302read_sf(); //读出时间,然后显示}}if(s2==0){delay(10);if(s2==0){while(!s2)display(shi,fen,miao); //加上这句,按键按下就不会闪fen--; fen=fen/10*16+fen%10; //转为16进制if(fen==-1)fen=0x59;write_1302(write_fen,fen);read_sf();}}}if(knum==2){if(s1==0){delay(10);if(s1==0){while(!s1)display(shi,fen,miao); //加上这句,按键按下就不会闪shi++; shi=shi/10*16+shi%10; //转为16进制if(shi==0x24)shi=0x00;write_1302(write_shi,shi);read_sf();}}if(s2==0){delay(10);if(s2==0){while(!s2)display(shi,fen,miao); //加上这句,按键按下就不会闪shi--;shi=shi/10*16+shi%10; //转为16进制if(shi==-1)shi=0x23;write_1302(write_shi,shi);read_sf();}}}}void main(){// init_1302();while(1){read_sf();keyscan();}}。
(完整版)DS1302数码管显示程序
clock_s1<<=4;
clock_s1=clock_s1|clock_s2;// 10to16
clock_f1=mie/10;
clock_f2=mie%10;
clock_f1=clock_f1&0xff; //全1出1与运算
clock_f2=clock_f2&0xff;
delay(1);P0=0X00;}
if(cant1==5)
cant1=0;
P2=2;
P0=ledmap[10];//显示"-"数组里的0x40
delay(1);
P0=0X00;
if(cant2<=3)
{
P2=3;
P0=ledmap[clock_fs];//分十位
delay(1);
P0=0X00;
P2=4;
if(mie>=60)
{
mie=0;
}
delayAJ(10);
}//以上时钟+设定
}
}
if(down==0)
{
delayAJ(5);//消抖
if(down==0)
{
delayAJ(5);
if(b==1)
{
hour--;
if(hour<0)
{
hour=23;
}
delayAJ(10);
}
if(b==2)
delayAJ(5);
}
while(!set)
{
delayAJ(5);
}
}
if(b!=0)//时分设定
{
if(up==0)
时钟芯片DS1302数码管程序
{
uchar i;
dsclk=0;//清零时钟总线
dsdata=0;//清零数据总线
dsret=0;//片选端无效
dsret=1;//逻辑控制有效,可对1302操作
for(i=16;i>0;i++)
dsclk=1;
}
dsclk=1;//上升沿动作
dsret=0;//片选无效,不可进行操作
}
/*********** 时间显示函数**************/
void show(
{
uchar i;
for(i=0;i<8;i++) // 数码管有8位,因此需要循环8次
{
uchar code tab[8]={0xf7,0xfb,0Xfd,0Xfe,0x7f,0xbf,0xdf,0xef};//数码管显示位选端
uchar buf[8];//申请数据暂存空间
/********** 延时函数************/
void delay(uchar i)
{
while(--i);
address=address>>1;
if(dsdata)
address=address|0x80;
dsclk=1;//上升沿动作
dsclk=1;//等待
}
dsclk=1;//时钟置高
dsret=0;//片选无效
return (address);
}
/*********** 写 ***************/
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/***********************延时程序=a*1ms**************************************/
void delay(uchar a)
{
uchar i;
while(a-- !=0)
{ // led_disp();
for(i=0;i<125;i++);
cant2=0;
clock_ss=hour/ 10; clock_sg=hour%10;
clock_fs=mie/ 10; clock_fg=mie%10;
clock_ms=sei/10; clock_mg=sei%10;
}
if(b==2)
{ cant1=0;
cant2++;
clock_ss=hour/ 10; clock_sg=hour%10;
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
//===以下IO定义请根据您硬件的连接修改===
sbit T_RST=P3^5;//ds1302-5
sbit T_IO=P3^4;//ds1302-6
sbit T_CLK=P3^6;//ds1302-7
clock_fs=mie/ 10; clock_fg=mie%10;
clock_ms=sei/10; clock_mg=sei%10;
}
if(cant1<=3)
{
P2=0;
P0=ledmap[clock_ss];
delay(1);
P0=0X00;
P2=1;
P0=ledmap[clock_sg];//时个位
uchar read_byte(void)
{
uchar i;
for(i=0;i<8;i++)
{
ACC=ACC>>1;
T_CLK = 1;
T_CLK = 0;
ACC7 = T_IO;
}
return(ACC);
}
/******************DS1302:写入数据(先送地址,再写数据)***************************/
mie=clock_fs*10+ clock_fg;
clock_ss=clk_time[2]/ 16; clock_sg=clk_time[2]%16;//BCD*to*10
hour=clock_ss*10+ clock_sg; //用16求商和余进行"高4位"和"低4位"分离
}
if(b==1)
{
cant1++;
while(a--)
{
for(i=0;i<125;i++);
{
led_disp();
}
}
}
void key()
{
uchar clock_s1, clock_s2, clock_f1, clock_f2;
delayAJ(5);
if(set==0)
{
delayAJ(5);//消抖
if(set==0)
{
b++;
write_1302(0x80,0x01);//0x80是写秒数据此处写进"01"秒
write_1302(0x82,clock_f1);//0x82是写分数据
write_1302(0x84,clock_s1);//0x84是写时数据
write_1302(0x8e,0x80); //WP=1写保护
delay(255);
P0=0X00;
P2=7;
P0=ledmap[clock_mg];
delay(1);P0=0X00;
}
/***********************按键延时程序=a*1ms**************************************/
void delayAJ(uchar a)
{
uchar i;
void led_disp()
{ uchar cant1,cant2;
if(b==0)
{
cant1=0;cant2=0;
clock_ms=clk_time[0]/ 16; clock_mg=clk_time[0]%16;
clock_fs=clk_time[1]/ 16; clock_fg=clk_time[1]%16;
{
mie--;
if(mie<0)
{
mie=59;
}
delayAJ(10);
}//以上时钟-设定
}
}
//********************以下是转BCD码的程序DS1302认BCD码
clock_s1=hour/10;
clock_s2=hour%10;
clock_s1=clock_s1&0xff;
clock_f1<<=4;
clock_f1=clock_f1|clock_f2;// 10to16
//*******************************************转BCD码的程序DS1302认BCD码
}
if(b==3)
{
b=0;
write_1302(0x8e,0x00); //WP=0写操作
void write_1302(uchar addr,uchar da)
{
T_RST=0; //停止工作
T_CLK=0;
T_RST=1; //重新工作
write_byte(addr); //写入地址
write_byte(da);
T_RST=0;
T_CLK=1;
}
/******************DS1302:读取数据(先送地址,再读数据)**************************/
clock_s2=clock_s2&0xff;
clock_s1<<=4;
clock_s1=clock_s1|clock_s2;// 10to16
clock_f1=mie/10;
clock_f2=mie%10;
clock_f1=clock_f1&0xff; //全1出1与运算
clock_f2=clock_f2&0xff;
if(mie>=60)
{
mie=0;
}
delayAJ(10);
}//以上时钟+设定
}
}
if(down==0)
{
delayAJ(5);//消抖
if(down==0)
{
delayAJ(5);
if(b==1)
{
hour--;
if(hour<0)
{
hour=23;
}
delayAJ(10);
}
if(b==2)
}
}
/************************主程序**********************************************/
void main(void)
{
uchar temp=0x80;
uchar i;
b=0;
P3=0xff;
while(1)
{
temp=0x81;//读的初始地址
delay(1);P0=0X00;}
if(cant1==5)
cant1=0;
P2=2;
P0=ledmap[10];//显示"-"数组里的0x40
delay(1);
P0=0X00;
if(cant2<=3)
{
P2=3;
P0=ledmap[clock_fs];//分十位
delay(1);
P0=0X00;
P2=4;
}
}
/***********************显示程序**********************************************/
/* DS1302秒,分,时寄存器是BCD码形式:用16求商和余进行"高4位"和"低4位"分离*/
/****************************************************************************/
/************************************************************************/
// huaqinMCU DS1302实验程序数码管显示时钟设置说明
// "8键"为时钟设置、时分切换、保存"0键"为加"4键"为减
/************************************************************************/
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;//累加器A 51单片机原理中有介绍
sbit up=P3^1;
sbit down=P3^2;
sbit set=P3^0;
uchar a,b,clock_ss,clock_sg,clock_fs,clock_fg,clock_ms,clock_mg;
int hour,mie,sei;
uchar clk_time[3]; //秒,分,时寄存器初始值
code uchar ledmap[]={