前言
- 本人为STM32新手,水平有限。该4位触摸键程序肯定不是完美的,旨在学习分享的同时,获得大家的指导。
- 对于触摸按键,我也是初次使用,我手上的这块开发板为横向排列的4个触摸按键,采用的是TTP223芯片,因此无需处理防抖。
功能
本程序实现以下任一功能触发不同的动作:
- 任意键单击
- 任意键双击
- 任意键三击
- 任意键长按 1s
- 任意键长按 2s以上每隔 200ms
- 左滑 1 个键位
- 左滑 1 个键位并停留触摸 2s
- 左滑 2 个键位
- 左滑 2个键位并停留触摸 2s
- 左滑 3 个键位
- 左滑 3 个键位并停留触摸 2s
- 右滑 1 个键位
- 右滑 1 个键位并停留触摸 2s
- 右滑 2 个键位
- 右滑 2 个键位并停留触摸 2s
- 右滑 3 个键位
- 右滑 3 个键位并停留触摸 2s
设计思路
- 该按键程序驱动函数部分需要在主循环中不断扫描触摸按键的状态(暂未使用外部中断触发),而主循环中的程序应是尽量减少或不使用delay这样的延时。因此4个按键驱动采用了For循环判断按键的状态,全程不使用delay延时,需要用到的延时在TIM4定时器中断中用变量累加实现。
- 由于该按键具有多功能,因此按键的单击、双击、三击只能通按键的弹起检测来判断,并通过记录的弹起次数判断是单击还是双击或三击。
- 采用检测到2个键同时为低电平(按下)时为触滑状态,当全部按键为高电平时解除触滑状态。
- 通过记录触滑起始键位号与最后停留按压的键位号来判断当前是左滑还是右滑,左右滑动了几个键位。
程序代码
main.c
/**
*****************************************************************************
* @file main.c
* @hardware ---
* @chip STM32F103C8T6
* @expand 无
* @version V1.0
* @date 2022-04-9 周六
******************************************************************************
*/
/* includes ------------------------------------------------------------------*/
#include "config.h"
#include "i2c.h"
#include "oled_sh1106.h"
#include "tim.h"
#include "touch_key.h"
/* 变量定义 ------------------------------------------------------------------*/
/* 变量声明 ------------------------------------------------------------------*/
/* 函数声明 ------------------------------------------------------------------*/
/*******************************************************************************
* @brief 主函数.
* @param 无
* @retval 无
*/
int main(void)
{
delay_ms(200);
/*------------------------------ 上电初始化 -------------------------------*/
SYS_unite_config(); // 系统统一配置(RCC和中断优先级分组)
I2C1_init(); // 初始化 I2C1
oled_init(); // 初始化 OLED
TIM4_init(10, 7200); // 初始化 TIM4 设 1 ms 进中断
touchKey_init(); // 初始化 个触摸按键 A-D
/*-------------------------------- 主循环 ---------------------------------*/
while (1)
{
touchKey_driver();
}
}
/********************** (C) Copyright 2022 - End Of File **********************/
touchKey.c
void touchKeyAction(u8 keyCode) 中的内容为OLED显示测试按键响应的,实际应用时可根据需写入相应执行代码。
/**
******************************************************************************
* @file touch_key.c
* @hardware ---
* @chip STM32F103C8T6
* @expand 无
* @version V1.0
* @date 2022-04-17 周日
******************************************************************************
* @code -----------------------------------------------------------------
* | 代码 | 功能 || 代码 | 功能 |
* |-------------------------------||------------------------------|
* | 0xA0 | 触摸 A 键 按下 || 0xC0 | 触摸 C 键 按下 |
* | 0xA1 | 触摸 A 键 弹起 || 0xC1 | 触摸 C 键 弹起 |
* | 0xA2 | 触摸 A 键 长按 1s || 0xC2 | 触摸 C 键 长按 1s |
* | 0xA3 | 触摸 A 键 长按 2s || 0xC3 | 触摸 C 键 长按 2s |
* | 0xA4 | 触摸 A 键 右滑 1 || 0xC4 | 触摸 C 键 右滑 1 |
* | 0xA5 | 触摸 A 键 右滑 2 || 0xC7 | 触摸 C 键 左滑 1 |
* | 0xA6 | 触摸 A 键 右滑 3 || 0xC8 | 触摸 C 键 左滑 2 |
* | 0xAA | 触摸 A 键 单击 || 0xCA | 触摸 C 键 单击 |
* | 0xAB | 触摸 A 键 双击 || 0xCB | 触摸 C 键 双击 |
* | 0xAC | 触摸 A 键 三击 || 0xCC | 触摸 C 键 三击 |
* | 0xB0 | 触摸 B 键 按下 || 0xD0 | 触摸 D 键 按下 |
* | 0xB1 | 触摸 B 键 弹起 || 0xD1 | 触摸 D 键 弹起 |
* | 0xB2 | 触摸 B 键 长按 1s || 0xD2 | 触摸 D 键 长按 1s |
* | 0xB3 | 触摸 B 键 长按 2s || 0xD3 | 触摸 D 键 长按 2s |
* | 0xB4 | 触摸 B 键 右滑 1 || 0xD7 | 触摸 D 键 左滑 1 |
* | 0xB5 | 触摸 B 键 右滑 2 || 0xD8 | 触摸 D 键 左滑 2 |
* | 0xB7 | 触摸 B 键 左滑 1 || 0xD9 | 触摸 D 键 左滑 3 |
* | 0xBA | 触摸 B 键 单击 || 0xDA | 触摸 D 键 单击 |
* | 0xBB | 触摸 B 键 双击 || 0xDB | 触摸 D 键 双击 |
* | 0xBC | 触摸 B 键 三击 || 0xDC | 触摸 D 键 三击 |
* -----------------------------------------------------------------
*/
/* Includes ------------------------------------------------------------------*/
#include "touch_key.h"
#include "oled_sh1106.h"
/* 变量定义 ------------------------------------------------------------------*/
u16 touchKeyDownTime = 0; // 触摸键按下计时变量(ms)
u16 touchKeyUpTime = 0; // 触摸键弹起计时变量(ms)
u8 touchKeyDownFlag = 0; // 触摸按键按下标志位, 1 按下
u8 touchKeyUpFlag = 0; // 触摸键弹起标志位, 1 弹起
/**=============================================================================
* @brief 触摸按键初始化.
* @param 无
* @retval 无
*/
void touchKey_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; // 定义 GPIO_Init 结构体变量
// 触摸按键引脚 GPIOA 时钟,已在主函数开始调用 RCC_GPIO_config() 使能
GPIO_InitStructure.GPIO_Pin = KEY_PIN; // 选择引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入模式
GPIO_Init(KEY_PORT, &GPIO_InitStructure); // 初始化引脚
}
/**=============================================================================
* @brief 触摸按键动作响应函数(执行各键动作时需要执行的程序).
* @param u8 keyCode: 触摸按键功能码
* @retval None
*/
void touchKeyAction(u8 keyCode)
{
static u8 cnt = 0;
switch (keyCode)
{
// 触摸键 A
case 0xA0: oled_showString8x16(0, 0, "A0", 0); break;
case 0xA1: oled_showString8x16(0, 0, "A1", 0); break;
case 0xA2: oled_showString8x16(0, 0, "A2", 0); cnt = 0; break;
case 0xA3: oled_showChar8x16(80, 0, 'A', 0); cnt++; break;
case 0xA4: oled_showString8x16(104, 0, " A1", 0); cnt ++; break;