OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2947|回复: 1

stm32按键扫描

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2018-8-6
在线时间
2 小时
发表于 2018-8-6 09:25:03 | 显示全部楼层 |阅读模式
1金钱
各位,  写了一个按键扫描的,通过按键长短实现不同操作,但是按键没响应,想帮忙看看问题在哪儿?谢谢
//bsp_key.h
=======================================================
#ifndef BSP_KEY_H_
#define BSP_KEY_H_

#include "stm32f10x.h"

//reset pin                                       
#define RESET_PIN                                GPIO_Pin_8                //PA8
#define RESET_PORT                        GPIOA
#define reset_check                        (!GPIO_ReadInputDataBit(RESET_PORT, RESET_PIN))

#define NULL_KEY                              0
#define SHORT_KEY                                1
#define LONG_KEY                                2

uint8_t reset_needed(void);

uint8_t key_scan(void);

void key_service(void);

void EXTI9_5_IRQHandler(void);
void TIM3_IRQHandler(void);
void KEY_NVIC_Init(void);
void Timerx_Init(uint16_t arr, uint16_t psc);
void KEY_GPIO_Config(void);

#endif


//bsp_key.c
========================================================
#include "./key/bsp_key.h"
#include "./led/bsp_led.h"


uint32_t pending_time = 0;
uint8_t key_down_flag = 0;

uint8_t reset_needed(void)
{
  return reset_check;
}

uint8_t key_scan(void)
{
        uint8_t ret = NULL_KEY;
       
  if( key_down_flag == 1 )
  {
    if( pending_time < 6 ) //按键扰动
    {
      pending_time  = 0;
      key_down_flag = 0;
      ret = NULL_KEY;
    }
    else if( pending_time >= 6 && pending_time < 400 ) //short key
    {
      pending_time  = 0;
      key_down_flag = 0;
      ret =  SHORT_KEY;
    }
    else if( pending_time >= 400 )  //long key
    {
      pending_time  = 0;
      key_down_flag = 0;
      ret =  LONG_KEY;
    }
  }
               
  return ret;
}

void key_service(void)
{
        switch(key_scan())
        {
                case NULL_KEY:
                        break;
                case SHORT_KEY:
                        LED2(ON);
                        //修改参数
                        break;
                case LONG_KEY:
                        LED3(ON);
                        //当前配置参数字符闪烁/滚动
                        break;
                default:
                        break;
        }
}

void EXTI9_5_IRQHandler(void)
{
    if( EXTI_GetITStatus(EXTI_Line8) != RESET ) //PA8
    {
        EXTI_ClearITPendingBit(EXTI_Line8);
        if( reset_needed() ) //press key
        {
            key_down_flag = 1;
        }
        else
        {
            pending_time = 0;
            key_down_flag = 0;
        }
    }
}

void TIM3_IRQHandler(void)
{
    if( TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(TIM3, TIM_FLAG_Update);
        pending_time++;
    }
}

//注意优先级不能超过设定的组的范围!否则会有意想不到的错误
//组划分:stm32 4bits
//组0:0位抢占优先级,4位响应优先级
//组1:1位抢占优先级,3位响应优先级
//组2:2位抢占优先级,2位响应优先级
//组3:3位抢占优先级,1位响应优先级
//组4:4位抢占优先级,0位响应优先级
//NVIC_SubPriority和NVIC_PreemptionPriority的原则是,数值越小,越优先
void KEY_NVIC_Init(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
#if(0)
        EXTI_InitTypeDef EXTI_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //开启 AFIO 时钟
                                                    //GPIOA.8 中断线以及中断初始化配置,下降沿触发
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource8);
        EXTI_InitStructure.EXTI_Line    = EXTI_Line8;
        EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure); //初始化中断线参数
#endif
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        NVIC_InitStructure.NVIC_IRQChannel                                                                    = TIM3_IRQn; //EXTI9_5_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;     //抢占优先级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0x03;     //子优先级
        NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}

void Timerx_Init(uint16_t arr, uint16_t psc)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

        TIM_TimeBaseStructure.TIM_Period        = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值,10kHz,计数到100为10ms(T=1/f=0.1ms)
  TIM_TimeBaseStructure.TIM_Prescaler     = (psc-1); //预分频值,10Khz的计数频率(72MHz/7200=10kHz)
  TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
  TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;  //TIM向上计数模式
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
       
        TIM_ITConfig(TIM3, TIM_IT_Update|TIM_IT_Trigger, ENABLE); //更新中断+触发中断
       
  KEY_NVIC_Init();       
  TIM_Cmd(TIM3, ENABLE);
}

void KEY_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;  //定义GPIO结构体       

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOB口时钟
        //将PB0配置为推挽输出
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //50M时钟速度
        GPIO_Init(GPIOB, &GPIO_InitStructure);

}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4521
金钱
4521
注册时间
2018-5-11
在线时间
946 小时
发表于 2018-8-6 10:28:04 | 显示全部楼层
这个有点太复杂了,参考三行键盘程序,搜索一下。
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-18 01:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表