求助关于万年历1602显示乱码问题|我爱单片机 - 数码之家
查看完整版本: [--
赞助商链接
自己尝试做一个万年历,但是程序下载好后,然后1602上运行显示不正确,具体情况是都是乱码,而且快速的从右到左,然后在从右到左不停,还有刚开始的时候只是第一行显示一行黑块,然后我摁下硬件复位才开始滚动显示乱码~~~具体就是这样,请各位高手帮忙分析分析原因图片如下:[attachment=2253591]摁下复位之后[attachment=2253590]代码如下:#include®52.hinclude&intrins.hdefine uchar unsigned char #define uint unsigned int#define LCDIO P0sbit DQ=P1^3;//ds18b20与单片机连接口sbit rs=P1^0; sbit rd=P1^1;sbit lcden=P1^2;sbit acc0=ACC^0; //移位时的第0位sbit acc7=ACC^7; //移位时用的第7位uchar second,minute,hour,day,month,year,week,count=0; uchar ReadValue,num, //温度值uchar code table[]={&
MON&};uchar code table1[]={& 15:45:00 000.0C&};uchar code table2[]={&THUFRISATSUNMONTUEWES&};uchar data disdata[5];sbit DATA=P3^4; //时钟数据接口sbit RST=P3^5; sbit SCLK=P3^3; sbit menu=P2^0; //菜单sbit add=P2^1; //加一sbit dec=P2^2; //减一void delay(uint z){ uint x,y; for(x=z;x&0;x--) for(y=110;y&0;y--);}void delay1(uint z){ for(;z&0;z--);}void write_com(uchar com){ rs=0; rd=0; lcden=0; P0= delay(5); lcden=1; delay(5); lcden=0; } void write_date(uchar date){ rs=1; rd=0; lcden=0; P0= delay(5); lcden=1; delay(5); lcden=0; } void init(){ lcden=0; write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); write_com(0x80); delay(5); write_com(0x80); for(num=0;num&15;num++) { write_date(table[num]); delay(5); } write_com(0x80+0x40); for(num=0;num&15;num++) { write_date(table1[num]); delay(5); }
} void Write1302(uchar dat){ SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备 delay1(2); //稍微等待,使硬件做好准备 for(i=0;i&8;i++) //连续写8个二进制位数据 { DATA=dat&0x01; //取出dat的第0位数据写入1302 delay(2); //稍微等待,使硬件做好准备 SCLK=1; //上升沿写入数据 delay1(2); //稍微等待,使硬件做好准备 SCLK=0; //重新拉低SCLK,形成脉冲 dat&&=1; //将dat的各数据位右移1位,准备写入下一个数据位 } }
void WriteSet1302(uchar Cmd,uchar dat) { RST=0; //禁止数据传递 SCLK=0; //确保写数居前SCLK被拉低 RST=1; //启动数据传输 delay1(2); //稍微等待,使硬件做好准备 Write1302(Cmd); //写入命令字 Write1302(dat); //写数据 SCLK=1; //将时钟电平置于已知状态 RST=0; //禁止数据传递 } uchar Read1302(void) { uchar i, delay(2); //稍微等待,使硬件做好准备 for(i=0;i&8;i++) //连续读8个二进制位数据 { dat&&=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位 if(DATA==1) //如果读出的数据是1 dat|=0x80; //将1取出,写在dat的最高位 SCLK=1; //将SCLK置于高电平,为下降沿读出 delay1(2); //稍微等待 SCLK=0; //拉低SCLK,形成脉冲下降沿 delay1(2); //稍微等待 } //将读出的数据返回 } uchar ReadSet1302(uchar Cmd) { RST=0; //拉低RST SCLK=0; //确保写数居前SCLK被拉低 RST=1; //启动数据传输 Write1302(Cmd); //写入命令字 dat=Read1302(); //读出数据 SCLK=1; //将时钟电平置于已知状态 RST=0; //禁止数据传递 //将读出的数据返回}void Init_DS1302(void){
WriteSetE,0x00); //根据写状态寄存器命令字,写入不保护指令
WriteSet,((0/10)&&4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值 WriteSet,((45/10)&&4|(45%10))); //根据写分寄存器命令字,写入分的初始值 WriteSet,((15/10)&&4|(15%10))); //根据写小时寄存器命令字,写入小时的初始值 WriteSet,((29/10)&&4|(29%10))); //根据写日寄存器命令字,写入日的初始值 WriteSet,((11/10)&&4|(11%10))); //根据写月寄存器命令字,写入月的初始值 WriteSetc,((10/10)&&4|(10%10))); //nian WriteSeta,((4/10)&&4|(4%10)));} void DisplaySecond(uchar x){ uchar i,j; i=x/10; j=x%10; write_com(0xc7);
write_date(0x30+i);
write_date(0x30+j); }void DisplayMinute(uchar x){ uchar i,j; i=x/10; j=x%10;
write_com(0xc4); write_date(0x30+i); write_date(0x30+j); } void DisplayHour(uchar x){ uchar i,j;
i=x/10; j=x%10; write_com(0xc1); write_date(0x30+i); write_date(0x30+j); } void DisplayDay(uchar x){ uchar i,j;
i=x/10; j=x%10; write_com(0x89); write_date(0x30+i); write_date(0x30+j); } void DisplayMonth(uchar x){ uchar i,j;
i=x/10; j=x%10; write_com(0x86); write_date(0x30+i); write_date(0x30+j); } void DisplayYear(uchar x){ uchar i,j; i=x/10; j=x%10;
write_com(0x83); write_date(0x30+i); write_date(0x30+j); } void DisplayWeek(uchar x){ x=x*3; write_com(0x8c); for(i=0;i&3;i++) { write_date(table2[x]); x++; } }
void read_date(void){ ReadValue = ReadSet); second=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F); ReadValue = ReadSet); minute=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F); ReadValue = ReadSet); hour=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F); ReadValue = ReadSet); day=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F); ReadValue = ReadSet); month=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F); ReadValue = ReadSetd); year=((ReadValue&0x70)&&4)*10 + (ReadValue&0x0F); ReadValue=ReadSetb); //读星期 week=ReadValue&0x07; DisplaySecond(second); DisplayMinute(minute); DisplayHour(hour); DisplayDay(day); DisplayMonth(month); DisplayYear(year); DisplayWeek(week); } void turn_val(char newval,uchar flag,uchar newaddr,uchar s1num) { newval=ReadSet1302(newaddr); //读取当前时间 newval=((newval&0x70)&&4)*10+(newval&0x0f); //将bcd码转换成十进制 if(flag) //判断是加一还是减一 { newval++; switch(s1num) { case 1: if(newval&99) newval=0; DisplayYear(newval); case 2: if(newval&12) newval=1; DisplayMonth(newval); case 3: if(newval&31) newval=1; DisplayDay(newval); case 4: if(newval&6) newval=0; DisplayWeek(newval); case 5: if(newval&23) newval=0; DisplayHour(newval); case 6: if(newval&59) newval=0; DisplayMinute(newval); case 7: if(newval&59) newval=0; DisplaySecond(newval); default: } } else { newval--; switch(s1num) { case 1: if(newval==0) newval=99; DisplayYear(newval); case 2: if(newval==0) newval=12; DisplayMonth(newval); case 3: if(newval==0) newval=31; DisplayDay(newval); case 4: if(newval&0) newval=6; DisplayWeek(newval); case 5: if(newval&0) newval=23; DisplayHour(newval); case 6: if(newval&0) newval=59; DisplayMinute(newval); case 7: if(newval&0) newval=59; DisplaySecond(newval); default: } } WriteSet1302((newaddr-1),((newval/10)&&4)|(newval%10)); //将新数据写入寄存器 }
//键盘扫描程序//*******************************************void key_scan(void){ uchar miao,s1num=0; if(menu==0) { delay(5); if(menu==0) { while(!menu); s1num++; while(1) { if(menu==0) { delay(5); if(menu==0) { while(!menu); s1num++; } } rd=0; miao=ReadSet); second= WriteSet,miao|0x80); write_com(0x0f);//光标闪射 if(s1num==1) { year=ReadSetd); write_com(0x80+4); //年光标 if(add==0) { delay(3); if(add==0) { while(!add); turn_val(year,1,0x8d,1); } } if(dec==0) { delay(3); if(dec==0) { while(!dec); turn_val(year,0,0x8d,1); } } } if(s1num==2) { month=ReadSet); write_com(0x80+7); //月光标 if(add==0) { delay(3); if(add==0) { while(!add); turn_val(month,1,0x89,2); } } if(dec==0) { delay(3); if(dec==0) { while(!dec); turn_val(month,0,0x89,2); } } } if(s1num==3) { day=ReadSet); write_com(0x80+10);//日光标 if(add==0) { delay(3); if(add==0) { while(!add); turn_val(day,1,0x87,3); } } if(dec==0) { delay(3); if(dec==0) { while(!dec); turn_val(day,0,0x87,3); //写入日寄存器 } } } if(s1num==4) { week=ReadSetb); write_com(0x80+14); //星期光标 if(add==0) { delay(3); if(add==0) { while(!add); turn_val(week,1,0x8b,4); } } if(dec==0) { delay(3); if(dec==0) { while(!dec); turn_val(week,0,0x8b,4); } } } if(s1num==5) { hour=ReadSet); write_com(0x80+0x40+2); //时光标 if(add==0) { delay(3); if(add==0) { while(!add); turn_val(hour,1,0x85,5); } } if(dec==0) { delay(3); if(dec==0) { while(!dec); turn_val(hour,0,0x85,5); } } } if(s1num==6)//调时间分 { minute=ReadSet); write_com(0x80+0x40+5); if(add==0) { delay(5); if(add==0) { while(!add); turn_val(minute,1,0x83,6); //写入分寄存器 } } if(dec==0) { delay(3); if(dec==0) { while(!dec); turn_val(minute,0,0x83,6); //写入分寄存器 } } } if(s1num==7)//调时间秒 { second=ReadSet); write_com(0x80+0x40+8);//秒光标 if(add==0) { delay(3); if(add==0) { while(!add); if(second==0x60) second=0x00; turn_val(second,1,0x81,7); } } if(dec==0) { delay(3); if(dec==0) { while(!dec); turn_val(second,0,0x81,7); } } }
if(s1num==8) { miao=ReadSet); second= WriteSet,second&0x7f); s1num=0;//s1num清零// write_com(0x0c);//光标不闪烁// } } } }} void delay_18B20(unsigned int i)//延时1微秒{ while(i--);}void ds1820rst()/*ds1820复位*/ { unsigned char x=0; DQ = 1; //DQ复位 delay_18B20(4); //延时 DQ = 0; //DQ拉低 delay_18B20(100); //精确延时大于480us DQ = 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(); b=ds1820rd(); tvalue=b; tvalue&&=8; tvalue=tvalue|a; if(tvalue&0x0fff) tflag=0; else {tvalue=~tvalue+1; tflag=1; } tvalue=tvalue*(0.425);//温度值扩大10倍,精确到1位小数 return(tvalue); }void ds1820disp()//温度值显示 { disdata[0]=tvalue/;//百位数 disdata[1]=tvalue%x30;//十位数 disdata[2]=tvalue%100/10+0x30;//个位数 disdata[3]=tvalue%10+0x30;//小数位 if(tflag==0) flagdat=0x20;//正温度不显示符号 else flagdat=0x2d;//负温度显示负号:- if(disdata[0]==0x30) {disdata[0]=0x20;//如果百位为0,不显示 if(disdata[1]==0x30) {disdata[1]=0x20;//如果百位为0,十位为0也不显示 } } write_com(0xc9); write_date(flagdat);//显示符号位 write_com(0xca); write_date(disdata[0]);//显示百位 write_com(0xcb); write_date(disdata[1]);//显示十位 write_com(0xcc); write_date(disdata[2]);//显示个位 write_com(0xcd); write_date(0x2e);//显示小数点 write_com(0xce); write_date(disdata[3]);//显示小数位 write_com(0xcf); write_date('C'); }void main(){ init(); Init_DS1302(); //将1302初始化 read_temp();//读取温度 ds1820disp();//显示 while(1) { read_date(); key_scan(); read_temp();//读取温度 ds1820disp();//显示 } }
赞助商链接
代码发上来给你看看啊,
赞助商链接
发个代码、照片上来吧,这样大家判断问题也容易些~~~
建议先用万用表检查所有连接1602的线是否有虚焊或接触不良, 下一步才检查源程序是否有问题, 所以先处理好硬件才检测软件.
我的1602屏显示字符也是这样的,最后换了个片子 就正常了
代码已经在一楼放出,麻烦帮忙看看,之前在另外一块板子上能正常显示,但是就是星期位置是乱码还有就是分钟总是显示85,现在新焊的板子,初步估计是硬件问题,可是查了半天都没办法,实在没辙了,请大神帮帮忙~~~
代码已经在一楼放出,麻烦帮忙看看,之前在另外一块板子上能正常显示,但是就是星期位置是乱码还有就是分钟总是显示85,现在新焊的板子,初步估计是硬件问题,可是查了半天都没办法,实在没辙了,请大神帮帮忙~~~
代码已在一楼放出,之前在另外一块板子上能正常显示,但是就是星期位置是乱码还有就是分钟总是显示85,现在新焊的板子,初步估计是硬件问题,可是查了半天都没办法,请大神帮帮忙~~~
估计是DS1302时钟芯片未能读取数据, 检查相关数据线是否接触不良, 如可以上传制作实物和显示问题相片给大家一起研究解决.
你意思是换块板子重新焊接~~~好坑爹的方法~~~这个方法等到实在没办法的时候再用~~~
好吧,我尽量吧,因为乱码滚动比较快,手机有压力,我拍个视频然后截个动态图片
还有忘说了,程序里面有些语句貌似是没用到的,因为是从网上down的一个功能比较少,仿真没问题,实物就是问题多多呀,
问题已解决,换了块单片机就好了,貌似是我单片机某个引脚有问题,乱码消失了,至于第一幅图片里面第一行黑块需要复位下,是因为1602覆盖在单片机上影响接电,我只好先拿掉1602接好电后才插上1602就导致了需要复位才正常显示,后来又出现新问题,最终也解决了,下面把我后来遇到的问题,就是显示部分显示不正常,不走动,然后调节时间也是错乱的,因为我用的stc89c52(说实话我只熟悉这一款)P0/P1/P2/P3 是准双向口/弱上拉,那么就需要在ds1302 I/O加一个上拉(网上也有说io、sclk、rst都加上拉,我没试过,大家可以先试试给io加个上拉,不行再给另外两个也加上),具体就是这样,作为一个菜鸟,我也不知道分析的对不对,不过怎么说问题还是解决了,就给各位做个参考,让大家少走弯路~~~
好吧,此贴终结!
DS1302的3条数据线和DS18B20的DQ线一般都加上拉电阻传送数据时较为稳定, 楼主吸收了宝贵的实践经验, 继续加油.
引用第9楼zichuanliufe于 19:35发表的 回 4楼(ccfx) 的帖子 :你意思是换块板子重新焊接~~~好坑爹的方法~~~这个方法等到实在没办法的时候再用~~~ 一点都不坑爹,我曾经一块做下载板,之前正常,放一段时间后怎么弄都不行,最后气的重新做一个,好了
其实,有个逻辑分析仪的话,问题瞬间解决。
感觉像时序的问题&&你用的什么片子来着?&&网上下的程序 仿真没问题&&实际有时候要自己改延时呀什么的
学习!字数补丁,嘿嘿!
查看完整版本: [--
Powered by
Gzip enabled