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应用刚学单片机,好多好奇,所以想做个简单的时钟。
下面是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时钟显示程序

write_data(table1[num]);
}
/**************************显示欢迎界面函数*************************************/
void displaystar(void)
delay(500);大约延时500ms
**************************************************************/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void delay20ms(void) //3*i*j+2*i=3*100*60+2*100=20000μs=20ms;
{
uchar i;
write_com(0x80);
for(i=0;i<16;i++)
write_data(table2[i]);
write_com(0x80+0x40);
for(i=0;i<16;i++)
write_data(table3[i]);
}
/***************************显示时间、日期子函数*********************************/
if(s1num!=0&&s4num==0)//按键1按下*次且s4再次之前未曾按过(按键按下时,时间修改函数)
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可调时钟+DS18B20温度数码管切换显示

DS1302可调时钟+DS18B20温度数码管切换显示(2013-01-04 15:30:28)转载▼标签:校园#include#include#define uchar unsigned char#define uint unsigned int#define Write_Protect 0x8e //写保护#define OutPut P2 //显示输出sbit DQ=P1^7; //ds18b20单总线定义为P1.7sbit Beep=P3^2; //蜂鸣器输出端定义为P3.2sbit RST=P1^2; //复位端口定义在P1.2引脚sbit IO=P1^1; //数据输出端定义在P1.1引脚sbit SCLK=P1^0; //时钟输出端口定义在P1.0引脚sbit key=P1^3; //时间调节控制键sbit key1=P1^5; //每按一次位加一sbit key2=P1^4; //每按一次位减一sbit key3=P1^6; //显示切换uchar data disdata[5];uint tvalue;//温度值uchar tflag;//温度正负标志uchar code Wei[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; //位选数据uchar code Duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0--9共阴代码code uchar Waddr[]={0x80,0x82,0x84,0x86,0x88,0x8c,0x8a};code uchar Raddr[]={0x81,0x83,0x85,0x87,0x89,0x8d,0x8b};uchar timeset[]={0x01,0x02,0x03,0x04,0x05,0x00,0x01};uchar time_buf[7];uchar time_disp[7];uchar dispdat[8];uchar Btdis=0,k=0,z;bit btx,btx1,btx2,btx3,bt1,bt2,bt3;bit Btread;void ex_model(); //显示模式切换void delaynms(uchar n){uchar i,j;for(i=n;i>0;i--)for(j=125;j>0;j--);}void Ds1302_Write_Byte(unsigned char addr, unsigned char d){unsigned char i;RST=1;//写入目标地址:addraddr = addr & 0xFE; //最低位置零for (i = 0; i < 8; i++){if (addr & 0x01){IO=1;}else{IO=0;}SCLK=1;SCLK=0;addr = addr >> 1; }//写入数据:dfor (i = 0; i < 8; i++){if (d & 0x01){IO=1;}else{IO=0;}SCLK=1;SCLK=0;d = d >> 1;}RST=0; //停止DS1302总线}uchar Ds1302_Read_Byte(unsigned char addr){unsigned char i;unsigned char temp;RST=1;//写入目标地址:addraddr = addr | 0x01; //最低位置高for (i = 0; i < 8; i ++){if (addr & 0x01)IO=1;}else{IO=0;}SCLK=1;SCLK=0;addr = addr >> 1;}//输出数据:tempfor (i = 0; i < 8; i++){temp = temp >> 1;if (IO){temp |= 0x80;}else{temp &= 0x7F;SCLK=1;SCLK=0;}RST=0; //停止DS1302总线return temp;}void Write1302(uchar dat){uchar i;SCLK=0;for(i=0;i<8;i++){IO=dat&0x01;SCLK=1;SCLK=0;dat=dat>>1;}}uchar Readset1302(uchar Cmd){uchar dat;SCLK=0;RST=1;Write1302(Cmd);SCLK=1;RST=0;return dat;}void Ds1302_Write_Time(void){unsigned char i,tmp;uchar flag;flag=Readset1302(0x81);if(flag&0x80) //判断时钟芯片是否停止,为1时时钟停止{//掉电保存for(i=0;i<7;i++) //BCD 处理{tmp=timeset[i]/10;//timeset[]={0x01,0x02,0x03,0x04,0x05,0x06,0x01}time_buf[i]=timeset[i]; //time_buf[7]time_buf[i]=time_buf[i]+tmp*16;}Ds1302_Write_Byte(0x8e,0x00); //关闭写保护Ds1302_Write_Byte(Waddr[6],time_buf[6]); //周Ds1302_Write_Byte(Waddr[5],time_buf[0]); //年Ds1302_Write_Byte(Waddr[4],time_buf[1]); //月Ds1302_Write_Byte(Waddr[3],time_buf[2]); //日Ds1302_Write_Byte(Waddr[2],time_buf[3]); //时Ds1302_Write_Byte(Waddr[1],time_buf[4]); //分Ds1302_Write_Byte(Waddr[0],time_buf[5]); //秒Ds1302_Write_Byte(0x8e,0x80); //打开写保护}}void Ds1302_Read_Time(void){unsigned char i,tmp;// Ds1302_Write_Byte(0x8e,0x00); //关闭写保护time_buf[0]=Ds1302_Read_Byte(Raddr[5]); //年time_buf[1]=Ds1302_Read_Byte(Raddr[4]); //月time_buf[2]=Ds1302_Read_Byte(Raddr[3]); //日time_buf[3]=Ds1302_Read_Byte(Raddr[2]); //时time_buf[4]=Ds1302_Read_Byte(Raddr[1]); //分time_buf[5]=(Ds1302_Read_Byte(Raddr[0]))&0x7F; //秒time_buf[6]=Ds1302_Read_Byte(Raddr[6]); //周// Ds1302_Write_Byte(0x8e,0x80); //打开写保护for(i=0;i<8;i++) //BCD 处理{tmp=time_buf[i]/16;//time_buf[]={年,月,日,时,分,秒,周}time_buf[i]=time_buf[i];time_disp[i]=time_buf[i]+tmp*10;}}void Ds1302_Init(void){RST=0;//RST脚置低SCLK=0;//SCK脚置低Ds1302_Write_Byte(0x80,0x00);}void display(){uchar i;if(Btdis==0){if(bt2==0){dispdat[0]=Duan[time_disp[3]/10]; //时dispdat[1]=Duan[time_disp[3]];}else{dispdat[0]=0xff;dispdat[1]=0xff;}dispdat[2]=0xbf; //"-"if(bt3==0){dispdat[3]=Duan[time_disp[4]/10]; //分dispdat[4]=Duan[time_disp[4]];}else{dispdat[3]=0xff;dispdat[4]=0xff;}dispdat[5]=0xbf;dispdat[6]=Duan[time_disp[5]/10]; //秒dispdat[7]=Duan[time_disp[5]];}if(Btdis==1){if(bt1==0){dispdat[0]=Duan[time_disp[0]/10]; //年dispdat[1]=Duan[time_disp[0]];}else{dispdat[0]=0xff;dispdat[1]=0xff;}dispdat[2]=0xbf; //"-"if(bt2==0){dispdat[3]=Duan[time_disp[1]/10]; //月dispdat[4]=Duan[time_disp[1]];}else{dispdat[3]=0xff;dispdat[4]=0xff;}dispdat[5]=0xbf;if(bt3==0){dispdat[6]=Duan[time_disp[2]/10]; //日dispdat[7]=Duan[time_disp[2]];}else{dispdat[6]=0xff;dispdat[7]=0xff;}}if(Btdis==2){dispdat[0]=0xff;if(bt1==0){dispdat[1]=Duan[time_disp[6]]; //周}else{dispdat[1]=0xff;}dispdat[2]=0xbf; //"-" dispdat[3]=0xbf;dispdat[4]=0xbf;dispdat[5]=0xbf;dispdat[6]=Duan[time_disp[5]/10];dispdat[7]=Duan[time_disp[5]];}if(Btdis==3){ds1820disp();}for(i=0;i<8;i++){P0=dispdat[i];OutPut=Wei[i]; //Wei[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}delaynms(1);P0=0xff;}}void baoshi(){ uchar i;if(((time_disp[4])==59)&&((time_disp[5])>=55)&&((time_disp[5])<=60))//分和秒的报时条件{for(i=0;i<8;i++) //小灯轮流点亮,蜂鸣器发出滴答声{P3=Duan[i];delaynms(300);}}elseP3=0xdb;}void keyscan(){display();if(!key){if(btx==0){if(!key){btx=1;k++;}while(k==1){Btdis=1;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}else{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[0]<99){time_disp[0]++;}else{time_disp[0]=0;}}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[0]>0){time_disp[0]--;}else{time_disp[0]=99;}}}}else{btx2=0;}}while(k==2){Btdis=1;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}else{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[1]<12){time_disp[1]++;if(time_disp[1]==2){if(time_disp[0]%4==0){if(time_disp[2]>29){time_disp[2]=29;}}else if(time_disp[2]>28){time_disp[2]=28;}}}else{time_disp[1]=1;}}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[1]>1){time_disp[1]--;if(time_disp[1]==2){if(time_disp[0]%4==0){if(time_disp[2]>29){time_disp[2]=29;}}else if(time_disp[2]>28){time_disp[2]=28;}}}else{time_disp[1]=12;}}}}else{btx2=0;}}while(k==3){Btdis=1;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}else{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[1]==2){if(time_disp[0]%4==0){if(time_disp[2]<29){time_disp[2]++;}else{time_disp[2]=1;}}else if(time_disp[2]<28){time_disp[2]++;}else{time_disp[2]=1;}}else if(time_disp[1]<8){if(time_disp[1]%2==0) //小于8月的月份除以2的余数为0则为小月{if(time_disp[2]<30){time_disp[2]++;}else{time_disp[2]=1;}}else if(time_disp[1]%2==1) //小于8月的月份除以2的余数为1则为大月{if(time_disp[2]<31){time_disp[2]++;}else{time_disp[2]=1;}}}else if(time_disp[1]>7){if(time_disp[1]%2==0){if(time_disp[2]<31){time_disp[2]++;}else{time_disp[2]=1;}}else if(time_disp[1]%2==1){if(time_disp[2]<30){time_disp[2]++;}else{time_disp[2]=1;}}}}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[1]==2){if(time_disp[0]%4==0){if(time_disp[2]>1){time_disp[2]--;}{time_disp[2]=29;}}else if(time_disp[2]>1){time_disp[2]--;}else{time_disp[2]=28;}}else if(time_disp[1]<8){if(time_disp[1]%2==0){if(time_disp[2]>1){time_disp[2]--;}{time_disp[2]=30;}}else if(time_disp[1]%2==1){if(time_disp[2]>1){time_disp[2]--;}else{time_disp[2]=31;}}}else if(time_disp[1]>7){if(time_disp[1]%2==0){if(time_disp[2]>1)time_disp[2]--;}else{time_disp[2]=31;}}else if(time_disp[1]%2==1){if(time_disp[2]>1){time_disp[2]--;}else{time_disp[2]=30;}}}}}else{btx2=0;}}while(k==4){Btdis=2;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[6]<7){time_disp[6]++;}else{time_disp[6]=1;}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[6]>1){time_disp[6]--;}else{time_disp[6]=7;}}}}else{btx2=0;}}while(k==5){Btdis=0;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[3]<23){time_disp[3]++;}else{time_disp[3]=0;}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[3]>0){time_disp[3]--;}else{time_disp[3]=23;}}}}else{btx2=0;}}while(k==6){Btdis=0;display();if(!key){if(btx==0){if(!key){btx=1;k++;}}}{btx=0;}if(!key1){if(btx1==0){if(!key1){btx1=1;if(time_disp[4]<59){time_disp[4]++;}else{time_disp[4]=0;}}}else{btx1=0;}if(!key2){if(btx2==0){if(!key2){btx2=1;if(time_disp[4]>0){time_disp[4]--;}else{time_disp[4]=59;}}}}else{btx2=0;}}while(k==7){uchar tmp;uchar i;for(i=0;i<7;i++){timeset[i]=time_disp[i];}//将调整后的时候写入DS1302for(i=0;i<7;i++) //BCD 处理{tmp=timeset[i]/10;//timeset[]={0x01,0x02,0x03,0x04,0x05,0x06,0x01}time_buf[i]=timeset[i]; //time_buf[7]time_buf[i]=time_buf[i]+tmp*16;}Ds1302_Write_Byte(0x8e,0x00); //关闭写保护Ds1302_Write_Byte(Waddr[6],time_buf[6]); //周Ds1302_Write_Byte(Waddr[5],time_buf[0]); //年Ds1302_Write_Byte(Waddr[4],time_buf[1]); //月Ds1302_Write_Byte(Waddr[3],time_buf[2]); //日Ds1302_Write_Byte(Waddr[2],time_buf[3]); //时Ds1302_Write_Byte(Waddr[1],time_buf[4]); //分Ds1302_Write_Byte(Waddr[0],time_buf[5]); //秒Ds1302_Write_Byte(0x8e,0x80); //打开写保护k=0;}}else{btx=0;}if(!key3){if(btx3==0){if(!key3){btx3=1;if(Btdis<3){Btdis++;}else{Btdis=0;}}}}else{btx3=0;}}void ex_model(){if(((time_disp[5])>=0)&&((time_disp[5])<=8)) //前八秒显示温度Btdis=3;if(((time_disp[5])>=9)&&((time_disp[5])<=12)) //显示周Btdis=2;if(((time_disp[5])>=13)&&((time_disp[5])<=18)) //显示年Btdis=1;if(((time_disp[5])>=19)&&((time_disp[5])<=59)) //显示当前时间Btdis=0;}void tiaoshidisplay(){if(z==15){z=0;switch(k){case 1:bt1=~bt1;P3=~P3;break; //年case 2:bt2=~bt2;bt1=0;P3=~P3;break; //月case 3:bt3=~bt3;bt2=0;P3=~P3;break; //日case 4:bt1=~bt1;bt3=0;P3=~P3;break; //周case 5:bt2=~bt2;bt1=0;P3=~P3;break; //时case 6:bt3=~bt3;bt2=0;P3=~P3;break; //分default:bt3=0;break;}}}void delay_18B20(unsigned int i)//延时1微秒{while(i--);}void ds1820rst(){ unsigned char x=0;DQ = 1; //DQ复位delay_18B20(4); //延时DQ = 0; //DQ拉低delay_18B20(100); //精确延时大于480usDQ = 1; //拉高delay_18B20(40);}uchar ds1820rd(){ unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i--){ DQ = 0; //给脉冲信号dat>>=1;DQ = 1; //给脉冲信号if(DQ)dat|=0x80;delay_18B20(10);}return(dat);}void ds1820wr(uchar wdata){unsigned char i=0;for (i=8; i>0; i--) { DQ = 0;DQ = wdata&0x01;delay_18B20(10);DQ = 1;wdata>>=1;}}read_temp(){uchar a,b;ds1820rst();ds1820wr(0xcc);/ds1820wr(0x44);/ds1820rst();ds1820wr(0xcc);/ds1820wr(0xbe);/a=ds1820rd();。
DS1302驱动程序详解1

