5970|2

1万

帖子

16

TA的资源

版主

楼主
 

【新版CH554评测】二、触摸按键程序分析 [复制链接]



按照计划第二篇应是触摸按键例程分析

这个例程应在程序包路径下的:\EXAM\TouchKey\
首先手册上是这么介绍的:
  1. 17.3 Touch-Key 功能
  2. 电容检测步骤:
  3. (1)、设置 TKEY_CTRL 寄存器中的 bTKC_2MS 和 bTKC_CHAN2~bTKC_CHAN0,选择周期和输入通道。被
  4. 选择的输入通道,其所在 GPIO 引脚必须设置为高阻输入模式、或者开漏输出模式并且处于输
  5. 出 1 的状态(相当于高阻输入),Pn_DIR_PU[x]=0。
  6. (2)、清零 bTKC_IF 并开启中断 IE_TKEY 等待定时中断,或者通过主动查询 bTKC_IF 进入中断程序。
  7. (3)、当前通道的电容检测完毕后将自动设置 bTKC_IF 请求中断,同时进入下一个周期的准备阶段,
  8. 并保持 TKEY_DAT 数据不变约 87uS。
  9. (4)、进入中断程序中,首先从 TKEY_DAT 中读取当前通道的电容数据,并屏蔽最高位 bTKD_CHG,该
  10. 数据是相对值,与电容量成反比,当触摸按键按下时的数据比未按下时的数据小。
  11. (5)、设置 TKEY_CTRL 寄存器中的 bTKC_2MS 和 bTKC_CHAN2~bTKC_CHAN0,选择下一个输入通道。该
  12. 写操作将自动清零 bTKC_IF,结束中断请求。
  13. (6)、用步骤(4)读取的 TKEY_DAT 数据与之前保存的该通道无按键时的数据比较,判断是否电容变化
  14. 和是否有按键被按下。
  15. (7)、中断返回,当下一个通道的电容检测完毕后将转向步骤(3)。


复制代码



手册上还说:Touch-Key:6 通道电容检测,支持最多 15 个触摸按键,支持独立定时中断。

可见有独立定时器这就方便很多。


下边分析一下例程:

首先端口初使化,初使为不带上拉的高阻输入

  1. P1_DIR_PU &= ~channel;
  2.         P1_MOD_OC &= ~channel;
复制代码



这个手册有说明:
Pn_MOD_OC Pn_DIR_PU  工作模式描述
0  0  高阻输入模式,引脚没有上拉电阻


然后设为2MS定时:
  1. TKEY_CTRL |= bTKC_2MS ;
复制代码



再然后,采样要测通道的5次采样平均值做为初使值
  1. for ( i = 0; i < TOUCH_NUM; i++ )
  2.         {
  3.                 sum = 0;
  4.                 j = SAMPLE_TIMES;
  5.                 TK_SelectChannel( i );
  6. //                TKEY_CTRL |= TK_Code[i];
  7.                 while( j-- )
  8.                 {
  9.                         OverTime = 0;
  10.                         while( ( TKEY_CTRL & bTKC_IF ) == 0 )
  11.                         {
  12.                                 if( ++OverTime == 0 )
  13.                                 {
  14.                                         return FAIL;
  15.                                 }
  16.                         }
  17.                         sum += TKEY_DAT;                                                                                                        /*  */
  18.                 }
  19.                 Key_FreeBuf[i] = sum / SAMPLE_TIMES;
  20.                 printf( "Key_FreeBuf[%d]=%d\t", (UINT16)(i), (UINT16)Key_FreeBuf[i] );
  21.         }
复制代码



而主程序只是判断哪个通道发生的按键动作:
  1. while ( 1 )
  2.         {
  3. //                if( TK_Measure() != SUCCESS )                                        /* For Query Mode. */
  4. //                {
  5. //                        printf("ERROR\n");
  6. //                }
  7.                
  8.                 if( Touch_IN != 0 )
  9.                 {
  10.                         if( Touch_IN & CH0 )
  11.                         {
  12.                                 printf("CH0 is pressed.\n");
  13.                         }
  14.                         if( Touch_IN & CH1 )
  15.                         {
  16.                                 printf("CH1 is pressed.\n");
  17.                         }
  18.                         if( Touch_IN & CH2 )
  19.                         {
  20.                                 printf("CH2 is pressed.\n");
  21.                         }
  22.                         if( Touch_IN & CH3 )
  23.                         {
  24.                                 printf("CH3 is pressed.\n");
  25.                         }
  26.                         if( Touch_IN & CH4 )
  27.                         {
  28.                                 printf("CH4 is pressed.\n");
  29.                         }
  30.                         if( Touch_IN & CH5 )
  31.                         {
  32.                                 printf("CH5 is pressed.\n");
  33.                         }
  34.                         Touch_IN = 0;
  35.                 }
  36.         }
  37.        
复制代码



真证干活的是在中断的服务程序里边选择下一通道:
  1. void TK_int_ISR( void ) interrupt INT_NO_TKEY using 1
  2. {
  3.         static UINT8 ch = 0;
  4.         UINT16 KeyData;

  5.         KeyData = TKEY_DAT;
  6.        
  7.         if( KeyData < ( Key_FreeBuf[ch] - TH_VALUE ) )
  8.         {
  9.                 Touch_IN |=  1 << ( TK_Code[ch] - 1 );
  10.         }
  11.        
  12. //        printf( "ch[%d]=%d\t", (UINT16)(TK_Code[ch] - 1), (UINT16)KeyData );

  13.         if( ++ch >= TOUCH_NUM )
  14.         {
  15. //                printf("\n");
  16.                 ch = 0;
  17.         }       
  18.         TK_SelectChannel( ch );


  19. }
复制代码




而全程的通道选择程序如下:
  1. UINT8 TK_SelectChannel( UINT8 ch )
  2. {
  3.         if ( ch <= TOUCH_NUM )
  4.         {
  5.                 TKEY_CTRL = ( TKEY_CTRL & 0XF8) | TK_Code[ch];
  6.                 return SUCCESS;
  7.         }

  8.         return        FAIL;
  9. }
复制代码




可见,电容触摸是利用每次电容变化时,同初始值相比较而产生的动作,所以刚加电时绝对不要在触摸按键上边,放任何东东。


以下是运行的截图:









此内容由EEWORLD论坛网友ddllxxrr原创,如需转载或用于商业用途需征得作者同意并注明出处


此帖出自单片机论坛

最新回复

  详情 回复 发表于 2018-4-2 16:31
点赞 关注
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 

回复
举报

305

帖子

0

TA的资源

一粒金砂(高级)

沙发
 
此帖出自单片机论坛
 
个人签名单价1元含税的USB和Touchkey单片机CH551G已大批量出货,试样QQ:1258305301
 

回复

1万

帖子

16

TA的资源

版主

板凳
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表