打印
[RISC-V MCU 应用开发]

二十二、CH32V103应用教程——触摸按键检测(TKEY)

[复制链接]
3643|32
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 RISCVLAR 于 2020-12-3 19:11 编辑

CH32V103应用教程——触摸按键检测(TKEY)

本章教程使用CH32V103开发板的触摸按键TK1进行触摸按键检测,并将检测信息通过串口调试助手打印显示。


1、TKEY简介及相关函数介绍
1、TKEY_V 开启
TKEY_V单元检测内部复用了ADC模块的通道选择及部分寄存器地址,所用使用 TKEY_V功能需要开启ADC模块(ADON=1),并打开 ADC 时钟以此来访问相关寄存器。然后将TKEY_V_CTLR(ADC_CTLR1)寄存器的TKENABLE 位置1,打开TKEY_V 单元功能。

注:因为共用了采样通道选择,所以ADC和TKEY_V检测功能不能同时使用。

2、工作原理
一旦开启了TKEY_V功能,硬件内部将自动进行周期性地采样计数转换过程,并在完成一次转换后,通知应用代码在固定时间(tDR)内取走数据,开启下一次转换,此循环过程在TKEY_V开启下是自动进行的。如图所示,硬件内部会提供了用来计数的脉冲源TKCLK,应用软件选择当前硬件计数周期为500us或 1ms,当内部完成周期内的计数统计后,会产生 TKIF 标志通知应用代码读取本次转换数值,应用代码需要在最长43us(tDR)内取走数据,否则下一轮的转换将影响数据寄存器的内容。


关于CH32V103触摸按键检测具体信息,可参考CH32V103应用手册。CH32V103 触摸按键检测所用标准库函数在ADC章节已介绍,在此不再赘述。

2、硬件设计
本章教程所用资源均为开发板内部资源,无需进行硬件设计。

3、软件设计
TKEY_V通过电容改变影响内部振荡频率变化的原理,以统计计数值大小检测触摸按键。具体操作流程如下:
1)开启RCC模块的ADCEN位,打开TKEY_V寄存器操作权限。
2)开启TKEY_V功能,置ACON位为1,唤醒ADC模块。将ADC_CTLR1寄存器的TKENABLE位置1,打开TKEY_V单元。
3)配置采样周期,操作TKEY_V_CTLR寄存器的CCSEL[2:0]和TKCPS位,选择500us 或1ms周期。单元内部是以AHB时钟计时,所以需要CCSEL[2:0]域与当前 AHB 频率相等,否则会导致采样周期偏大或偏小。
4)配置采样通道,设置TKEY_V_CHANNEL寄存器,此寄存器的写操作会触发新的一轮周期开始。
5)等待TKIF标志置1,表示完成一次转换,可以读取TKEY_V_SDR寄存器中的 TKDR[13:0]计数值。TKSTA指示当前TKDR[13:0]域计数值是否有效。TKIF标志需要软件写1清0。如果置位了TKIEN,在TKIF=1时会同步触发TKEY_V(ADC)中断,进入ADC中断服务函数。
6)重复 3-5 步骤,获取下一次计数值。3-4为可选配置。
根据上述操作步骤,编写程序如下:
tkey.h文件
#ifndef __TKEY_H
#define __TKEY_H

#include "ch32v10x_conf.h"

/* Global define */ //此处查看寄存器时,应查看TKEY寄存器
#define TKEY_CR   ADC1->CTLR1   //ADC1->CTLR1寄存器由TKEY_V_CTLR寄存器映射而来,此处查看寄存器时应该查看TKEY_V_CTLR寄存器,而不是ADC1->CTLR1寄存器
#define TKEY_CH   ADC1->RSQR3   //ADC1->RSQR3寄存器由TKEY_V_CHANNEL寄存器映射而来,此处查看寄存器时应该查看TKEY_V_CHANNEL寄存器,而不是ADC1->RSQR3寄存器
#define TKEY_SR   ADC1->RDATAR  //ADC1->RDATAR寄存器由TKEY_V_SDR寄存器映射而来,此处查看寄存器时应该查看TKEY_V_SDR寄存器,而不是ADC1->RDATAR寄存器

void Touch_Key_Init(void);
u16 Touch_Key_Adc(u8 ch);

#endif
tkey.h文件主要进行相关定义及函数声明;
tkey.c文件
#include "tkey.h"

/*******************************************************************************
* Function Name  : Touch_Key_Init
* Description    : Initializes Touch Key collection.
* Input          : None
* Return         : None
*******************************************************************************/
void Touch_Key_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE ); //使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );  //使能ADC1时钟

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    ADC_Cmd(ADC1, ENABLE);   //使能开启ADC1

    TKEY_CR |= 0x51000000;   // 根据TKEY_V 控制寄存器(TKEY_V_CTLR),设置TKEY_V计数周期时基:56MHz;同时使能TKEY模块控制,开启TKEY_V单元。
}

