完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
电子万年历,LCD屏无显示,是什么情况 判忙删掉了,PO口上拉电阻也加上了,还是没有 #include #include #include #define uint unsigned int #define uchar unsigned char ***it IO= P1^0; //DS1302数据线 ***it SCLK = P1^1; //DS130时钟线 ***it RST = P1^2; //DS1302复位线 ***it RS = P2^0; //LCD数据/命令选择端 ***it RW = P2^1; //LCD读/写控制 ***it EN = P2^2; //LCD使能端 ***it K1=P3^4; //选择 ***it K2=P3^5; //加 ***it K3=P3^6; //减 ***it K4=P3^7; //确定 uchar tCount=0; uchar MonthsDays[]={0,31,0,31,30,31,30,31,31,30,31,30,31}; uchar *WEEK[]={"SUN","MON","TUS","WEN","THU","FRI","SAT"}; uchar LCD_DSY_BUFFER1[]={"DATE 00-00-00 "}; //显示格式 uchar LCD_DSY_BUFFER2[]={"tiME 00:00:00 "}; uchar DateTime[7]; //所读取的日期时间 char Adjust_Index=-1; //当前调节的时间对象:,,分,是,日,月,年(1,2,3,4,6) uchar Change_Flag[]= "-MHDM-Y"; //(分,时,日,月,年)(不调节秒与周) /*---------延时程序------------------*/ void DelayMS(uint ms) { uchar i; while(ms--){for(i=0;i<120;i++);} } //-----------向DS1302写入一字节------------------// void Write_A_Byte_TO_DS1302(uchar x) { uchar i; for(i=0;i<8;i++){ IO=x&0x01; //每一位与1与存入IO中 SCLK=1;SCLK=0; //一个高脉冲将数据送入液晶控制器 x>>=1; // 右移 } } //-----------从DS1302读取一字节------------------// uchar Get_A_Byte_FROM_DS1302() { uchar i,b=0x00; for(i=0;i<8;i++){ b |= _crol_((uchar)IO,i); SCLK=1;SCLK=0; //每一个高脉冲读取一位数据 } return b/16*10+b%16; //返回BCD码 } //-----------从DS1302指定位置读数据------------------// uchar Read_Data(uchar addr) { uchar dat; RST = 0;SCLK=0;RST=1; //RST高电平时读/写 Write_A_Byte_TO_DS1302(addr); //先写入地址 dat = Get_A_Byte_FROM_DS1302(); SCLK=1;RST=0; return dat; } //---------向DS1302某地址写入数据--------------------// void Write_DS1302(uchar addr,uchar dat) { SCLK=0;RST=1; Write_A_Byte_TO_DS1302(addr); Write_A_Byte_TO_DS1302(dat); SCLK=0;RST=0; //高脉冲写入数据 } //--------------设置时间----------------// void SET_DS1302() { uchar i; //写控制字,取消写保护 Write_DS1302(0x8E,0x00); //分时日月年依次写入 for(i=1;i<7;i++) { //分的起始地址10000010(0x82),后面依次是时,日,月,周,年,写入地址每次递增2 Write_DS1302(0x80+2*i,(DateTime/10<<4)|(DateTime%10)); } Write_DS1302(0x8E,0x80); //加保护 } //----------读取当前日期时间------------// void GetTime() {uchar i; for(i=0;i<7;i++){ DateTime=Read_Data(0X81+2*i);} } //-----------读LCD状态------------------// uchar Read_LCD_State() { uchar state; RS=0;RW=1;EN=1; //输出:D0~D7=状态字 DelayMS(1); state=P0; //从P0口读LCD状态 EN = 0;DelayMS(1); return state; } //-----------向LCD写数据------------------// void Write_LCD_Data(uchar dat) { LCD_Busy_Wait(); RS=1;EN=0;RW=0; //写数据,EN为高脉冲, P0=dat;EN=1;DelayMS(1);EN=0; } //-------------写LCD指令-------------------// void Write_LCD_Command(uchar cmd) { LCD_Busy_Wait(); RS=0;EN=0; RW=0; //写指令,EN高脉冲,输出:D0~D7=数据 P0=cmd;EN=1;DelayMS(1);EN=0; } //-------------LCD初始化-------------------// void Init_LCD() { Write_LCD_Command(0x38); //设置16*2显示,5*7点阵,8位数据接口 DelayMS(1); Write_LCD_Command(0x01); //显示清零,数据指针清零 DelayMS(1); Write_LCD_Command(0x06); //写一个字符后地址指针自动加1 DelayMS(1); Write_LCD_Command(0x0c); //设置开显示,不显示光标 DelayMS(1); } //------------------------------------------ //设置液晶显示位置 //------------------------------------------ void Set_LCD_POS(uchar p){ Write_LCD_Command(p|0x80);//相当于在0x80基础上加入位置量 } //----在LCD上显示字符串---------// void Display_LCD_String(uchar p,uchar *s) { uchar i; Set_LCD_POS(p); for(i=0;i<16;i++) { Write_LCD_Data(s); //在固定位置显示时间日期 DelayMS(1); } } //---------日期与时间值转换为数字字符----------------// void Format_DateTime(uchar d,uchar *a) { a[0]=d/10+'0'; a[1]=d%10+'0'; } //判断是否为闰年 uchar isLeapYear(uint y) { return (y%4==0&&y%100!=0)||(y%400==0);} //求自2000.1.1开始的任何一天是星期几 //函数没有通过,求出总天数后再求星期几 //因为求总天数可能会超出uint的范围 void RefreshWeekDay() { uint i,d,w=5; //已知1999.12.31是周五 for(i=2000;i<2000+DateTime[6];i++) { d=isLeapYear(i)?366:365; w=(w+d)%7; } d=0; for(i=1;i d+=DateTime[3]; //保存星期,0~6表示星期日,星期一,二,...,六,为了与DS1302的星期格式匹配,返回值需要加1 DateTime[5]=(w+d)%7+1; } //*****年月日时分++/--********// void DateTime_Adjust(char x) { switch(Adjust_Index) { case 6: //年00-99 if(x==1&&DateTime[6]<99) DateTime[6]++; if(x==-1&&DateTime[6]>0) DateTime[6]--; //获取2月天数 MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28; //如果年份变化后当前月份的天数大于上限则设为上限 if(DateTime[3]>MonthsDays[DateTime[4]]) { DateTime[3]=MonthsDays[DateTime[4]];} RefreshWeekDay(); //刷新星期 break; case 4: //月01-12 if(x==1&&DateTime[4]<12) DateTime[4]++; if(x==-1&&DateTime[4]>1) DateTime[4]--; MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28; if(DateTime[3]>MonthsDays[DateTime[4]]) { DateTime[3]=MonthsDays[DateTime[4]];} RefreshWeekDay(); break; case 3: //日00-28、29、30、31,调节之前首先根据年份得出该年中断二月 天数 MonthsDays[2]=isLeapYear(2000+DateTime[6])?29:28; //根据当前月份决定调节日期的上限 if(x==1&&DateTime[3] RefreshWeekDay(); break; case 2: //时 if(x==1&&DateTime[2]<23) DateTime[2]++; if(x==-1&&DateTime[2]>0) DateTime[2]--; break; case 1: //分 if(x==1&&DateTime[1]<59) DateTime[1]++; if(x==-1&&DateTime[1]>0) DateTime[1]--; break; } } //---定时器0每秒刷新LCD显示----// void T0_INT() interrupt 1 { TH0=-50000/256; TL0=-50000%256; if(++tCount !=2) return; tCount=0; //按指定格式生成待显示的日期时间串 Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5); Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8); Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11); //星期 strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]-1]); //时分秒 Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5); Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8); Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11); //显示年月日,星期,时分秒 Display_LCD_String(0x00,LCD_DSY_BUFFER1); Display_LCD_String(0x40,LCD_DSY_BUFFER2); } //----------键盘中断(INT0)-------------// void EX_INT0() interrupt 0 { if(K1==0) //选择调整对象(Y M D H M) { DelayMS(10); if(K1==0){ //while(K1==0); if(Adjust_Index==-1||Adjust_Index==1) { Adjust_Index=7; } Adjust_Index--; if(Adjust_Index==5) Adjust_Index=4; LCD_DSY_BUFFER2[13]='['; LCD_DSY_BUFFER2[14]=Change_Flag[Adjust_Index]; //显示调节对象 LCD_DSY_BUFFER2[15]=']'; } } else if(K2==0) //加 { //while(K2==0); DelayMS(10); if(K2==0) DateTime_Adjust(1); } else if(K3==0) //减 { DelayMS(10);//while(K3==0); if(K3==0) DateTime_Adjust(-1); } else if(K4==0) //确定 { //while(K4==0); DelayMS(10); if(K4==0){ SET_DS1302(); //将调整后的时间写入DS1302 LCD_DSY_BUFFER2[13]=' '; LCD_DSY_BUFFER2[14]=' '; LCD_DSY_BUFFER2[15]=' '; Adjust_Index=-1; } } } void main() { Init_LCD(); //液晶初始化 IE=0x83; //允许INT0,T0中断,EA=1,,ET0=1,EX0=1 IP=0x01; //设置外部中断0为高级中断 IT0=0x01; //外部中断0为电平触发,低电平有效 TMOD=0x01; //设置定时器T0工作方式为方式1, TH0=-50000/256; //装入初始值,定时1秒 TL0=-50000%256; TR0=1; //启动定时器 while(1) { //如果未执行调整操作则正常读取当前时间 if(Adjust_Index==-1) GetTime(); }} |
|
相关推荐
3个回答
|
|
图传错了,是这张
|
|
|
|
图是这张
|
|
|
|
注意看引脚定义和时序延时时间这些
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1897 浏览 1 评论
901 浏览 0 评论
1370 浏览 0 评论
推动SiCMOSFET国产化,华秋获“芯塔电子”优秀媒体合作伙伴奖
1786 浏览 0 评论
3744 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-5-14 10:59 , Processed in 0.588796 second(s), Total 44, Slave 36 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号