请选择 进入手机版 | 继续访问电脑版
查看: 711|回复: 4

[原创] 【LPC845-BRK板卡试用申请】(六)电容触摸按键控制LED

[复制链接]
  • TA的每日心情
    奋斗
    4 小时前
  • 签到天数: 578 天

    [LV.9]以坛为家II

    49

    主题

    2143

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    6727
    最后登录
    2024-3-29
    发表于 2023-4-15 01:10:01 | 显示全部楼层 |阅读模式
    本帖最后由 andeyqi 于 2023-4-20 08:27 编辑

    1.电容触摸按键的检测原理

    首先我们来看下LPC845-BRK开发板的原理图,电容touch 按键部分如下(图1.1),从图中可以看出电容按键有四根引脚和mcu 相连,其中检测原理是什么?之前没有做过电容触摸按键的项目,对原理也不了解,我们带着这个问题尝试从用户开发手册(UM11029)中寻找答案。
    cap_touch.png

    图 1.1
    按键检出原理是什么?
    对于触摸按键的检测原理可以从图1.2(UM11029文档的26.3章节)找到答案,图1.1 上的的触摸按键从结构上看X和Y构成了一个电容C,从图1.2 的描述可知当手指或者触摸笔触碰到电容按键的时候就会对电容C进行充电,充电时X相当于于电容的负极,Y相当于电容的正极,Y极板上会聚集电量,当达到设定的阈值后C会进行放电,放完电后又会重复上述的充电过程,通过采集Y极触发阈值的放电次数来检测按键状态,因按下和非按下时这个次数是不同的从而完成按键状态的识别。
    cap_touch_overview.png

    图 1.2

    通过示波器抓取YH 引脚上的按下/抬起时的信号状态,从图 1.3 和 1.4 的对比可以看出,这两种状态下的充放电次数是不同的,CAP IP 模块将采集的计数值上报给用户供开发者识别按键状态。


    touch_a.jpg

    图 1.3

    touch_b.jpg

    图 1.4

    原理图的CAPY_R PIN脚的作用?

    从图一的原理图看硬件设计上Y的一路输出检测连接到了MCU的ACMP端口上了,看到这个设计时难免有些疑惑,这个脚的作用是什么呢?从图1.6 的截图中可知电容按键状态检测有两种模式一种是通过YH的电压检测另外一种就是通过ACMP的比较值触发检测。
    acmp.png
    图 1.5



    2 .编码验证
    了解上述的工作模式的区别后,本次实验我们不使用acmp 的方式,官方的sdk driver 驱动示例下已经包含了电容按键的示例程序,我们只要将X/YL/YH三个GPIO配置好后,把示例程序移植进工程即可,MCUXpresso IDE  工具自带GPIO功能配置工具可以方便我们生成IO配置的文件,添加对应的IO配置后就会自动根据配置的属性生成代码,会提高我们的开发效率,配置的属性和生成的代码如图2.1.
    mex.png

    图 2.1

    同理在图形界面下添加YL/YH引脚的配置即可完成引脚的路由配置。
    capioconfig.png
    图 2.2

    GPIO 引脚配置好后,我们将sdk 的驱动代码作为一个任务加入工程,结合之前的GPIO操作,检测到触摸按键按下后点亮板载LED,松开后熄灭LED.对应代码如下:

    1. /*
    2. * Copyright 2020 NXP
    3. * All rights reserved.
    4. *
    5. * SPDX-License-Identifier: BSD-3-Clause
    6. */

    7. #include "pin_mux.h"
    8. #include "board.h"
    9. #include "fsl_capt.h"
    10. #include "fsl_debug_console.h"

    11. #include <stdbool.h>
    12. #include "fsl_power.h"
    13. #include "fsl_gpio.h"
    14. #include "FreeRTOS.h"
    15. #include "task.h"
    16. #include "drv_gpio.h"


    17. /*******************************************************************************
    18. * Definitions
    19. ******************************************************************************/
    20. #define DEMO_CAPT_BASE            CAPT
    21. #define DEMO_CAPT_IRQn            CMP_CAPT_IRQn
    22. #define DEMO_CAPT_IRQHandler      CMP_CAPT_IRQHandler
    23. #define DEMO_CAPT_ENABLE_PINS     kCAPT_X0Pin
    24. #define DEMO_CAPT_ENABLE_PINS_NUM 1
    25. #define DEMO_CAPT_CLOCK_FREQ      CLOCK_GetFroFreq()

    26. /*******************************************************************************
    27. * Prototypes
    28. ******************************************************************************/

    29. /*******************************************************************************
    30. * Variables
    31. ******************************************************************************/
    32. volatile uint16_t g_captRawData[DEMO_CAPT_ENABLE_PINS_NUM];
    33. volatile bool g_captPollDone;

    34. /*******************************************************************************
    35. * Code
    36. ******************************************************************************/

    37. /*!
    38. * @brief ISR for CAPT.
    39. */
    40. void DEMO_CAPT_IRQHandler(void)
    41. {
    42.     uint32_t intStat;
    43.     capt_touch_data_t s_captData;

    44.     intStat = CAPT_GetInterruptStatusFlags(DEMO_CAPT_BASE);

    45.     CAPT_ClearInterruptStatusFlags(DEMO_CAPT_BASE, intStat);

    46.     /* If timeout happens, the board capt capacitor should be changed. */
    47.     if (intStat &
    48.         (kCAPT_InterruptOfYesTouchStatusFlag | kCAPT_InterruptOfNoTouchStatusFlag | kCAPT_InterruptOfTimeOutStatusFlag))
    49.     {
    50.         CAPT_GetTouchData(DEMO_CAPT_BASE, &s_captData);

    51.         g_captRawData[s_captData.XpinsIndex] = s_captData.count;
    52.     }

    53.     if (intStat & kCAPT_InterruptOfPollDoneStatusFlag)
    54.     {
    55.         g_captPollDone = true;
    56.     }
    57. }

    58. void capt_touch_init(void)
    59. {
    60.     capt_config_t captConfig;
    61.     uint32_t captClockFreq;

    62.     PRINTF("CAPT basic continuous example.\r\n");

    63.     /* Initialize CAPT module. */
    64.     CAPT_GetDefaultConfig(&captConfig);

    65.     /* Calculate the clock divider to make sure CAPT work in 2Mhz fclk. */
    66.     captClockFreq           = DEMO_CAPT_CLOCK_FREQ;
    67.     captConfig.clockDivider = (captClockFreq / 2000000U - 1U);
    68.     captConfig.enableXpins  = DEMO_CAPT_ENABLE_PINS;

    69.     /* The CAPT FCLK is set to 2MHz, the delay period between two polling rounds
    70.      * is pollCount * 2096, setting pollCount to 250, then the polling round
    71.      * frequency is about 2Hz, user can change this value to smaller value to
    72.      * for faster polling round.
    73.      */
    74.     captConfig.pollCount = 250;

    75.     CAPT_Init(DEMO_CAPT_BASE, &captConfig);

    76.     /* Enable the interrupts. */
    77.     CAPT_EnableInterrupts(DEMO_CAPT_BASE, kCAPT_InterruptOfYesTouchEnable | kCAPT_InterruptOfNoTouchEnable |
    78.                                               kCAPT_InterruptOfTimeOutEnable | kCAPT_InterruptOfPollDoneEnable);
    79.     NVIC_EnableIRQ(DEMO_CAPT_IRQn);

    80.     /* Set polling mode and start poll. */
    81.     CAPT_SetPollMode(DEMO_CAPT_BASE, kCAPT_PollContinuousMode);   
    82. }

    83. /*!
    84. * @brief Main function
    85. */
    86. int capt_touch_main(void *pvParameters)
    87. {
    88.     int pin = lpc84x_pin_get("P1.1");

    89.     lpc84x_pin_mode(pin,PIN_MODE_OUTPUT);
    90.     while (1)
    91.     {
    92.         while (!g_captPollDone)
    93.         {
    94.             vTaskDelay(1);
    95.         }
    96.         if(g_captRawData[0] > 60)
    97.         {
    98.             lpc84x_pin_write(pin,0);
    99.         }
    100.         else
    101.         {
    102.             lpc84x_pin_write(pin,1);
    103.         }
    104.         /* Output the captured data. */
    105.         

    106.         g_captPollDone = false;
    107.     }
    108. }

    复制代码


    3.下载验证



    8208194f49a083f15fb52247c723d6bf[00-00-00--00-00-15].gif


    =================代码如下=================


    =================使用文档在此贴资料区=================








    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    7 小时前
  • 签到天数: 105 天

    [LV.6]常住居民II

    9

    主题

    258

    帖子

    0

    高级会员

    Rank: 4

    积分
    590
    最后登录
    2024-3-29
    发表于 2023-4-15 22:59:42 | 显示全部楼层
    学习了,代码工程,条理清晰。感谢分享!
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    6 天前
  • 签到天数: 1334 天

    [LV.10]以坛为家III

    88

    主题

    4290

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    9022
    最后登录
    2024-3-29
    发表于 2023-4-17 10:22:46 | 显示全部楼层
    这个帖子厉害了,
    连实现的物理,电气原理都讲了
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    4 小时前
  • 签到天数: 578 天

    [LV.9]以坛为家II

    49

    主题

    2143

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    6727
    最后登录
    2024-3-29
     楼主| 发表于 2023-4-17 11:20:35 | 显示全部楼层
    jobszheng5 发表于 2023-4-17 10:22
    这个帖子厉害了,
    连实现的物理,电气原理都讲了

    存粹个人根据手册理解,理解的也不一定很到位
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    7 小时前
  • 签到天数: 105 天

    [LV.6]常住居民II

    9

    主题

    258

    帖子

    0

    高级会员

    Rank: 4

    积分
    590
    最后登录
    2024-3-29
    发表于 2023-4-17 13:32:54 | 显示全部楼层
    非常好的帖子,从原理,到代码,非常好,学习了!
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-3-29 14:20 , Processed in 0.136702 second(s), 23 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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