|
|
对于初学者最糟心的事就是程序编写的很好,却在仿真时出毛病。程序能在开发板上顺利执行,数码管与点阵屏proteus显示仿真却总是出问题。你的本意是想用仿真发现问题,从而减少在现实中出错的机率,结果到仿真那一步让你抓狂了,薅掉半斤头发,最后发现与你的程序与原理图毛事没有,毛病出在proteus软件上,毕竟人编写的软件,还达不到真正模拟实物的水平,只能努力无限接近。
我用了一整天,和这个问题较劲,期间无数次反对AI提出的问题答案与解决方案。也不能说AI一点帮助没有,在某些问题与思路上还是能给些提示的,但更多的时间是在胡说八道,引你入歧途,所以我浪费了这么长时间。
因为我是直接用P0,和P2端口控制的8个数码管,所以我会用逻辑探针去检查P0端口及与P0相连的线,发现P0口在程序proteus仿真过程中,出现了我不需要的数据,即出现了干扰。
这促使我放弃直接用P0与P2端口,我决定用两个74HC595串转并芯片级联来控制8个数码管。我要看看没有了P0的数据干扰,会有效吗?结果是解决了95%的故障。剩下的故障是因为我有些变量设置成pdata模式,而这个模式也容易造成proteus仿真51芯片工作时,出现对芯片P0与P2寄存器的干扰,从而神秘地间接影响你的变量。总结下来都是一回事,P0与P2寄存器易受干扰,从而在proteus仿真中故障,使你的程序能在开发板运行(实物容错能力比虚拟仿真强),但在仿真时出现乱码,乱跳,甚至不显示,重点体现在有很多个LED灯一起工作的情况,比如更多的数码管与8*8点阵。
实话实说,pdata设置造成P0寄存器的干扰,最后还是AI提出的假设,我验证成功了。单独靠我自己,绝对发现不了这种玄幻。
下面是我用51单片机中断计时,在数码管上显示时间的程序,整合了长短按键功能,按键设置时间功能。AI说pdata设置变量,使得51仿真时,调用了P0去寻址,从而神秘使得51误判我某个按键启动,显示小时部分在00与23之间互跳,分钟部分在00与01间互跳。
故初学者在写程序时,还是尽量不要用片外内存,即不用pdata与xdata,除非256个字节片内RAM用完,尤其是在用数码管与点阵显示数字时。硬件设置上弃用芯片寄存器直接控制数码管与点阵,用类似74HC595芯片来传输数据,控制点阵与数码管。
程序中注释掉的是我程序修改前的痕迹,我没有删除,有兴趣的人可以对比一下仿真现象与效果。
- #include<reg51.h>
- #include<intrins.h>
- // #define weixuan P2
- // #define duanxuan P0
- sbit key1=P3^0;
- sbit key2=P3^1;
- sbit key3=P3^2;
- sbit key4=P3^3;
- sbit SH_CP=P1^0;
- sbit ST_CP=P1^1;
- sbit DS1=P1^2;
- unsigned char code KeyCodeMap[4] ={0x26,0x25,0x28,0x27};//up left down right
- typedef unsigned char u8;
- typedef unsigned int u16;
- u8 T0RH,T0RL;
- u8 secflag=0;
- bit sethour=0,setmin=0;
- u8 keysta[4]={1,1,1,1};
- signed char hour=0;
- signed char min=0;
- signed char sec=0;
- bit hourblink=0;
- bit minblink=0;
- /* 共阴极管的数字索引
- u8 code gsmg_code[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- */
- unsigned char code gsmg_code[] = { //共阳极管的数字索引
- 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
- 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
- };
- // u8 smgbuff[8]={0x3f,0x3f,0x40,0x3f,0x3f,0x40,0x3f,0x3f};//s,min,h
- u8 smgbuff[8]={0xC0,0xC0,0xBF,0xC0,0xC0,0xBF,0xC0,0xC0};//s,min,h
- u8 wselect[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
- unsigned long keydowntime[4]={0,0,0,0};
- void tranfer_data(u8 dat1,u8 dat2) //595串转并芯片的数据传输函数,dat1交给第一级,控制位选,dat2交给第二级,段选
- {
- u8 i=0;
- for(i=0;i<8;i++)
- {
- DS1=dat2>>7;
- dat2<<=1;
- SH_CP=0;
- _nop_ ();
- SH_CP=1;
- _nop_();
-
- }
-
-
- for(i=0;i<8;i++)
- {
- DS1=dat1>>7;
- dat1<<=1;
- SH_CP=0;
- _nop_ ();
- SH_CP=1;
- _nop_();
-
- }
- ST_CP=0;
- _nop_();
- ST_CP=1;
- _nop_ ();
- }
- void ledscan()
- {
- static u8 i=0;
- // duanxuan=0x00; // hide shade
- // duanxuan=0xFF;
- // weixuan=0x00;
- // weixuan =(0x01<<i);
- // duanxuan=smgbuff[i];
-
- // tranfer_data(0x00,0xFF); //hide shade
- tranfer_data(wselect[i], smgbuff[i]);//transer wx and dx data
-
-
-
- i++;
- if(i>=8)
- {
- i=0;
- }
- //i=i&0x07;
- }
- void configtime(u8 ms)
- {
- unsigned long tmp;
- tmp=ms*11059200/12/1000;
- tmp=65536-tmp+15;//delay compensationn
- T0RH=(u8)(tmp>>8);
- T0RL=(u8)tmp;
- EA=1;
- TMOD=0X01;
- TH0=T0RH;
- TL0=T0RL;
- ET0=1;
- TR0=1;
- }
- void keyscan()
- {
- static u8 keybuff[4]={0xff,0xff,0xff,0xff};
-
- u8 j=0;
- keybuff[0]=(keybuff[0]<<1) | key1;
- keybuff[1]=(keybuff[1]<<1) | key2;
- keybuff[2]=(keybuff[2]<<1) | key3;
- keybuff[3]=(keybuff[3]<<1) | key4;
-
-
- for(j=0;j<4;j++)
- {
- if(keybuff[j]==0x00)
- {
- keysta[j]=0;
- keydowntime[j]+=4;
- }
- else if(keybuff[j]==0xff)
- {
- keysta[j]=1;
- keydowntime[j]=0;
- }
- }
-
-
-
-
- }
- void keyaction(u8 kode)
- {
- //0x26,0x25,0x28,0x27
- switch(kode)
- {
- case 0x26:
- {
- if(sethour==1)
- {
-
- hour++;
-
- if(hour>=24)
- {
- hour=0;
- }
- smgbuff[1]=gsmg_code[hour%10];
- smgbuff[0]=gsmg_code[hour/10];
- }
- if(setmin==1)
- {
- min++;
- if(min>=60)
- {
- min=0;
- }
- smgbuff[4]=gsmg_code[min%10];
- smgbuff[3]=gsmg_code[min/10];
- }
- break;
- }
- case 0x25:sethour=~sethour;break;
- case 0x28:
- {
- if(sethour==1)
- {
- hour--;
- if(hour<0)
- {
- hour=23;
- }
- smgbuff[1]=gsmg_code[hour%10];
- smgbuff[0]=gsmg_code[hour/10];
- }
- if(setmin==1)
- {
- min--;
- if(min<0)
- {
- min=59;
- }
- smgbuff[4]=gsmg_code[min%10];
- smgbuff[3]=gsmg_code[min/10];
- }
- break;
- }
- case 0x27:setmin=~setmin;break;
- default :break;
- }
-
-
- }
- void keydrive()
- {
- static u8 backup[4]={1,1,1,1};
- u8 k=0;
- static unsigned long timemax[4]={1000,1000,1000,1000};
- for(k=0;k<4;k++)
- {
- if(backup[k]!=keysta[k])
- {
- backup[k]=keysta[k];
- if(backup[k]!=0)
- {
- keyaction(KeyCodeMap[k]);
-
- }
- }
- if(keydowntime[k]>0)
- {
- if(keydowntime[k]>=timemax[k])
- {
- keyaction(KeyCodeMap[k]);
- timemax[k]+=200;
- }
-
- }
- else
- {
- timemax[k]=1000;
- }
- }
- }
- void time()
- {
- if(secflag==1)
- {
- secflag=0;
-
- sec++;
- if(sec==60)
- {
- sec=0;
-
- min++;
- if(min==60)
- {
- min=0;
-
- hour++;
- if(hour==24)
- {
- hour=0;
- }
- smgbuff[1]=gsmg_code[hour%10];
- smgbuff[0]=gsmg_code[hour/10];
-
- }
- smgbuff[4]=gsmg_code[min%10];
- smgbuff[3]=gsmg_code[min/10];
- }
- smgbuff[7]=gsmg_code[sec%10];
- smgbuff[6]=gsmg_code[sec/10];
- }
-
- }
- void main()
- {
- configtime(5); //中断函数中内容较多,1ms可能不够用,故设置成5ms
-
-
- while(1)
- {
- time();
- keydrive();
-
-
- }
-
- }
- void interruptmr() interrupt 1
- {
- static u16 timer1=0;
- static u16 timer2=0;
- TH0=T0RH;
- TL0=T0RL;
- ledscan();
- keyscan();
- timer1++;
- timer2++;
- if(timer1==200)
- {
- timer1=0;
- secflag=1;
- }
- if(timer2==100)
- {
- timer2=0;
-
- if(sethour==1 )
- {
- if(hourblink==0)
- {
- smgbuff[1]=0xFF;
- smgbuff[0]=0xFF;
-
- }
- else
- {
- smgbuff[1]=gsmg_code[hour%10];
- smgbuff[0]=gsmg_code[hour/10];
- }
- hourblink=~hourblink;
- }
- else
- {
- smgbuff[1]=gsmg_code[hour%10];
- smgbuff[0]=gsmg_code[hour/10];
- }
- if(setmin==1)
- {
- if(minblink==0)
- {
- smgbuff[4]=0xFF;
- smgbuff[3]=0xFF;
-
- }
- else
- {
- smgbuff[4]=gsmg_code[min%10];
- smgbuff[3]=gsmg_code[min/10];
- }
- minblink=~minblink;
- }
- else
- {
- smgbuff[4]=gsmg_code[min%10];
- smgbuff[3]=gsmg_code[min/10];
- }
-
- }
- }
复制代码 |
评分
-
查看全部评分
|