|
|
我用89C51芯片编写了一个简易时钟,功能是用89C51中断计时,然后在8位数码管上显示出来。使用4个按键来对小时与分钟调整,并整合了长短按键功能。程序可以在普中A4开发板顺利运行,所以我贴出来分享给新进者。
但同时也向路过的大神问一个问题?为什么程序在proteus上不能正确仿真,总是出现乱码?在网上搜过各种答案,也照着答案修改过原理图,还是不能解决。问过AI,它总是一本正经的胡说八道,害我浪费很多时间。本来我直接用P2口控制位选,用P0接个74HC138跟随器控制段选,没成功。按AI说的,P2也接上74HC138,还与数码管之间连上限流电阻,依然无效。单步运行仿真,还能看到数码管时不时显示乱码,整体仿真连显示都没有。换成8个单个的数码管,结局一样。proteus自己的提示是CPU过载,我按网上提示所说,换了台性能好的游戏本,还是一样结果。
所以我没招了,有用proteus非常多的大神没有?希望你们能帮我解决一下这个大众问题。这个问题应该是很普便性的,但一直没见到好的解决方案。它是proteus的51单片机之坑。我在使用点阵时,也会碰到类似问题。
我把时钟设计的proteus9.0原理图与针对原理图调整的程序放在了附件的zip文件里
下面是我在普中开发板上的成功代码,根据开发板原理图编写。
- #include<reg51.h>
- #define weixuan P2
- #define duanxuan P0
- sbit key1=P3^1;
- sbit key2=P3^0;
- sbit key3=P3^2;
- sbit key4=P3^3;
- 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}; //数字索引表
- u8 smgbuff[8]={0x3f,0x3f,0x40,0x3f,0x3f,0x40,0x3f,0x3f};//s,min,h
- unsigned long pdata keydowntime[4]={0,0,0,0}; //按键按下计时
- void ledscan()
- {
- static u8 i=0;
- duanxuan=0x00; // hide shade
- weixuan =(weixuan&0xe3) |(i<<2); 开发板用的是P2.2 2.3 2.4引脚来位选,所以i左移2位后或到P2口上
- duanxuan=smgbuff[i];
- i++;
- if(i>=8)
- {
- i=0;
- }
- }
- 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() //消抖思路学自kingst开发板教程
- {
- 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;
-
- //i=i&0x07;
- for(j=0;j<4;j++)
- {
- if(keybuff[j]==0x00)
- {
- keysta[j]=0; //keybuff左移8次后若显示都是0,说明消抖后,按键处于按下状态,同时按键时间加4,改变数字可以改灵敏度
- keydowntime[j]+=4;
- }
- else if(keybuff[j]==0xff)
- {
- keysta[j]=1;
- keydowntime[j]=0; //按键弹起后,按下时间要归0
- }
- }
-
-
-
-
- }
- void keyaction(u8 kode)
- {
- //0x26,0x25,0x28,0x27
- switch(kode)
- {
- case 0x26: //向上键,方向加
- {
- if(sethour==1)
- {
-
- hour++;
-
- if(hour>=24)
- {
- hour=0;
- }
- smgbuff[6]=gsmg_code[hour%10];
- smgbuff[7]=gsmg_code[hour/10];
- }
- if(setmin==1)
- {
- min++;
- if(min>=60)
- {
- min=0;
- }
- smgbuff[3]=gsmg_code[min%10];
- smgbuff[4]=gsmg_code[min/10];
- }
- break;
- }
- case 0x25:sethour=~sethour;break; //左键调小时
- case 0x28: //向下键,方向减
- {
- if(sethour==1)
- {
- hour--;
- if(hour<0)
- {
- hour=23;
- }
- smgbuff[6]=gsmg_code[hour%10];
- smgbuff[7]=gsmg_code[hour/10];
- }
- if(setmin==1)
- {
- min--;
- if(min<0)
- {
- min=59;
- }
- smgbuff[3]=gsmg_code[min%10];
- smgbuff[4]=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 pdata 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; //注意,按键弹起后,此处要恢复timemax的初值。
- }
- }
- }
- 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[6]=gsmg_code[hour%10];
- smgbuff[7]=gsmg_code[hour/10];
-
- }
- smgbuff[3]=gsmg_code[min%10];
- smgbuff[4]=gsmg_code[min/10];
- }
- smgbuff[0]=gsmg_code[sec%10];
- smgbuff[1]=gsmg_code[sec/10];
- }
-
- }
- void main()
- {
- configtime(1); //配置一毫秒中断计时
-
-
- 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==1000)
- {
- timer1=0;
- secflag=1;
- }
- if(timer2==500) //此处增加调整时间时,数字的闪烁功能,以判断当前处于调整时间状态。
- {
- timer2=0;
- if(sethour==1 )
- {
- if(hourblink==0)
- {
- smgbuff[6]=0x00;
- smgbuff[7]=0x00;
-
- }
- else
- {
- smgbuff[6]=gsmg_code[hour%10];
- smgbuff[7]=gsmg_code[hour/10];
- }
- hourblink=~hourblink;
- }
- else
- {
- smgbuff[6]=gsmg_code[hour%10];
- smgbuff[7]=gsmg_code[hour/10];
- }
- if(setmin==1)
- {
- if(minblink==0)
- {
- smgbuff[4]=0x00;
- smgbuff[3]=0x00;
-
- }
- else
- {
- smgbuff[3]=gsmg_code[min%10];
- smgbuff[4]=gsmg_code[min/10];
- }
- minblink=~minblink;
- }
- else
- {
- smgbuff[3]=gsmg_code[min%10];
- smgbuff[4]=gsmg_code[min/10];
- }
- }
- }
复制代码 |
|