本帖最后由 andeyqi 于 2023-4-20 08:27 编辑
1.电容触摸按键的检测原理
首先我们来看下LPC845-BRK开发板的原理图,电容touch 按键部分如下(图1.1),从图中可以看出电容按键有四根引脚和mcu 相连,其中检测原理是什么?之前没有做过电容触摸按键的项目,对原理也不了解,我们带着这个问题尝试从用户开发手册(UM11029)中寻找答案。
图 1.1 按键检出原理是什么?
对于触摸按键的检测原理可以从图1.2(UM11029文档的26.3章节)找到答案,图1.1 上的的触摸按键从结构上看X和Y构成了一个电容C,从图1.2 的描述可知当手指或者触摸笔触碰到电容按键的时候就会对电容C进行充电,充电时X相当于于电容的负极,Y相当于电容的正极,Y极板上会聚集电量,当达到设定的阈值后C会进行放电,放完电后又会重复上述的充电过程,通过采集Y极触发阈值的放电次数来检测按键状态,因按下和非按下时这个次数是不同的从而完成按键状态的识别。
图 1.2
通过示波器抓取YH 引脚上的按下/抬起时的信号状态,从图 1.3 和 1.4 的对比可以看出,这两种状态下的充放电次数是不同的,CAP IP 模块将采集的计数值上报给用户供开发者识别按键状态。
图 1.3
图 1.4
原理图的CAPY_R PIN脚的作用?
从图一的原理图看硬件设计上Y的一路输出检测连接到了MCU的ACMP端口上了,看到这个设计时难免有些疑惑,这个脚的作用是什么呢?从图1.6 的截图中可知电容按键状态检测有两种模式一种是通过YH的电压检测另外一种就是通过ACMP的比较值触发检测。
2 .编码验证
了解上述的工作模式的区别后,本次实验我们不使用acmp 的方式,官方的sdk driver 驱动示例下已经包含了电容按键的示例程序,我们只要将X/YL/YH三个GPIO配置好后,把示例程序移植进工程即可,MCUXpresso IDE 工具自带GPIO功能配置工具可以方便我们生成IO配置的文件,添加对应的IO配置后就会自动根据配置的属性生成代码,会提高我们的开发效率,配置的属性和生成的代码如图2.1.
图 2.1
同理在图形界面下添加YL/YH引脚的配置即可完成引脚的路由配置。图 2.2
GPIO 引脚配置好后,我们将sdk 的驱动代码作为一个任务加入工程,结合之前的GPIO操作,检测到触摸按键按下后点亮板载LED,松开后熄灭LED.对应代码如下:
- /*
- * Copyright 2020 NXP
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include "pin_mux.h"
- #include "board.h"
- #include "fsl_capt.h"
- #include "fsl_debug_console.h"
- #include <stdbool.h>
- #include "fsl_power.h"
- #include "fsl_gpio.h"
- #include "FreeRTOS.h"
- #include "task.h"
- #include "drv_gpio.h"
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- #define DEMO_CAPT_BASE CAPT
- #define DEMO_CAPT_IRQn CMP_CAPT_IRQn
- #define DEMO_CAPT_IRQHandler CMP_CAPT_IRQHandler
- #define DEMO_CAPT_ENABLE_PINS kCAPT_X0Pin
- #define DEMO_CAPT_ENABLE_PINS_NUM 1
- #define DEMO_CAPT_CLOCK_FREQ CLOCK_GetFroFreq()
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- volatile uint16_t g_captRawData[DEMO_CAPT_ENABLE_PINS_NUM];
- volatile bool g_captPollDone;
- /*******************************************************************************
- * Code
- ******************************************************************************/
- /*!
- * @brief ISR for CAPT.
- */
- void DEMO_CAPT_IRQHandler(void)
- {
- uint32_t intStat;
- capt_touch_data_t s_captData;
- intStat = CAPT_GetInterruptStatusFlags(DEMO_CAPT_BASE);
- CAPT_ClearInterruptStatusFlags(DEMO_CAPT_BASE, intStat);
- /* If timeout happens, the board capt capacitor should be changed. */
- if (intStat &
- (kCAPT_InterruptOfYesTouchStatusFlag | kCAPT_InterruptOfNoTouchStatusFlag | kCAPT_InterruptOfTimeOutStatusFlag))
- {
- CAPT_GetTouchData(DEMO_CAPT_BASE, &s_captData);
- g_captRawData[s_captData.XpinsIndex] = s_captData.count;
- }
- if (intStat & kCAPT_InterruptOfPollDoneStatusFlag)
- {
- g_captPollDone = true;
- }
- }
- void capt_touch_init(void)
- {
- capt_config_t captConfig;
- uint32_t captClockFreq;
- PRINTF("CAPT basic continuous example.\r\n");
- /* Initialize CAPT module. */
- CAPT_GetDefaultConfig(&captConfig);
- /* Calculate the clock divider to make sure CAPT work in 2Mhz fclk. */
- captClockFreq = DEMO_CAPT_CLOCK_FREQ;
- captConfig.clockDivider = (captClockFreq / 2000000U - 1U);
- captConfig.enableXpins = DEMO_CAPT_ENABLE_PINS;
- /* The CAPT FCLK is set to 2MHz, the delay period between two polling rounds
- * is pollCount * 2096, setting pollCount to 250, then the polling round
- * frequency is about 2Hz, user can change this value to smaller value to
- * for faster polling round.
- */
- captConfig.pollCount = 250;
- CAPT_Init(DEMO_CAPT_BASE, &captConfig);
- /* Enable the interrupts. */
- CAPT_EnableInterrupts(DEMO_CAPT_BASE, kCAPT_InterruptOfYesTouchEnable | kCAPT_InterruptOfNoTouchEnable |
- kCAPT_InterruptOfTimeOutEnable | kCAPT_InterruptOfPollDoneEnable);
- NVIC_EnableIRQ(DEMO_CAPT_IRQn);
- /* Set polling mode and start poll. */
- CAPT_SetPollMode(DEMO_CAPT_BASE, kCAPT_PollContinuousMode);
- }
- /*!
- * @brief Main function
- */
- int capt_touch_main(void *pvParameters)
- {
- int pin = lpc84x_pin_get("P1.1");
- lpc84x_pin_mode(pin,PIN_MODE_OUTPUT);
- while (1)
- {
- while (!g_captPollDone)
- {
- vTaskDelay(1);
- }
- if(g_captRawData[0] > 60)
- {
- lpc84x_pin_write(pin,0);
- }
- else
- {
- lpc84x_pin_write(pin,1);
- }
- /* Output the captured data. */
-
- g_captPollDone = false;
- }
- }
复制代码
3.下载验证
=================代码如下=================
=================使用文档在此贴资料区=================
|