首页天道酬勤51单片机ds1302数码管时钟,时钟模块和单片机怎么连

51单片机ds1302数码管时钟,时钟模块和单片机怎么连

张世龙 05-12 23:27 59次浏览

DS1302实时时钟具有计算2100年前的秒、分、时、日、日期、星期、月、年的能力和闰年的调整能力。 图1:DS1302针脚图像

其中:

X1、X2:32.768KHz晶振接入引脚。

GND :地。

:复位端子、低电平有效,操作时为高电平。

I/O :数据输入输出端子,具有三态功能。

slk :串行时钟输入端子。

Vcc1 :动作电源端子。

Vcc2 :备用电源端子。 电池断电时提供1302个电源

图2 :控制寄存器

图3 :日历、时钟寄存器

图4:1字节的读取/写入定时

LCD时序图(写命令(RS=L ) :设置显示坐标并写入数据(RS=H ) ) )LCD1602关键性的指令设置

1 .清除指令

功能: 1清除液晶显示屏,将所有DDRAM内容填充到“空白”的ASCII中

代码20H;

2光标返回,将光标撤回到液晶显示器的左上

3将地址计数器(AC )的值设为0。

2 .进入模式设定指令

功能:每次输入1位数据时设定光标的移位方向,另外,设定每次写入时是否移动1个字符。 参数的设定如下。

位名称的设定

I/D 0=写入新数据后,将光标向左移动1=写入新数据后,将光标向右移动

S 0=即使写入新数据显示器也不移动1=即使写入新数据显示器整体也向右

移动一个字符

3 :显示开关控制指令

功能:控制显示器的打开/关闭、光标的显示/关闭以及光标是否闪烁。 参数设定的情况

情况如下。

位名称的设定

D 0=显示功能关闭1=显示功能打开

C 0=无光标1=有光标

B 0=光标闪烁1=光标不闪烁

4 .功能设定命令

功能:设定数据总线的位数、显示的行数、字体。 参数设置如下:

位名称的设定

DL 0=数据总线4位1=数据总线8位

N 0=显示1行1=显示2行

F 0=57点/每个字符1=510点/每个字符

5 :显示字符地址

要显示文字,首先输入要显示文字的地址。 也就是说,它告诉模块字符显示在哪里。 例如,如果第二行中第一个字符的地址为40H,则可以将光标定位在是否直接写入40H

第二行第一个字符的位置是? 这样不行。 这是因为在写入显示地址时需要最高位D7

由于恒定为高一级,因此实际写入的数据应该为01000000b(40h )

10000000b(80h )=11000000 b (c0h )。 1602的话前16个就可以了。 第二行也同样使用前16个地址。

/*显示实验效果:1602时钟,按K3进入时钟设置,按K1选择要设置的时分秒日月,按K2选择将设置加1。 */# includereg 52.h # includeintrins.h # define LCD 1602数据P0 typedefunsignedcharu 8; typedef unsigned int u16; sbit E=P2^7; //设定液晶端口使能信号sbit RW=P2^5; //读写选择读: H/写: Lsbit RS=P2^6; //数据指令选择数据: H/指令: Lsbit key1=P3^1; sbit key2=P3^0; sbit key3=P3^2; sbit SCLK=P3^6; //设置时钟端口sbit IO=P3^4; sbit RST=P3^5; u 16 read [ ]={0x 81,0x 83,0x 85,0x 87,0x 89,0x8b,0x8d}; //秒分时日月周年读寄存器u 16 write [ ]={0x 80,0x 82,0x 84,0x 86,0x 88,0x8a,0x8c}; //秒时分日月周年写入寄存器u 8time [ ]={0x 30,0x 30,0x 22,0x 08,0 x02,0x 05,0x 19 }; //保管初始时间u16 setmark,setplace; //setmark检测是否按下了key3,setplace选择要调整的时间块。 voidDelay_ms(u16n; Void Init配置(; void LCD显示器(; voidlcdwrite _ com (u8数据; voidlcdwrite _ datas (u8数据; 语音液晶屏init (; 语音写入(u8地址,u8数据); u8 readbyte (u8地址; void ds1302init (; void read_time (; void main () { u16 i; init配置(; 初始化液晶屏init (; ds1302init (; wile(1) if ) setmark==0) /时钟正常工作({ read_time; } else//调整时间(if ) key1==0) ) delay_ms ) 1; if(key1==0) )

