新手入门
- 积分
- 6
- 金钱
- 6
- 注册时间
- 2018-8-6
- 在线时间
- 2 小时
|
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);
}
|
|