DS1302驱动程序详解DS1302引脚介绍特性介绍驱动程序详解sbit IO=P1^0; //DS1302数据线sbit SCLK=P1^1; //DS1302时钟线sbit RST=P1^2; //DS1302复位线uchar WEEK[][4]={"SUN","***","MON","TUS","WEN","THU","FRI","SAT"}; //亦可定义成指针数组*WEEK[]uchar LCD_DSY_BUFFER1[]={"DA TE 00-00-00 "};uchar LCD_DSY_BUFFER2[]={"TIME 00:00:00 "};uchar DateTime[7];void Initialize_LCD();void Display_LCD_String(uchar p,uchar *s);void DelayMS(uint ms);//------------------------------------------------------------------//向DS1302写入一个字节//------------------------------------------------------------------void Write_A_Byte_TO_DS1302(uchar x){uchar i;SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备for (i=0;i<8;i++){IO=x & 0x01; //取出x的第0位数据写入1302SCLK=1; //上升沿写入数据SCLK=0; //重新拉低SCLK,形成脉冲x >>=1; //将x的各数据位右移1位,准备写入下一个数据位}}//------------------------------------------------------------------//从DS1302读取一个字节,//注意:DS1302中所存放的数据是BCD码,在读写时要注意转换////------------------------------------------------------------------uchar Get_A_Byte_FROM_DS1302(){uchar i,b=0x00;for (i=0;i<8;i++){b |= _crol_((uchar)IO,i);//将uchar类型的IO数据左移i位SCLK=1; //将SCLK置于高电平,为下降沿读出SCLK=0; //时钟下降沿读取}return (b/16)*10+b%16; //将BCD码转换为十进制数}//------------------------------------------------------------------//从DS1302指定位置读取数据//------------------------------------------------------------------ uchar Read_Data(uchar addr){uchar dat;RST=0; //拉低RSTSCLK=0; //确保写数据前SCLK被拉低RST=1; //启动数据传输Write_A_Byte_TO_DS1302(addr); //写入命令字dat=Get_A_Byte_FROM_DS1302();SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递return dat;}//------------------------------------------------------------------//读取当前日期时间//------------------------------------------------------------------ void GetTime(){uchar i,addr =0x81;for (i=0;i<7;i++){DateTime[i] = Read_Data(addr);addr+=2;}}//------------------------------------------------------------------//日期与时间值转换为数字字符//------------------------------------------------------------------ void Format_DataTime(uchar d,uchar *a){a[0]=d/10+'0';a[1]=d%10+'0';}//------------------------------------------------------------------//主程序//------------------------------------------------------------------ void main(){Initialize_LCD();while(1){GetTime();Format_DataTime(DateTime[6],LCD_DSY_BUFFER1+5); //0x8D 年份寄存器Format_DataTime(DateTime[4],LCD_DSY_BUFFER1+8); //0x89 月份寄存器Format_DataTime(DateTime[3],LCD_DSY_BUFFER1+11); //0x87 日期寄存器//星期strcpy (LCD_DSY_BUFFER1+13,WEEK[DateTime[5]]);//将字符串WEEK[DateTime[5]]复制到字符数组LCD_DSY_BUFFER1+13中//0x8B 周日寄存器Format_DataTime(DateTime[2],LCD_DSY_BUFFER2+5); //0x85 小时寄存器Format_DataTime(DateTime[1],LCD_DSY_BUFFER2+8); //0x83 分钟寄存器Format_DataTime(DateTime[0],LCD_DSY_BUFFER2+11); //0x81 秒寄存器Display_LCD_String(0x00,LCD_DSY_BUFFER1); //第一行显示年、月、日、星期几Display_LCD_String(0x40,LCD_DSY_BUFFER2); //第二行显示小时、分钟、秒}}。
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显示时间

}
setds1302();//设置时间初值,
while(1)
{
getds1302();//循环显示时间
ledbuf[0]=ledmap[timebuf[0]%16];//显示秒个位
ledbuf[1]=ledmap[timebuf[0]/16];//显示秒十位
ledbuf[2]=ledmap[timebuf[1]%16]&0x7f;//显示分个位,并显示小数点
ledbuf[3]=ledmap[timebuf[1]/16];//显示分十位
ledbuf[4]=ledmap[timebuf[2]%16]&0x7f;//显示小时个位,并显示小数点
ledbuf[5]=ledmap[timebuf[2]/16];//显示小时十位
disp();//调数码管上显示时间程序
void delay(unsigned int z)
{
unsigned char i;
while(z--)//显示要用的延时程序
for(i=110;i>0;i--);
}
void writebyte(unsigned char date)
{
unsigned char j;
//1302写子程序
for(j=0;j<8;j++)
_nop_();
dat=1;
_nop_();
_nop_();
return date;
}
addr,unsigned char date)
{ ce=0;
_nop_();
clk=0;
_nop_();
ce=1;
_nop_();//1302写某个地址数据子程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/************************************************************************/ // huaqinMCU DS1302 实验程序数码管显示时钟设置说明// "8键"为时钟设置、时分切换、保存"0键"为加"4键"为减/************************************************************************/ #include <reg52.h>#define uchar unsigned char#define uint unsigned int//===以下IO定义请根据您硬件的连接修改===sbit T_RST=P3^5;//ds1302-5sbit T_IO=P3^4;//ds1302-6sbit T_CLK=P3^6;//ds1302-7sbit 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[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//数码管段码/******************DS1302:写入操作(上升沿)*********************/void write_byte(uchar da){uchar i;ACC=da;for(i=8;i>0;i--){T_IO=ACC0;T_CLK=0;T_CLK=1;ACC=ACC>>1;}}/******************DS1302:读取操作(下降沿)*****************/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:写入数据(先送地址,再写数据)***************************/ 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:读取数据(先送地址,再读数据)**************************/ uchar read_1302(uchar addr){uchar temp;T_RST=0; //停止工作T_CLK=0;T_RST=1; //重新工作write_byte(addr); //写入地址temp=read_byte();T_RST=0;T_CLK=1; //停止工作return(temp);}/***********************延时程序=a*1ms**************************************/void delay(uchar a){uchar i;while(a-- !=0){ // led_disp();for(i=0;i<125;i++);}}/***********************显示程序**********************************************//* DS1302秒,分,时寄存器是BCD码形式:用16求商和余进行"高4位"和"低4位"分离*/ /****************************************************************************/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=clock_fs*10+ clock_fg;clock_ss=clk_time[2]/ 16; clock_sg=clk_time[2]%16;//BCD*to*10hour=clock_ss*10+ clock_sg; //用16求商和余进行"高4位"和"低4位"分离}if(b==1){cant1++;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;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];//时个位delay(1);P0=0X00;}if(cant1==5)cant1=0;P2=2;P0=ledmap[10];//显示"-"数组里的0x40delay(1);P0=0X00;if(cant2<=3){P2=3;P0=ledmap[clock_fs];//分十位delay(1);P0=0X00;P2=4;P0=ledmap[clock_fg];//时个位delay(1);P0=0X00;}if(cant2==5)cant2=0;P2=5;P0=ledmap[10];//显示"-"数组里的0x40delay(1);P0=0X00;P2=6;P0=ledmap[clock_ms];//秒十位delay(1);P0=0X00;P2=7;P0=ledmap[clock_mg];delay(1);P0=0X00;}/***********************按键延时程序=a*1ms**************************************/ void delayAJ(uchar a){uchar i;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++;delayAJ(5);}while(!set){delayAJ(5);}}if(b!=0)//时分设定{if(up==0){delayAJ(5);//消抖if(up==0){if(b==1){hour++;if(hour>=24){hour=0;}delayAJ(10);}if(b==2){mie++;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){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_s2=clock_s2&0xff;clock_s1<<=4;clock_s1=clock_s1|clock_s2;// 10to16clock_f1=mie/10;clock_f2=mie%10;clock_f1=clock_f1&0xff; //全1出1 与运算clock_f2=clock_f2&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 写操作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);}}/************************主程序**********************************************/ void main(void){uchar temp=0x80;uchar i;b=0;P3=0xff;while(1){temp=0x81;//读的初始地址for(i=0;i<3;i++)//分别把秒分时数据读出分3次读好一次地址加2" temp+=2;"{clk_time[i]=read_1302(temp);temp+=2;}key();//键盘扫描}}。