/*******************************************************************************
* Function Name  : Touch_Key_Adc
* Description    : Returns ADCx conversion result data.
* Input          : ch: ADC channel.
*                    ADC_Channel_0: ADC Channel0 selected.
*                    ADC_Channel_1: ADC Channel1 selected.
*                    ADC_Channel_2: ADC Channel2 selected.
*                    ADC_Channel_3: ADC Channel3 selected.
*                    ADC_Channel_4: ADC Channel4 selected.
*                    ADC_Channel_5: ADC Channel5 selected.
*                    ADC_Channel_6: ADC Channel6 selected.
*                    ADC_Channel_7: ADC Channel7 selected.
*                    ADC_Channel_8: ADC Channel8 selected.
*                    ADC_Channel_9: ADC Channel9 selected.
*                    ADC_Channel_10: ADC Channel10 selected.
*                    ADC_Channel_11: ADC Channel11 selected.
*                    ADC_Channel_12: ADC Channel12 selected.
*                    ADC_Channel_13: ADC Channel13 selected.
*                    ADC_Channel_14: ADC Channel14 selected.
*                    ADC_Channel_15: ADC Channel15 selected.
* Return         : val: The Data conversion value.
*******************************************************************************/
u16 Touch_Key_Adc(u8 ch)
{
  u16 val;

  TKEY_CH = ch;     // 选择通道

  while(!(TKEY_CR & 0x08000000)); //当未清除计数转换完成标志
  val = (u16)TKEY_SR; //TKEY_V计数转换值

  return val;
}
tkey.c文件主要进行相关初始化配置以及获取触摸按键检测值
main.c文件
int main(void)
{
    u16 ADC_val;

    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n",SystemCoreClock);

    Touch_Key_Init();

    while(1)
    {
        ADC_val = Touch_Key_Adc(ADC_Channel_1);
        printf( "TouchKey:%04d\r\n",  ADC_val );

        if(ADC_val & 0x8000)
        {
            printf("This value is discarded\r\n");
        }

        TKEY_CR |=0x08000000;  //TKEY_V_CTLR寄存器位27,计数转换完成标志,软件写1清0,清除标志位
    }
}
main.c文件主要进行函数初始化以及触摸按键检测计数值的打印输出。

4、下载验证
将编译好的程序下载到开发板并复位,串口打印具体情况如下:

手指触摸触摸按键之后,串口打印具体情况如下:





21、TKEY.rar

459.47 KB

使用特权

评论回复

相关帖子

沙发
南岛蜗牛| | 2022-2-25 14:53 | 只看该作者
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;这个改为GPIO_Pin_2,触摸tk2没反应,但触摸tk1就有反应,这是怎么回事

使用特权

评论回复
评论
RISCVLAR 2022-3-7 13:21 回复TA
修改引脚之后,也要注意修改对应的ADC通道 
板凳
onlycook| | 2022-3-7 15:09 | 只看该作者
TKEY_V功能是什么功能

使用特权

评论回复
地板
loutin| | 2023-4-15 19:41 | 只看该作者
这个支持多少路的测量呢              

使用特权

评论回复
5
modesty3jonah| | 2023-4-16 22:00 | 只看该作者
可以测量几路的电容电压              

使用特权

评论回复
6
benjaminka| | 2023-4-17 17:59 | 只看该作者
这个的硬件是怎么设计的              

使用特权

评论回复
7
bestwell| | 2023-4-18 08:54 | 只看该作者
这个测试的敏感度怎么样              

使用特权

评论回复
8
ulystronglll| | 2023-4-18 11:04 | 只看该作者
这个如何调节触摸按键的敏感度              

使用特权

评论回复
9
mmbs| | 2023-4-18 11:26 | 只看该作者
带ADC的I/O口来检测吗              

使用特权

评论回复
10
olivem55arlowe| | 2023-4-18 12:00 | 只看该作者
触摸不是检测充放电的过程吗              

使用特权

评论回复
11
primojones| | 2023-4-18 12:03 | 只看该作者
CH32V103的功能真是强大。

使用特权

评论回复
12
juliestephen| | 2023-4-18 12:07 | 只看该作者
充放电需要多长的时间              

使用特权

评论回复
13
louliana| | 2023-5-10 20:39 | 只看该作者
如何利用单片机检测电容充放电的时间

使用特权

评论回复
14
lzbf| | 2023-5-10 21:04 | 只看该作者
CH32V103单片机可以实现触摸按键么

使用特权

评论回复
15
alvpeg| | 2023-5-10 21:12 | 只看该作者
电容式触摸按键必须需要用专用芯片吗?

使用特权

评论回复
16
burgessmaggie| | 2023-5-10 21:37 | 只看该作者
普通单片机怎样做电容式触摸感应按键

使用特权

评论回复
17
1988020566| | 2023-5-10 21:51 | 只看该作者
如何使用单片机的AD功能实现触摸按键

使用特权

评论回复
18
yeates333| | 2023-5-10 22:09 | 只看该作者
哪个单片机自带触摸按键和lcd功能

使用特权

评论回复
19
benjaminka| | 2023-5-10 22:14 | 只看该作者
电容触摸按键原理是什么              

使用特权

评论回复
20
jonas222| | 2023-5-11 15:46 | 只看该作者
如何实现一个按键的长时间按下?              

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

132

主题

293

帖子

41

粉丝