网上的DS1302与1602搭配的程序很多都有很大问题。我写个全的,而且写得很细,让大家看看好了解,端口自己修改即可
#include#include /*********************************端口定义**********************************/ sbit sclk = P3^4; sbit io= P3^3; sbit rst= P3^5; sbit rs=P1^0; sbit en=P1^2; sbit rw=P1^1; #define uchar unsigned char #define uint unsigned int uchar flag,second,minute,hour,week,day,month,year;//秒、分、时、星期、日、月、年 void delay(uint z) //延时子程序 { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void delayus() { _nop_(); _nop_(); _nop_(); _nop_(); } void write_1602dat(uchar dat)//定义一个带参数的写数据子程序 { rs=1; //1602的rs为0时,接收命令,为1时接收数据 P0=dat;//把void write_shu(uchar shu)中的COM中的数据给P0口 delay(5); en=1; delay(5); en=0; delay(5); } void write_1602com(uchar com)//定义一个带参数的写命令子程序 { rs=0; //1602的rs为0时,接收命令,为1时接收数据 P0=com;//把void write_com(uchar com)中的COM中的数据给P0口 delay(5); en=1; delay(5); en=0; delay(5); } void Write1602(uchar add,uchar dat) { write_1602com(add); write_1602dat(dat); } void init1602()//定义一个初始化子程序 { en=0; rw=0; write_1602com(0x38);//调用 write_com子程序并把0x38赋给P0口,显示模式打开 write_1602com(0x0e);//调用 write_com子程序并把“开显示,显示光标,光标闪烁”指令码赋给P0口 write_1602com(0x06);//调用 write_com子程序并把“地址指针加1,整屏不移动”指令码赋给P0口 //write_com(0x80+0x10);//数据指针初始化,让指针指向可显示的最右端 write_1602com(0x80);//数据指针初始化,让指针指向最左端,显示从第一行开始 write_1602com(0x01);//调用 write_com子程序并把"清零指"令码赋给P0口 Write1602(0x80,'2'); Write1602(0x81,'0'); Write1602(0x80+4,'-'); Write1602(0x80+7,'-'); Write1602(0x80+0x40+5,':'); Write1602(0x80+0x40+8,':'); } /********************写一个字节**************/ void write_1302byte(dat) { uchar i; sclk=0; delayus(); for(i=8;i>0;i--) { io=dat&0x01;//只要是从低位取数,向高位一定要和0X01与 delayus(); sclk=1;//为写数据制造上升沿。 delayus(); sclk=0;//为下一次上升沿写下一个字节做准备 dat>>=1;//将数据向左移一位,准备写入下一个数据 } } /********************读一个字节***************/ uchar read_1302byte() { uchar i,dat; delayus(); for(i=8;i>0;i--) { dat>>=1; if(io==1) { dat|=0x80;//将1取出,写在dat的最高位。 } sclk=1;//把sclk拉高,为读一个字节的下降沿做准备 delayus;//稍等制造一个高电平 sclk=0;//为读一个字节制造下降沿 delayus; } return dat; } /*************写入一个时间位*****************/ void write_1302(uchar add,uchar dat) { rst=0; delayus(); sclk=0; delayus(); rst=1; write_1302byte(add); delayus(); write_1302byte(dat); delayus(); rst=0; } /****************读1302的地址******************/ uchar read_1302add(uchar add) { uchar timedat; rst=0; _nop_(); sclk=0; _nop_(); rst=1; write_1302byte(add);//写入要读的地址 timedat=read_1302byte();//将上面地址中的数据赋给timedat sclk=1; _nop_(); rst=0; return timedat; } /****************初始化1302*********************/ void init_1302() { flag=read_1302add(0x81);//读秒寄存器的最高位,读出时钟状态 if(flag&0x80)//判断时钟是否关闭,若内部关闭,则初始,若没关闭,不初始化,还在走 { write_1302(0x8e,0x00);//去除写保护 write_1302(0x80,((55/10)<<4|(55%10)));//写秒寄存器,并写入初值55 write_1302(0x82,((59/10)<<4|(55%10)));//写分寄存器,并写入初值59 write_1302(0x84,((22/10)<<4|(22%10)));//写小时寄存器,并写入初值23 write_1302(0x86,((24/10)<<4|(24%10)));//写日寄存器,并写入初值18 write_1302(0x88,((2/10)<<4|(2%10)));//写月寄存器,并写入初值2 write_1302(0x8a,((5/10)<<4|(5%10)));//写周寄存器,并写入初值5 write_1302(0x8c,((12/10)<<4|(12%10)));//写年寄存器,并写入初值12,不能写2012年 write_1302(0x90,0xa5);//写充电方式 write_1302(0x8e,0x80);//加上写保护 } }[page] /*****************读出秒的十进制数***************************/ uchar readsecond(uchar dat) { dat=read_1302add(0x81); second=((dat&0x70)>>4)*10+(dat&0x0f); return second; } /*****************读出分的十进制数***************************/ uchar readminute(uchar dat) { dat=read_1302add(0x83); minute=((dat&0x70)>>4)*10+(dat&0x0f); return minute; } /*****************读出小时的十进制数***************************/ uchar readhour(uchar dat) { dat=read_1302add(0x85); hour=((dat&0x70)>>4)*10+(dat&0x0f); return hour; } /*****************读出天的十进制数***************************/ uchar readday(uchar dat) { dat=read_1302add(0x87); day=((dat&0x70)>>4)*10+(dat&0x0f); return day; } /*****************读出月的十进制数***************************/ uchar readmonth(uchar dat) { dat=read_1302add(0x89); month=((dat&0x70)>>4)*10+(dat&0x0f); return month; } /*****************读出周的十进制数***************************/ uchar readweek(uchar dat) { dat=read_1302add(0x8b); week=((dat&0x70)>>4)*10+(dat&0x0f); return week; } /*****************读出年的十进制数***************************/ uchar readyear(uchar dat) { dat=read_1302add(0x8d); year=((dat&0xf0)>>4)*10+(dat&0x0f); return year; } /************************读出所有时间**********************/ readtime() { readsecond(); readminute(); readhour(); readday(); -readmonth(); readweek(); readyear(); } /*********************向1602写入时间****************************/ void write_second() { uchar shi,ge; shi=second/10; ge=second%10; Write1602(0x80+0x40+9,0x30+shi); Write1602(0x80+0x40+10,0x30+ge); } void write_minute() { uchar shi,ge; shi=minute/10; ge=minute%10; Write1602(0x80+0x40+6,0x30+shi); Write1602(0x80+0x40+7,0x30+ge); } void write_hour() { uchar shi,ge; shi=hour/10; ge=hour%10; Write1602(0x80+0x40+3,0x30+shi); Write1602(0x80+0x40+4,0x30+ge); } void write_day() { uchar shi,ge; shi=day/10; ge=day%10; Write1602(0x80+8,0x30+shi); Write1602(0x80+9,0x30+ge); } void write_month() { uchar shi,ge; shi=month/10; ge=month%10; Write1602(0x80+5,0x30+shi); Write1602(0x80+6,0x30+ge); } void write_year() { uchar shi,ge; shi=year/10; ge=year%10; Write1602(0x80+2,0x30+shi); Write1602(0x80+3,0x30+ge); } void write_week() { /*uchar shi,ge; shi=week/10; ge=week%10; Write1602(0x80+12,0x30+shi); Write1602(0x80+13,0x30+ge); */ Write1602(0x80+12,0x30+week); } void main() { delay(100); init1602(); init_1302(); while(1) { readtime(); write_second(); write_minute(); write_hour(); write_day(); write_month(); write_year(); write_week(); } }
上一篇:基于51单片机的智能小车(遥控模块寻迹避障)
下一篇:基于51单片机的倒计时器设计
推荐阅读最新更新时间:2024-03-16 14:25