打印

关于按键控制LED移位的问题

[复制链接]
2799|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
810629123|  楼主 | 2012-3-24 15:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
有块板子,看到开发资料上有个用两个按键来控制8个LED灯左移右移的程序,其中程序有点不懂。硬件为单片机P0^0、P0^1、对应按键1按键2。P1口分别对应8个LED灯。程序如下:#include <reg51.h>
#include <intrins.h>
unsigned char scan_key();
void proc_key(unsigned char key_v);
void delayms(unsigned char ms);
sbit K1 = P0^0; //对应按钮K1
sbit K2 = P0^1; //对应按钮K2
main()
{
unsigned char key_s,key_v;
key_v = 0x03;//未按状态
P2 = 0xfe;
while(1)
{
  key_s = scan_key();
  if(key_s != key_v)
  {
   delayms(10);
   key_s = scan_key();
   if(key_s != key_v)
   {
    key_v = key_s;
    proc_key(key_v);     
   }
  }
}
}
unsigned char scan_key()  //读按键
{
unsigned char key_s;
key_s = 0x00;
key_s |= K2;//读取2号按键上的值
key_s <<= 1;//左移一位     
key_s |= K1;//读取1号按键上的值
return key_s;  
}
void proc_key(unsigned char key_v) //移动亮灯
{
if((key_v & 0x01) == 0)
{
  P2 = _cror_(P2,1);
}
else if((key_v & 0x02) == 0)
{
  P2 = _crol_(P2, 1);
}
}
void delayms(unsigned char ms)  // 延时子程序
{      
unsigned char i;
while(ms--)
{
  for(i = 0; i < 120; i++);
}
主要不懂的就是主函数中的while语句中,在key_v = key_s;
之后的循环中,并未再改变key_v的值,那么以后比较key_s与key_v时是怎么比较的?麻烦大家帮忙讲解分析一下循环语句中的具体内容,谢谢!!

}

相关帖子

沙发
NE5532| | 2012-3-24 16:05 | 只看该作者
楼主把每一行都加上注释看看呢。

使用特权

评论回复
板凳
XUYI-011| | 2012-3-24 16:15 | 只看该作者
加上注释看看

使用特权

评论回复
地板
810629123|  楼主 | 2012-3-24 16:26 | 只看该作者
2# NE5532 是要单独的隐去每一句然后再试试效果吗?

使用特权

评论回复
5
810629123|  楼主 | 2012-3-24 16:35 | 只看该作者
2# NE5532 我自己又写了一个,修改了while语句如下
while(1)
{
  key_s = scan_key();
  delayms(1000);
  if(key_s!=key_v)
  proc_key(key_s);
}
}
和读按键程序,如下
unsigned char scan_key()
{
unsigned char key_s;
key_s = 0x00;
if(!K2)
  key_s=0xfe;
if(!K1)
  key_s=0xfd;
return key_s ;
}
和移动亮灯程序
void proc_key(unsigned char key_s) //移动亮灯
{
if(key_s  ==0xfe )
{
  P2 = _cror_(P2,1);
}
else if(key_s  == 0xfd)
{
  P2 = _crol_(P2, 1);
}
while语句中的延时函数改了大一些,因为发现太小容易使按键反映时间太敏捷,导致按一下移过多位。改过后基本功能可以实现。现在就是不理解原程序中的while部分。帮忙讲解一下,谢谢!!
}

使用特权

评论回复
6
NE5532| | 2012-3-24 21:39 | 只看该作者
2# NE5532  是要单独的隐去每一句然后再试试效果吗?
810629123 发表于 2012-3-24 16:26


我是建议你把每一行后面写个注释,说明这一行是在做什么哈。

使用特权

评论回复
7
NE5532| | 2012-3-24 21:40 | 只看该作者
比如
delayms(1000);      //因为…………所以加入延时1S

而不是简单地说

delayms(1000);     //延时1S

使用特权

评论回复
8
810629123|  楼主 | 2012-3-25 18:21 | 只看该作者
7# NE5532 哦,知道了,非常感谢!

使用特权

评论回复
9
1328616904| | 2012-4-4 21:36 | 只看该作者
while(1)
{
  key_s = scan_key();
  if(key_s != key_v)//如果不相等则执行下面语句
  {
   delayms(10);//延时去抖动
   key_s = scan_key();//再次读取并赋值
   if(key_s != key_v)//如果不相等则执行下面语句
   {
    key_v = key_s;//这次确定真的有按键按下了
    proc_key(key_v); //读取数据   
   }

使用特权

评论回复
10
1328616904| | 2012-4-4 21:37 | 只看该作者
while(1)
{
  key_s = scan_key();
  if(key_s != key_v)//如果不相等则执行下面语句
  {
   delayms(10);//延时去抖动
   key_s = scan_key();//再次读取并赋值
   if(key_s != key_v)//如果不相等则执行下面语句
   {
    key_v = key_s;//这次确定真的有按键按下了
    proc_key(key_v); //读取数据   
   }

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

58

帖子

1

粉丝