51单片机,用键盘输入数码管显示的程序!!!用汇编语言,大家帮忙看看哪里错了!谢谢了!!!

51单片机,用键盘输入数码管显示的程序!!!用汇编语言,大家帮忙看看哪里错了!谢谢了!!!,第1张

你如果没有用译码器,那应该问题出在扫描部分。在显示下一个数码管显示的时候,要关了上一个数码管,同时更新第二个数码管数据输出端的数据。延时一段时间之后,再显示下一个数码管数据。这样一直扫描。固定扫描时间,有两种方法,一种是定时器中断,一种是自已用延时程序来自已作一个软件定时器。还有一个要注意的问题就是按键要设置一个40-100ms的延时,这样可以防止误读按键。

乍一看就有错误

key_press里的DDRB|=0XF0没用,这句的意思是把B端口的高4位配置成输出,后面DDRB&=0x0F马上又配成输入了。不过这是小问题。看意思b应该声明为静态变量,每次进函数应该都保持上一次的值不变,应该把原来的b=0这句去掉,换成static uchar b = 0;

还有键盘没有防抖功能,q没赋初值,都容易出问题,比如main里刚运行完key_press检测到键盘,然后进key_scan里时键盘抖动了,key_press没检测出来,q就不会被赋值,e=q+b就不一定是什么值了。

加点分呗

#define uchar unsigned char

long First,End; //定义全局变量

void delay(int n) //延时程序//

{int i,j;

for(i=0;i<n;i++)

{for(j=0;j<50;j++)

;}

}

long add(long x,long y) //加法程序//

{long z;

z=x+y;

return(z);

}

long sub(long x,long y) //减法程序//

{long z;

if(x>=y)

z=x-y;

else

{z=y-x;

z=z+10e6;} //最高位用1表示负数//

return(z);

}

long mul(long x,long y) //乘法程序//

{long z;

z=xy;

return(z);

}

long div(long x,long y) //除法程序//

{long z;

z=x/y;

return(z);

}

uchar kbscan(void) //键盘扫描程序//

{

uchar sccode;

P1=0xf0;

if((P1&0xf0)!=0xf0) //发全0行扫描码,列线输入

{ delay(222); //延时去抖

if((P1&0xf0)!=0xf0)

{sccode=0xfe; //逐行扫描初值

while((sccode&0x10)!=0)

{P1=sccode; //输出行扫描码

if((P1&0xf0)!=0xf0)

{

return(P1);} //如果检测到有键按下,返回键值

else

sccode=(sccode<<1)|0x01; //行扫描码左移一位

}

}

}

return(0); //无键按下,返回值为0

}

void display(void) //显示程序//

{int i;

uchar code rel[]=; //数码管选通

uchar code led[]=; //定义0-9

uchar data num[8];

num[0]=First/10000000; //千万位

num[1]=First/1000000%10; //百万位

num[2]=First/100000%10; //十万位

num[3]=First/10000%10; //万位

num[4]=First/1000%10; //千位

num[5]=First/100%10; //百位

num[6]=First/10%10; //十位

num[7]=First%10; //个位

for(i=7;i>=0;i--)

{P3=rel[i]; //位选输出

P2=led[num[i]]; //数据输出

delay(2); //此延时必不可少?

}

}

void main(void) //主程序//

{ int k,n;

uchar f,g,key,gn1;

n=0;

f=0;

P0=0; //初始时指示灯灭

while(1) //不断查询是否有按键动作

{ key=kbscan(); //获取返回键值

if(key!=0)

{

switch(key) //译码,将对应按键返回值转换为相应数值

{

case 0xee: k=0;break;//0

case 0xde: k=1;break;//1

case 0xbe: k=2;break;//2

case 0x7e: k=3;break;//3

case 0xed: k=4;break;//4

case 0xdd: k=5;break;//5

case 0xbd: k=6;break;//6

case 0x7d: k=7;break;//7

case 0xeb: k=8;break;//8

case 0xdb: k=9;break;//9

case 0xbb: k=10;First=0;End=0;f=0;break;//清除

case 0x7b: k=11;break;//等于

case 0xe7: k=12;f=1;break;//加

case 0xd7: k=13;f=2;break;//减

case 0xb7: k=14;f=3;break;//乘

case 0x77: k=15;f=4;break;//除

}

P0=1;

delay(280); //有按键时,指示灯的显示时间

P0=0; //按键指示灭

if(k<10) //为数字键时(0-9)

{

if(f!=0) //为数字键时,如果已经有功能键按下

{

n++; //记录数字键所按次数

gn1=0; //清除标志,再次为功能键时进行运算

g=f; //保存运算标志

if(n==1) //输入为各位数时,直接赋值

First=k;

else if(n>1) //输入为多位数时,将它转化为10进制的多位数

First=First10+k;

}

else //如果没有功能键按下

{

n++;

gn1=1; //定义标志,当下一次为功能键时,停止数据输入

if(n==1)

First=k;

else if(n>1)

First=First10+k;

End=First; //将第一个数保存

}

}

else if(k>11) //为功能键时(+-/)

{

if(gn1==1) //前一次数字键之后为功能键时

{

n=0; //清除计数标志

}

else //如果再次输入功能键,则进行运算

{n=0; //清除计数标志

switch(g)

{case 1: First=add(End,First);break;

case 2: First=sub(End,First);break;

case 3: First=mul(End,First);break;

case 4: First=div(End,First);break;}

}

End=First; //保存本次结果

}

else if(k==11) //为等于号时(=)

{n=0;

gn1=1; //接着输入为功能键时可以继续运算

switch(g)

{case 1: First=add(End,First);break;

case 2: First=sub(End,First);break;

case 3: First=mul(End,First);break;

case 4: First=div(End,First);break;

}

End=First; //保存最终运算结果

f=0; //清除运算标志

}

}

display(); //调用显示程序

}

}

1、首先将译码笔插入电脑USB口上就可以开始使用,下载安装译码笔官方语言驱动,按要求完成安装。

2、其次打开文本编辑软件,左击在译码笔上的“小键盘”按键,开始进行文字输入,选择要翻译的语言,可以双击“小键盘”软件图标,进行语言选择。

3、最后翻译完成后,点击“小键盘”软件图标上的“开始”键,翻译结果就出来了。

以上就是关于51单片机,用键盘输入数码管显示的程序!!!用汇编语言,大家帮忙看看哪里错了!谢谢了!!!全部的内容,包括:51单片机,用键盘输入数码管显示的程序!!!用汇编语言,大家帮忙看看哪里错了!谢谢了!!!、AVR mega16按键程序指教!连续按key1键数码管1显示从1~10,但是下面程序无法实现,错在哪、哪位大侠帮我解释一下下面的程序 特别是矩阵键盘的部分,我想通过实验板控制28BYJ-48步进电机的转向调速等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9647385.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-30
下一篇2023-04-30

发表评论

登录后才能评论

评论列表(0条)

    保存