打印

4键控制LED0~7为何总不行 小白求好人指教

[复制链接]
3908|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
STM29|  楼主 | 2013-5-10 15:52 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
//用的是STM32F103C6  KEIL
//这个是正确的4键控制LED0~3(LED1~4) 能够得出结果

u8 KEY_Scan(void)
{         
        static u8 key_up=1;//按键按松开标志       

        if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3 ==0))
        {
                delay_ms(10);//去抖动
                key_up=0;
                if(KEY0==0)
                {
                        return 1;
                }
                else if(KEY1==0)
                {
                        return 2;
                }
                else if(KEY2==0)
                {
                        return 3;
                }
                else if(KEY3 ==0)
                {
                        return 4;
                }
        }else if(KEY0==1&&KEY1==1&&KEY2==1&&KEY3 ==1)key_up=1;             
        return 0;// 无按键按下
}

//这是自己编写的4键控制LED0~7  其中KEY0是转换位 KEY1~3的输入组合对应 八个灯 下载后无法达到要求

u8 KEY_Scan(void)
{         
        static u8 key_up=1;//按键按松开标志
        u8 ide=0,key_toggle;
        key_toggle=KEY0;
          
    while(key_toggle)
        {
      if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3 ==0))
          {
                delay_ms(10);//去抖动
                if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3 ==0))
                {
                         if(KEY3==0)
                         {
                                  ide=ide | 0x04; key_up=0;
                         }
                         else if(KEY2==0)
                         {
                            ide=ide | 0x02;key_up=0;
                         }
                         else if(KEY1==0)
                         {
                            ide=ide | 0x01;key_up=0;
                         }
                }                
          }
          else
           {  key_up=1; }            
    }
   return ide;                                                          
}

int main(void)
{
        u8 t;       
        SystemInit();                   //系统时钟设置
        delay_init(72);             //延时初始化
        NVIC_Configuration();//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        LED_Init();                         //初始化与LED连接的硬件接口
        KEY_Init();                         //初始化与按键连接的硬件接口
        while(1)                    
        {
                t=KEY_Scan();//得到键值
                   if(t)
                {                                                  
                        switch(t)
                        {                                 
                                case 1:
                                        LED0=0;
                                        break;
                                case 2:
                                        LED1=0;
                                        break;
                                case 3:                               
                                        LED2=0;
                                        break;
                                case 4:
                                        LED3=0;
                                        break;
                                case 5:
                                        LED4=0;
                                        break;
                                case 6:
                                        LED5=0;
                                        break;
                                case 7:
                                        LED6=0;
                                        break;
                                case 8:
                                        LED7=0;
                                        break;
                        }
                }else delay_ms(10);
        }         

}       

沙发
cjhk| | 2013-5-10 18:48 | 只看该作者
程序注释一下   楼主   这样大家查起来   比较靠谱   应该问题不是很大   楼主

使用特权

评论回复
板凳
艺术家58| | 2013-5-10 20:45 | 只看该作者
本帖最后由 艺术家58 于 2013-5-10 20:49 编辑

KEYX==0是表示有按键,
        key_toggle=KEY0;
           
    while(key_toggle)
KEY0被按下ide就没有被赋值,它的返回值就是0

你可以对返回值做位操作
KEY0按下,对应第3位置1;KEY1按下,对应第2位置1;KEY2按下,对应第1位置1;KEY3按下,对应第0位置1。

使用特权

评论回复
地板
STM29|  楼主 | 2013-5-11 17:24 | 只看该作者
艺术家58 发表于 2013-5-10 20:45
KEYX==0是表示有按键,
        key_toggle=KEY0;
           

开始是他们都key_init();然后KEYX==1(这样应该没错吧 因为控制4灯那个程序 那里就可以执行);
KEY0==1然后key_toggle也是==1 就可以执行那个while了  输入就是按KEY1~3这个三个键  按一次KEY0(KEY0==0) 这是不执行while 就return ide 了。

您说的是ide=((KEY3 << 3) | (KEY2 << 2) | (KEY1 << 1) | KEY0) & 0x0f;这样做?

使用特权

评论回复
5
STM29|  楼主 | 2013-5-11 17:33 | 只看该作者
艺术家58 发表于 2013-5-10 20:45
KEYX==0是表示有按键,
        key_toggle=KEY0;
           


u8 KEY_Scan(void)
{         
        static u8 key_up=1;//按键按松开标志
        u8 ide=0,key_toggle;
        key_toggle=KEY0;
           
    while(key_toggle)      /*因为初始话 让他们KEY值都为1,然后用KEY0来控制其他三个KEY的输入输出
                              刚开始key_toggle==1 KEY1~3输入  如果按次KEY0(KEY==0)这是输出ide
                           */
        

{
      if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3 ==0))
          {
                delay_ms(10);//去抖动
                if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3 ==0))
                {
                         if(KEY3==0)
                         {
                                  ide=ide | 0x04; key_up=0;      //KEY3为第三位,KEY2为第二位,KEY1为第一位
                         }
                         else if(KEY2==0)                        //这时看是否有第二位的值
                         {
                            ide=ide | 0x02;key_up=0;            
                         }
                         else if(KEY1==0)                        //这时看是否有第一位的值
                         {
                            ide=ide | 0x01;key_up=0;             //这样ide就有KEY1~3的状态值
                         }                                       //这样就能实现八个灯的值
                }                 
          }
          else
           {  key_up=1; }            
    }
   return ide;                                                           
}

使用特权

评论回复
6
艺术家58| | 2013-5-11 19:07 | 只看该作者
while(key_toggle)
{
}
循环的退出条件呢

