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

【RISC-V MCU CH32V103测评】04:触摸按键控制LED亮灭

[复制链接]
423|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 天意无罪 于 2020-12-6 19:25 编辑

(一)硬件熟悉
CH32V103 系列产品触摸检测控制(TKEY_V)单元,通过将电容量变化转变为频率变化进行采样,实现触摸按键检测功能。检测通道复用 ADC 的 16 路外部通道。应用程序通过数字值的变化量判断触摸按键状态。
TKEY_V单元检测内部复用了ADC模块的通道选择及部分寄存器地址,所用使用 TKEY_V功能需要开启ADC模块(ADON=1),并打开 ADC 时钟以此来访问相关寄存器。然后将TKEY_V_CTLR(ADC_CTLR1)寄存器的TKENABLE 位置1,打开TKEY_V 单元功能。
注:因为共用了采样通道选择,所以ADC和TKEY_V检测功能不能同时使用。
(二)软件设计
实现功能:通过开发板上的两个触摸按键来控制开发板上的两个LED灯的亮灭。
1.  在BSP/src目录下新建一个tkey.c文件,在BSP/inc目录下新建一个tkey.h文件。

2.  在tkey.h文件里面定义相关宏定义、变量声明、以及函数声明等。
#ifndef BSP_INC_TKEY_H_
#define BSP_INC_TKEY_H_

#include "ch32v10x_conf.h"

#define TKEY_GPIO_PORT   GPIOA
#define TKEY1_GPIO_PIN   GPIO_Pin_1
#define TKEY2_GPIO_PIN   GPIO_Pin_2

/* 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_GetAdc(u8 ch);

#endif /* BSP_INC_TKEY_H_ */
3.  在tkey.c文件里面实现触摸按键的配置和初始化等。
#include "tkey.h"

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 = TKEY1_GPIO_PIN | TKEY2_GPIO_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(TKEY_GPIO_PORT, &GPIO_InitStructure);

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

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

u16 Touch_Key_GetAdc(u8 ch)
{
    u16 val;

    TKEY_CH = ch;     // 选择通道

    while(!(TKEY_CR & 0x08000000)); //当未清除计数转换完成标志

    val = (u16)TKEY_SR; //TKEY_V计数转换值

    return val;
}
4.  在main.c中添加按键检测代码。
int main(void)
{
    u16 ADC_VAL;

        Delay_Init();
        USART_Printf_Init(115200);
        LED_Init();
        Touch_Key_Init();

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

        while(1)
        {
            ADC_VAL = Touch_Key_GetAdc(ADC_Channel_1);
            printf( "TouchKey1:%04d\r\n",  ADC_VAL );

            if(ADC_VAL & 0x8000)
            {
                printf("This value is discarded\r\n");
            }
            else if((ADC_VAL > 0) && (ADC_VAL < 2000) )
            {
                LED1_ON();
            }

            TKEY_CR |=0x08000000;  //TKEY_V_CTLR寄存器位27,计数转换完成标志,软件写1清0,清除标志位

            Delay_Ms(10);

        ADC_VAL = Touch_Key_GetAdc(ADC_Channel_2);
        printf( "TouchKey2:%04d\r\n",  ADC_VAL );

        if(ADC_VAL & 0x8000)
        {
            printf("This value is discarded\r\n");
        }
        else if((ADC_VAL > 0) && (ADC_VAL < 2000) )
        {
            LED1_OFF();
        }

        TKEY_CR |=0x08000000;  //TKEY_V_CTLR寄存器位27,计数转换完成标志,软件写1清0,清除标志位

        Delay_Ms(10);
        }
}
(三) 效果演示



使用特权

评论回复

相关帖子

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

本版积分规则

61

主题

2988

帖子

12

粉丝