刚学,不明白为什么没有vdd,有脉冲,但是只有一个灯亮,第一个脉冲输出端只有高电平,其它的都是低电平,没有电平的高低变化,希望各位能看看应该怎么改才对
U2是怎么设置的?https://img-blog.csdnimg.cn/20210903165010556.gif
不知道你这个问题是否已经解决, 如果还没有解决的话:#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
/**********************************************************************/
#define KEY0_RCCclock RCC_AHB1Periph_GPIOE
#define KEY0_PinPort GPIOE
#define KEY0_WhichPin GPIO_Pin_2
#define KEY0_PinStatus GPIO_PuPd_UP //上拉
#define KEY0_shortPress Key0_ShortCallback
#define KEY0_longPress Key0_LongCallback
#define KEY1_RCCclock RCC_AHB1Periph_GPIOE
#define KEY1_PinPort GPIOE
#define KEY1_WhichPin GPIO_Pin_3
#define KEY1_PinStatus GPIO_PuPd_UP //上拉
#define KEY1_shortPress Key1_ShortCallback
#define KEY1_longPress Key1_LongCallback
/**********************************************************************/
#define KEY_MAXNUM 4 //最大按键数
#define KEY_TIMER_MS 2 //扫描时间间隔
#define KEY_DELAY_MS 10 //消抖完成标志位
#define KEY_PRESS_STATUS 0 //即按下标志位
#define KEY_LONG_STATUS (1000/KEY_DELAY_MS*3) //即按下3s及判定为长按
#define KEY_DOUBLE_HIT_MAX (100/KEY_DELAY_MS*3) //连击判定时间最大值为300ms
//#define KEY_DOUBLE_HIT_MIN (100/KEY_DELAY_MS*1) //连击判定事件最小值为100ms
/**********************************************************************/
#define KEY_NODOWN 0x0000 //无按键按下
#define KEY_DOWN 0x1000 //有按键按下
#define KEY_UP 0x2000 //按键短按标志位
#define KEY_LIAN 0x4000 //按键连按标志位
#define KEY_LONG 0x8000 //按键长按标志位
/**********************************************************************/
/*
这三个函数的作用分别是:
1、设置a某一位的值 G_SET_BIT
2、清楚a某一位的值 G_CLEAR_BIT
3、获得a某一位的值 G_IS_BIT_SET
*/
#define G_SET_BIT(a,b) (a |= (1 << b))
#define G_CLEAR_BIT(a,b) (a &= ~(1 << b))
#define G_IS_BIT_SET(a,b) (a & (1 << b))
/**********************************************************************/
//定义了一个回调指针,即根据发生的事件,
typedef void (*KeyCallback_Pointer) (void);
/**********************************************************************/
//单个按键对象结构体
__packed typedef struct
{
uint8_t Key_Num;//共有多少个按键对象
uint32_t Key_RccPeriphConfig;//按键对象时钟
GPIO_TypeDef* KeyPort;//按键所在IO口组
uint32_t Key_WhichPin;//第几个IO引脚
GPIOPuPd_TypeDef Key_PinStatus;//IO引脚的状态
KeyCallback_Pointer shortPress;//定义一个函数指针指向短按回调函数
KeyCallback_Pointer longPress;//定义一个函数指针指向长按回调函数
}keyTypeDef_t;//单个按键对象结构体!
/**********************************************************************/
//多个按键对象结构体(总)
__packed typedef struct
{
u8 KeyTotolNum; //按键总数累计
keyTypeDef_t* singleKey;//按键对象的指针!
}keysTypeDef_t;//多个按键对象结构体!
/**********************************************************************/
//双击枚举!
typedef enum {Keyd_Wait_Flag = 0,Keyd_End_Flag = 1,Keyd_IDLE_Flag = 2}keyd_Status;
//双击结构体!
typedef struct
{
keyd_Status Keyd_Flag;
uint16_t First_KeyVal;
uint16_t Key_Double_Hit_Count;
}Keyd_t;
/**********************************************************************/
extern u32 key_down;//声明外部变量,表示按键长短按及哪一个按键
extern keysTypeDef_t keys;
extern Keyd_t keyd;
void Key_Init(void);
void Key0_ShortCallback(void);
void Key0_LongCallback(void);
void Key1_ShortCallback(void);
void Key1_LongCallback(void);
void Key_Scan_TimeConfig(void);
uint16_t keyGet(keysTypeDef_t* keys_t);
void Key_Handle_Task(void);
#endif
最上面的和KEY0/KEY1处理有关的宏定义即是把底层抽离的方式之一,在移植的过程中,只需要修改宏定义即可完成对不同的IO口的初始化。而有关按键处理的函数我们并不需要去做处理,初始化按键处理后,只需要去判断 u32 key_down的不同的位,即可获得当前按键的各种状态。这里说一下key_down这个变量,我假定最多按键处理为4个,那么32位便以4分区,可以分成8各区域,那么每个区域即可标识不同的状态位,这里可以根据项目需求去做更改这个变量的不同位。
/
key_down 共有32位,这里把它分割成不同的区域:
0-3 : 预留区域,这里最多定义4个按键,哪个为1表示状态“绑定”在哪个按键上面
4-7 : 短按判断区,这里最多判断4个,哪个按键在触发短按事件,哪个位置1
8-11 : 长按判断区,这里最多判断4个,哪个按键在触发长按事件,哪个位置1
12-15 : 连击判断区,这里最多判断4个,哪个按键在触发连击事件,哪个位置1
/
从宏定义可以看出,这里是把按键这个事件当成一个类,类对应到单片机上每个按键IO口时,即为实例化了一个按键对象。我们需要几个按键,就去实例化几个IO口即可。每个对象都有两个函数指针,当对应状态产生时,即可调用初始化过程中的函数指针指向的函数。这里编程思想比较类似于C++,只是没有区分共有私有之类的数据部分。函数指针即为公共接口,需要自己去编写。这里我虽然在初始化时规定了指向,但是并没有编写接口(回调)函数,而是直接判断key_down 的相应位去判断按键状态。