按照计划第二篇应是触摸按键例程分析
这个例程应在程序包路径下的:\EXAM\TouchKey\
首先手册上是这么介绍的:
- 17.3 Touch-Key 功能
- 电容检测步骤:
- (1)、设置 TKEY_CTRL 寄存器中的 bTKC_2MS 和 bTKC_CHAN2~bTKC_CHAN0,选择周期和输入通道。被
- 选择的输入通道,其所在 GPIO 引脚必须设置为高阻输入模式、或者开漏输出模式并且处于输
- 出 1 的状态(相当于高阻输入),Pn_DIR_PU[x]=0。
- (2)、清零 bTKC_IF 并开启中断 IE_TKEY 等待定时中断,或者通过主动查询 bTKC_IF 进入中断程序。
- (3)、当前通道的电容检测完毕后将自动设置 bTKC_IF 请求中断,同时进入下一个周期的准备阶段,
- 并保持 TKEY_DAT 数据不变约 87uS。
- (4)、进入中断程序中,首先从 TKEY_DAT 中读取当前通道的电容数据,并屏蔽最高位 bTKD_CHG,该
- 数据是相对值,与电容量成反比,当触摸按键按下时的数据比未按下时的数据小。
- (5)、设置 TKEY_CTRL 寄存器中的 bTKC_2MS 和 bTKC_CHAN2~bTKC_CHAN0,选择下一个输入通道。该
- 写操作将自动清零 bTKC_IF,结束中断请求。
- (6)、用步骤(4)读取的 TKEY_DAT 数据与之前保存的该通道无按键时的数据比较,判断是否电容变化
- 和是否有按键被按下。
- (7)、中断返回,当下一个通道的电容检测完毕后将转向步骤(3)。
复制代码
手册上还说:Touch-Key:6 通道电容检测,支持最多 15 个触摸按键,支持独立定时中断。
可见有独立定时器这就方便很多。
下边分析一下例程:
首先端口初使化,初使为不带上拉的高阻输入
- P1_DIR_PU &= ~channel;
- P1_MOD_OC &= ~channel;
复制代码
这个手册有说明:
Pn_MOD_OC Pn_DIR_PU 工作模式描述
0 0 高阻输入模式,引脚没有上拉电阻
然后设为2MS定时:
再然后,采样要测通道的5次采样平均值做为初使值
- for ( i = 0; i < TOUCH_NUM; i++ )
- {
- sum = 0;
- j = SAMPLE_TIMES;
- TK_SelectChannel( i );
- // TKEY_CTRL |= TK_Code[i];
- while( j-- )
- {
- OverTime = 0;
- while( ( TKEY_CTRL & bTKC_IF ) == 0 )
- {
- if( ++OverTime == 0 )
- {
- return FAIL;
- }
- }
- sum += TKEY_DAT; /* */
- }
- Key_FreeBuf[i] = sum / SAMPLE_TIMES;
- printf( "Key_FreeBuf[%d]=%d\t", (UINT16)(i), (UINT16)Key_FreeBuf[i] );
- }
复制代码
而主程序只是判断哪个通道发生的按键动作:
- while ( 1 )
- {
- // if( TK_Measure() != SUCCESS ) /* For Query Mode. */
- // {
- // printf("ERROR\n");
- // }
-
- if( Touch_IN != 0 )
- {
- if( Touch_IN & CH0 )
- {
- printf("CH0 is pressed.\n");
- }
- if( Touch_IN & CH1 )
- {
- printf("CH1 is pressed.\n");
- }
- if( Touch_IN & CH2 )
- {
- printf("CH2 is pressed.\n");
- }
- if( Touch_IN & CH3 )
- {
- printf("CH3 is pressed.\n");
- }
- if( Touch_IN & CH4 )
- {
- printf("CH4 is pressed.\n");
- }
- if( Touch_IN & CH5 )
- {
- printf("CH5 is pressed.\n");
- }
- Touch_IN = 0;
- }
- }
-
复制代码
真证干活的是在中断的服务程序里边选择下一通道:
- void TK_int_ISR( void ) interrupt INT_NO_TKEY using 1
- {
- static UINT8 ch = 0;
- UINT16 KeyData;
- KeyData = TKEY_DAT;
-
- if( KeyData < ( Key_FreeBuf[ch] - TH_VALUE ) )
- {
- Touch_IN |= 1 << ( TK_Code[ch] - 1 );
- }
-
- // printf( "ch[%d]=%d\t", (UINT16)(TK_Code[ch] - 1), (UINT16)KeyData );
- if( ++ch >= TOUCH_NUM )
- {
- // printf("\n");
- ch = 0;
- }
- TK_SelectChannel( ch );
- }
复制代码
而全程的通道选择程序如下:
- UINT8 TK_SelectChannel( UINT8 ch )
- {
- if ( ch <= TOUCH_NUM )
- {
- TKEY_CTRL = ( TKEY_CTRL & 0XF8) | TK_Code[ch];
- return SUCCESS;
- }
- return FAIL;
- }
复制代码
可见,电容触摸是利用每次电容变化时,同初始值相比较而产生的动作,所以刚加电时绝对不要在触摸按键上边,放任何东东。
以下是运行的截图:
此内容由EEWORLD论坛网友ddllxxrr原创,如需转载或用于商业用途需征得作者同意并注明出处