打印

求助stm32 按钮扫描问题

[复制链接]
4270|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
momonivvuu|  楼主 | 2011-8-18 21:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
很奇怪,我用仿真器时可以采样到按钮的状态,不仿真直接上电跑的话就不成
我吧代码贴上吧
#define DK1_H {GPIOE->BSRR = GPIO_Pin_2;}
#define DK1_L {GPIOE->BRR = GPIO_Pin_2;}
#define DK2_H {GPIOE->BSRR = GPIO_Pin_3;}
#define DK2_L {GPIOE->BRR = GPIO_Pin_3;}
#define DK3_H {GPIOE->BSRR = GPIO_Pin_4;}
#define DK3_L {GPIOE->BRR = GPIO_Pin_4;}
#define DK4_H {GPIOE->BSRR = GPIO_Pin_5;}
#define DK4_L {GPIOE->BRR = GPIO_Pin_5;}
#define SK1_PIN (GPIOB->IDR & GPIO_Pin_5)
#define SK2_PIN (GPIOB->IDR & GPIO_Pin_6)
#define SK3_PIN (GPIOB->IDR & GPIO_Pin_7)
#define SK4_PIN (GPIOB->IDR & GPIO_Pin_8)

/*管脚初始化*/
void  key_init(void)
{ //管脚初始化
//PE2  -  5
GPIO_InitTypeDef GPIO_InitStructure;   
//GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2 | GPIO_Pin_3 |GPIO_Pin_4 | GPIO_Pin_5;
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//GPIO_Init(GPIOE, &GPIO_InitStructure);
//PB5  -   8
GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5 | GPIO_Pin_6 |GPIO_Pin_7 | GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*PIN  状态保持延时*/
void key_delay(void)
{
    u16 i;
   
for(i = 0;i < 400;i++)
   {
    ;
   }
}
/*
按键输出管脚选择
keynum:范围 1 - 4
  1  DK1  H
  2  DK2  H
  3  DK3  H
  4  DK4  H
  OTHER  ALL  OUT  L
*/
void key_out_select(u8 keynum)
{ //推免输出保护,硬件无二极管保护
//PE2  -  5
GPIO_InitTypeDef GPIO_InitStructure;   
GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2 | GPIO_Pin_3 |GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOE, &GPIO_InitStructure);
  key_delay();
  switch(keynum)
  {
   case 1:
   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_2;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_Init(GPIOE, &GPIO_InitStructure);
   DK1_H;
   break;
  case 2:
   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_3;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_Init(GPIOE, &GPIO_InitStructure);
   DK2_H;
   break;
  case 3:
   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_Init(GPIOE, &GPIO_InitStructure);
   DK3_H;
   break;
  case 4:
   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_Init(GPIOE, &GPIO_InitStructure);
   DK4_H;
   break;
  default:
   break;
  }
  key_delay();
  key_delay();
}
/*SK1--4  状态判别
返回:SK1  PIN  H    or 1
   SK2  PIN  H    or 2
   SK3  PIN  H    or 4
   SK4  PIN  H    or 8
   OTHER          or 0
*/
u16  key_in_status(void)
{
u16  status;
status = 0;
if(SK1_PIN != 0)
  status |= 1;
if(SK2_PIN != 0)
  status |= 2;
if(SK3_PIN != 0)
  status |= 4;
if(SK4_PIN != 0)
  status |= 8;
return(status);
}
/*
输入:按钮状态
输出:只有1个按钮按下   1
    大于1个按钮按下   0
*/
u8 key_status_jug(u16 status)
{
   u8 i,result,count;
   u16 iand;
   count = 0;
   result = 0;
   iand = 1;
   for(i=1;i<17;i++)
   {
   if((status & iand) != 0)   
    count++;
   iand = iand << 1;
   }  
   if (count == 1)
     result =1; //有且只有1个按下为有效
   return(result);
}


/*按键扫描采样子程序
状态保存表如下
    DK4  |   DK3    |    DK2    |    DK1
SK4 SK3 SK2 SK1 |  SK4 SK3 SK2 SK1 |  SK4 SK3 SK2 SK1 |  SK4 SK3 SK2 SK1
15   14  13  12     11  10  9   8      7   6   5   4      3    2   1  0
*/
void key_sample_sub(void)
{ u8 i;
u16 i_status=0;
u16 test;
test = tbt_time_dwd - key_time_dwd;
if(test>=key_sample_delay)
{//20ms采样一次
    key_time_dwd =  tbt_time_dwd;
    for(i=1;i<5;i++)
    {  //取得16个按键状态
        i_status = i_status << 4;
     key_out_select(i);
     i_status |= key_in_status();
    }
    key_count++;
    if(i_status == 0)
    {
     key_count = 0;//无按键动作 复位
     key_status = 0;
    }
    else
    {//有按键按下
       if(i_status == key_status)
    { //近两次采样状态一致
       if (key_status_jug(i_status)==1)
      {
       if(key_count >= key_lvbo_delay)
         {
        if(key_count == key_lvbo_delay)
         {
         标志寄存器_key_test = 1;
       key_test_time_dwd = tbt_time_dwd;
         key_result = i_status; //取得结果  按下有效 弹出释放
        }
        key_count = key_lvbo_delay+1;
      }
    }
     else
      {
        key_count = 0;
       key_status = 0;
      }
    }
    else
    {
      key_count = 0;
    key_status = i_status;
    }
    }
}
}
沙发
momonivvuu|  楼主 | 2011-8-18 21:53 | 只看该作者
现在又好了,把void key_delay(void)
{
    u16 i;
   
for(i = 0;i < 400;i++)
   {
    ;
   }
}

使用特权

评论回复
板凳
momonivvuu|  楼主 | 2011-8-18 21:53 | 只看该作者
黄色的400改大点就好了

使用特权

评论回复
地板
acgean| | 2011-8-19 11:55 | 只看该作者
楼主的这个按键扫描处理, 很笨呀.
这个delay 消耗了好多的时间哦. 那么多是时间资源让 delay 给消耗了.
是否考虑用定时器触发按键扫描呢?

使用特权

评论回复
5
momonivvuu|  楼主 | 2011-8-20 22:03 | 只看该作者
回复4楼,这个delay()是为了延时等待管教状态稳定啊
我是用定时器触发的啊,每20ms采样一次啊

使用特权

评论回复
6
momonivvuu|  楼主 | 2011-8-20 22:05 | 只看该作者
test = tbt_time_dwd - key_time_dwd;
if(test>=key_sample_delay)
tbt_time_dwd在2ms定时器中断中累加的啊,主循环中判断时间到否再进行按键扫描的啊

使用特权

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

本版积分规则

3

主题

18

帖子

1

粉丝