
你如果没有用译码器,那应该问题出在扫描部分。在显示下一个数码管显示的时候,要关了上一个数码管,同时更新第二个数码管数据输出端的数据。延时一段时间之后,再显示下一个数码管数据。这样一直扫描。固定扫描时间,有两种方法,一种是定时器中断,一种是自已用延时程序来自已作一个软件定时器。还有一个要注意的问题就是按键要设置一个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步进电机的转向调速等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)