{ setplace++;//按下key1要调整的时间块加一 setplace%=7;}while(i<50&&key1==0)//等待key1松开 {i++;delay_ms(10); } i=0; } if(key2==0) { delay_ms(1); if(key2==0)//按下key2对应的初始时间加一 { time[setplace]++;if((time[setplace]&0x0f)>9) //换成BCD码。{time[setplace]=time[setplace]+6;}if((time[setplace]>=0x60)&&(setplace<2))//分秒只能到59{time[setplace]=0;}if((time[setplace]>=0x24)&&(setplace==2))//小时只能到23{time[setplace]=0;}if((time[setplace]>=0x32)&&(setplace==3))//日只能到31{time[setplace]=0;}if((time[setplace]>=0x13)&&(setplace==4))//月只能到12{time[setplace]=0;}if((time[setplace]>=0x7)&&(setplace==5))//周只能到7{time[setplace]=1;} } while((i<50)&&(0==key2)) { i++;delay_ms(10); } i=0; } } lcdDisplay(); }}void delay_ms(u16 n) //准确延时一毫秒,晶振12M{u16 a,b;for(;n>0;n--){for(a=199;a>0;a--){for(b=1;b>0;b--){ ;}}}}void initConfiguration() //初始化外部中断0{EA=1;IT0=1;EX0=1;}void init0() interrupt 0//按下key3时间保持不变{ delay_ms(10); if(key3==0) { setmark=~setmark;setplace=0;ds1302init(); }}void lcdDisplay() //显示函数{lcdwrite_com(0x80+0x00);//确定写数据的位置lcdwrite_datas('2');lcdwrite_datas('0');lcdwrite_datas('0'+time[6]/16);//写入年份的高位lcdwrite_datas('0'+(time[6]&0x0f));//低位lcdwrite_datas('-');lcdwrite_datas('0'+time[4]/16);lcdwrite_datas('0'+(time[4]&0x0f)); //里面的小括号很重要lcdwrite_datas('-');lcdwrite_datas('0'+time[3]/16);lcdwrite_datas('0'+(time[3]&0x0f)); lcdwrite_com(0x8c);lcdwrite_datas('0'+(time[5]&0x07));lcdwrite_com(0xc0); //跳线帽sldxss接vcclcdwrite_datas('0'+time[2]/16);lcdwrite_datas('0'+(time[2]&0x0f));lcdwrite_datas('-');lcdwrite_datas('0'+time[1]/16);lcdwrite_datas('0'+(time[1]&0x0f));lcdwrite_datas('-');lcdwrite_datas('0'+time[0]/16); lcdwrite_datas('0'+(time[0]&0x0f));}void lcdwrite_com(u8 datas) //lcd液晶写入指令操作 模拟时序{E=0;RW=0;RS=0;lcd1602data=datas;delay_ms(1);E=1;//delay_ms(1);E=0;}void lcdwrite_datas(u8 datas) //lcd液晶写入数据操作{E=0;RW=0;RS=1;lcd1602data=datas;delay_ms(1); //延时不能太长否则调整不灵敏E=1;//delay_ms(1);E=0;}void lcdinit() //LCD液晶初始化{lcdwrite_com(0x38);//8位总线,显示两行,5x7点阵lcdwrite_com(0x0c);//开显示功能,无关标lcdwrite_com(0x06);//光标右移,即数据依次右移lcdwrite_com(0x01);//清屏lcdwrite_com(0x80);//第一个数据位置}void writebyte(u8 address,u8 datas) //在寄存器里写时间数据,模拟时序{u8 i;RST=0;_nop_();SCLK=0;_nop_();RST=1;_nop_();for(i=0;i<8;i++){IO=address&0x01;address>>=1;SCLK=1;_nop_();SCLK=0;_nop_();}for(i=0;i<8;i++){IO=datas&0x01;datas>>=1;SCLK=1;_nop_();SCLK=0;_nop_();}RST=0;}u8 readbyte(u8 address) //读寄存器里的时间数据{u8 i,datas,dat;RST=0;//_nop_();SCLK=0;//_nop_();RST=1;//_nop_();for(i=0;i<8;i++){IO=address&0x01;address>>=1;SCLK=1;_nop_();SCLK=0;_nop_();}//_nop_();for(i=0;i<8;i++){dat=IO;datas=(datas>>1)|(dat<<7);SCLK=1;_nop_();SCLK=0;_nop_();}RST=0;//_nop_();SCLK=1;//_nop_();IO=0;//_nop_();IO=1;//_nop_();return datas;}void ds1302init() //在寄存器里写入初始时间{u8 i;writebyte(0x8e,0x00); //关闭写保护寄存器for(i=0;i<7;i++){writebyte(write[i],time[i]);}writebyte(0x8e,0x80); //打开写保护寄存器}void read_time() //读取时钟时间 time数组存储{u8 i;for(i=0;i<7;i++){time[i]=readbyte(read[i]);}}

以上是我在学习过程中的一点总结,用的是普中的51单片机·。

51单片机ds1302万年历,stc51单片机使用手册 51单片机可调时钟程序,ds1302与单片机的连接