51单片机对DS1302时钟芯片仿真
DS1302时钟芯片内部含有一个实时时钟/日历和31个字节的静态RAM,实时时钟/日历可以提供2100年之前的年、月、日期、日、时、分、秒等信息,每月的天数和闰年的天数,可以自动调整,时钟操作可以通过AM/PM指示决定采用24小时或12小时格式,内部有31个字节可以供用户访问。 DS1302与单片机之间能简单地采用同步串行方法进行通信,使得管脚数量最少,与单片机通信只需RES(复位线)、I/O(数据线)、SCLK(串行时钟)3根信号线。
#include <reg51.h> #include <intrins.h> //因为要调用nop函数,所以添加了这个库NOP,延时作用 sbit RS=P3^0; //NOP指令本身的含义是空操作,即此时CPU什么也不做,仅仅是等待,直到下一个机器周期的到来。 sbit RW=P3^1; sbit E=P3^2; sbit T_RST=P3^3; sbit T_CLK=P3^4; sbit T_IO=P3^5; unsigned char datechar[]={“DATE:”}; unsigned char timechar[]={“TIME:”}; unsigned char datebuffer[10]={0x32,0x30,0,0,0x2d,0,0,0x2d,0,0};//0x32表示2,0×30表示0,0x2d表示— unsigned char timebuffer[8]={0,0,0x3a,0,0,0x3a,0,0};//0x3a表示: unsigned char weekbuffer={0x30}; void WriteB(unsigned char dat)//单字节写 { unsigned char i; for(i=8; i>0; i–) { T_IO=dat&0x01; T_CLK = 1; T_CLK = 0; dat = dat >> 1; } } unsigned char ReadB(void) //单字节读 { unsigned char i,readdat=0; for(i=8; i>0; i–) { readdat=readdat>>1; if(T_IO) { readdat|=0x80; } T_CLK = 1; T_CLK = 0; } return(readdat); } void W1302(unsigned char address,unsigned char dat) { T_RST = 0; T_CLK = 0; _nop_(); _nop_(); T_RST = 1; _nop_(); _nop_(); WriteB(address); WriteB(dat); T_CLK = 1; T_RST =0; } unsigned char R1302(unsigned char address) { unsigned char dat=0; T_RST = 0; T_CLK = 0; T_RST = 1; WriteB(address); dat = ReadB(); T_CLK = 1; T_RST =0; return(dat); } void delay(unsigned int n)//延时函数 { unsigned i=0,j=0; for(i=0;i<n;i++) { for(j=0;j<120;j++); } } void writedat(unsigned char dat)//写数据函数 { RS=1; // RS:数据/命令选择端 RW=0; // R/W :读/写选择端 E=0; // 使能端:下降沿有效 P2=dat; delay(5); E=1; E=0; } void writecom(unsigned char com)//写命令函数 { RS=0; // RS:数据/命令选择端 RW=0; // R/W :读/写选择端 E=0; //使能端:下降沿有效 P2=com; delay(5); E=1; E=0; } void initlcd()//初始化LCD1602 { writecom(0x38); //0x38;设置16×2显示 writecom(0x0c); //0x0C:设置开显示,不显示光标 writecom(0x06); //0x06:写一个字符后地址指针加1 writecom(0x01); //0x01:显示清0,数据指针清0 } void display()//显示函数 { int i=0,temp=0; temp=R1302(0x8d); //读年 datebuffer[2]=0x30+temp/16; datebuffer[3]=0x30+temp%16; temp=R1302(0x8b); //读星期 weekbuffer=0x30+temp; temp=R1302(0x89); //读月 datebuffer[5]=0x30+temp/16; datebuffer[6]=0x30+temp%16; temp=R1302(0x87); //读日 datebuffer[8]=0x30+temp/16; datebuffer[9]=0x30+temp%16; temp=R1302(0x85); //读时 temp=temp&0x7f; timebuffer[0]=0x30+temp/16; timebuffer[1]=0x30+temp%16; temp=R1302(0x83); //读分 timebuffer[3]=0x30+temp/16; timebuffer[4]=0x30+temp%16; temp=R1302(0x81); //读秒 temp=temp&0x7f; timebuffer[6]=0x30+temp/16; timebuffer[7]=0x30+temp%16; writecom(0x80); //0x80:LCD第一行的起始地址 for(i=0;i<5;i++) { writedat(datechar[i]); } writecom(0xc0); for(i=0;i<5;i++) { writedat(timechar[i]); } writecom(0x86);//显示日历 for(i=0;i<10;i++) { writedat(datebuffer[i]); } writecom(0xc6);//显示时间 for(i=0;i<8;i++) { writedat(timebuffer[i]); } writedat(‘ ‘); writedat(weekbuffer);//显示星期 } void main() { initlcd(); W1302(0x8e,0); //打开写保护 W1302(0x8c,0x20);//打开年,BCD码 W1302(0x8a,0x01);//写入星期 W1302(0x88,0x04);//写入月 W1302(0x86,0x27);//写入日 W1302(0x84,0x18);//写入时 W1302(0x82,0x44);//写入分 W1302(0x80,0x30);//写入秒 W1302(0x8e,0x80);//关闭写保护 while(1) { display(); } }
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/31236.html