遇到一个问题,如何按键按下既能控制流水灯又能把键值在数码管中显示呢?流水灯500ms的延时,和数码管动态刷新延时小于10ms显示有冲突。
bit和sbit,sfr都是C51扩展的变量类型,不是标准C语言类型
1.bit类型的值是一个二进制位,不是0就是1,类似布尔类型
2.sbit大部分是用在寄存器中的,方便对寄存器的某位进行操作的。
sbit LED1 = P0^0 把P0端口的第0位命名为LED1,方便使用
sbit 位变量名=SFR 名称^变量 位地址值
3.sfr也是一种扩充数据类型:,占用一个内存单元,利用它可以访问51单片机内部的所有特殊功能寄存器。如用sfr P1 = 0x90 指定P1来操作地址为0X90的寄存器
改变流水灯的方向
按键控制流水灯实现的功能:
1.key1启动键,首次按下可以产生自上向下的流水灯效果
2.key2停止键,按下可以终止流水灯的运动
3.key3和key4分别产生自上向下和自下向上的流水灯效果
实现的方法:
1.利用标志位Startflag来控制流水灯的开始和停止,初始化定义为0停止,为1时上电便有流水灯效果。用标志位UpDownflag控制流水灯的方向,初始化的值0,1来控制自上而下还是从下到上
2.利用移位运算符实现流水灯效果
注意:移位运算符实现循环移位才能实现流水灯的效果
C51库函数自带循环移位的效果:crol 循环左移 _cror_循环右移
按键应用层功能函数
void Key_Service()
{
switch(Key_Scan())
{
case 1: Startflag = 1;break;//开始
case 2: Startflag = 0;break;//停止
case 3: UpDownflag =1;break;//向上流水灯
case 4: UpDownflag =0;break;//向下流水灯
default :break;
}
if(Startflag)
{
P0 = temp;
if(UpDownflag)
{
temp = (temp>>1)|0x80; //右移一位
if(temp == 0xff) //条件判断给temp重新赋值,实现循环移位功能
temp = 0x7f;
}
else
{
temp = (temp<<1)|0x1;//左移一位
if(temp == 0xff) //条件判断给temp重新赋值,实现循环移位功能
temp = 0xfe;
}
DelayXms(500);
}
}
自己遇到的一个问题:按键按下既能控制流水灯又能把键值在数码管中显示
2个功能分开都能正确运行
糅合在一起就会出问题。
因为延时500ms数码管动态刷新有问题
void main()
{
LEDBuf[0]=23;
LEDBuf[1]=23;
LEDBuf[2]=23;
while(1)
{
Key_Service();
Didplay_Service();
}
}
void Didplay_Service()
{
switch(Key_Scan())
{
case 1:LEDBuf[3]=1;break;
case 2:LEDBuf[3]=2;break;
case 3:LEDBuf[3]=3;break;
case 4:LEDBuf[3]=4;break;
default :break;
}
Display();
}
如果删除500ms的延时,显示效果是这样的.
加上500ms延时,按键好像失效似的,返回显示的键值也不对,很奇怪的问题。
-
单片机
+关注
关注
6032文章
44513浏览量
632694 -
寄存器
+关注
关注
31文章
5308浏览量
119977 -
数码管
+关注
关注
32文章
1874浏览量
90921 -
流水灯
+关注
关注
21文章
432浏览量
59633 -
按键
+关注
关注
4文章
223浏览量
57568
发布评论请先 登录
相关推荐
评论