使用特权

评论回复
7
STM29|  楼主 | 2013-5-11 19:31 | 只看该作者
艺术家58 发表于 2013-5-11 19:07
while(key_toggle)
{
}

然后再按一次KEY0(key_toggle==0) 这是就退出while了 是不是哦?

使用特权

评论回复
8
艺术家58| | 2013-5-11 20:16 | 只看该作者
你要是不想在循环里改变key_toggle的值,你就把
while(key_toggle)
{
}
换成
while(KEY0)
{
}
你调试看看

使用特权

评论回复
9
STM29|  楼主 | 2013-5-11 20:31 | 只看该作者
艺术家58 发表于 2013-5-11 20:16
你要是不想在循环里改变key_toggle的值,你就把
while(key_toggle)
{

收到!好的, 我明天去实验室板子下进去看看哦

使用特权

评论回复
10
grasswolfs| | 2013-5-11 23:59 | 只看该作者
STM29 发表于 2013-5-11 20:31
收到!好的, 我明天去实验室板子下进去看看哦

嗯,KEY0是按键值,可以变化,而key_toggle是变量,进入这个函数之后就阻塞在这里了,建议还是采用轮询方式比较好

使用特权

评论回复
11
STM29|  楼主 | 2013-5-14 09:56 | 只看该作者
STM29 发表于 2013-5-11 20:31
收到!好的, 我明天去实验室板子下进去看看哦

这个方法还是不可以。:'( 难道不能4键控制8灯?

使用特权

评论回复
12
STM29|  楼主 | 2013-5-14 10:02 | 只看该作者
STM29 发表于 2013-5-14 09:56
这个方法还是不可以。 难道不能4键控制8灯?

哥 您能写一个我对比下哪里出错了吗? 谢谢了哥。这个代码修改得都不会再爱了。

使用特权

评论回复
13
grasswolfs| | 2013-5-14 12:07 | 只看该作者
本帖最后由 grasswolfs 于 2013-5-14 12:09 编辑
STM29 发表于 2013-5-14 10:02
哥 您能写一个我对比下哪里出错了吗? 谢谢了哥。这个代码修改得都不会再爱了。 ...

KEY0的定义是什么?是define的管脚么?一般不要在子函数里面就用while循环,这种阻塞的程序显然不好用,有仿真么?

使用特权

评论回复
14
grasswolfs| | 2013-5-14 12:15 | 只看该作者
STM29 发表于 2013-5-14 10:02
哥 您能写一个我对比下哪里出错了吗? 谢谢了哥。这个代码修改得都不会再爱了。 ...

scan就返回当前键值,然后主函数里面整合逻辑,现在逻辑太乱了,都不知道怎么按键的

使用特权

评论回复
15
grasswolfs| | 2013-5-14 12:18 | 只看该作者
STM29 发表于 2013-5-14 10:02
哥 您能写一个我对比下哪里出错了吗? 谢谢了哥。这个代码修改得都不会再爱了。 ...

你的逻辑是不是这样的:
按下按键0,进入准备状态,按下按键1,2,3,分别对应二进制的三位,最后按下按键0,按键结束,点亮LED,是这样的么?

使用特权

评论回复
16
艺术家58| | 2013-5-14 13:28 | 只看该作者
key_up提前置零了,就只能置一个位了。KEY0按下时再将key_up置零,这样别的位就可以重复置位了。感觉楼主是从电脑编程转到单片机编程的:lol

使用特权

评论回复
17
grasswolfs| | 2013-5-14 19:54 | 只看该作者
艺术家58 发表于 2013-5-14 13:28
key_up提前置零了,就只能置一个位了。KEY0按下时再将key_up置零,这样别的位就可以重复置位了。感觉楼主是 ...

为什么这么说呢?电脑编程和单片机编程有本质不同么?

使用特权

评论回复
18
STM29|  楼主 | 2013-5-14 21:12 | 只看该作者
grasswolfs 发表于 2013-5-14 12:18
你的逻辑是不是这样的:
按下按键0,进入准备状态,按下按键1,2,3,分别对应二进制的三位,最后按下按键0 ...

刚开始 因为初始化了嘛 然后就认为KEY0是=1 然后 KEY0不动  按下KEY1.2.3 然后后面就跟您说的一样  

使用特权

评论回复
19
STM29|  楼主 | 2013-5-14 21:19 | 只看该作者
艺术家58 发表于 2013-5-14 13:28
key_up提前置零了,就只能置一个位了。KEY0按下时再将key_up置零,这样别的位就可以重复置位了。感觉楼主是 ...

哥 您猜对了!!:lol   然后您说的这个逻辑是不是 因为我if里面的key_up 程序里 让我给key_up=0;  然后程序走不下去又被重复置位了?

使用特权

评论回复
20
dream_yi| | 2013-5-15 00:04 | 只看该作者
很……的程序:1.按键消抖
                                     if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3 ==0))
                                         {
                                           delay_ms(10);//去抖动
                                           if(key_up&&(KEY0==0||KEY1==0||KEY2==0||KEY3 ==0))
                                          那key_toggle=KEY0;消抖哪去了?
                              2.   key_toggle=KEY0;
                                    while(key_toggle)
                                    赋值在while()下方,这怎么能跳出来呢?
                               3. 假设上面都没问题,你按了1,2,3,中的一个,t被赋值了,之后想要跳出来不是要按KEY0吗?按了之后呢?
                                    返回什么了?

使用特权

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

本版积分规则

3

主题

21

帖子

1

粉丝