[RISC-V MCU 应用开发] 【RISC-V MCU CH32V103测评】04:触摸按键控制LED亮灭

[复制链接]
 楼主| 天意无罪 发表于 2020-12-6 19:14 | 显示全部楼层 |阅读模式
本帖最后由 天意无罪 于 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文件。
674805fccbc732d5bd.png
2.  在tkey.h文件里面定义相关宏定义、变量声明、以及函数声明等。
  1. #ifndef BSP_INC_TKEY_H_
  2. #define BSP_INC_TKEY_H_

  3. #include "ch32v10x_conf.h"

  4. #define TKEY_GPIO_PORT   GPIOA
  5. #define TKEY1_GPIO_PIN   GPIO_Pin_1
  6. #define TKEY2_GPIO_PIN   GPIO_Pin_2

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

  11. void Touch_Key_Init(void);
  12. u16 Touch_Key_GetAdc(u8 ch);

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

  2. void Touch_Key_Init(void)
  3. {
  4.     GPIO_InitTypeDef GPIO_InitStructure;

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

  7.     GPIO_InitStructure.GPIO_Pin = TKEY1_GPIO_PIN | TKEY2_GPIO_PIN;
  8.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  9.     GPIO_Init(TKEY_GPIO_PORT, &GPIO_InitStructure);

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

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

  13. u16 Touch_Key_GetAdc(u8 ch)
  14. {
  15.     u16 val;

  16.     TKEY_CH = ch;     // 选择通道

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

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

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

  4.         Delay_Init();
  5.         USART_Printf_Init(115200);
  6.         LED_Init();
  7.         Touch_Key_Init();

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

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

  13.             if(ADC_VAL & 0x8000)
  14.             {
  15.                 printf("This value is discarded\r\n");
  16.             }
  17.             else if((ADC_VAL > 0) && (ADC_VAL < 2000) )
  18.             {
  19.                 LED1_ON();
  20.             }

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

  22.             Delay_Ms(10);

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

  25.         if(ADC_VAL & 0x8000)
  26.         {
  27.             printf("This value is discarded\r\n");
  28.         }
  29.         else if((ADC_VAL > 0) && (ADC_VAL < 2000) )
  30.         {
  31.             LED1_OFF();
  32.         }

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

  34.         Delay_Ms(10);
  35.         }
  36. }
(三) 效果演示
TouchLED20201206_192303.gif


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

本版积分规则

61

主题

3277

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部

61

主题

3277

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部