【新版CH554评测】二、触摸按键程序分析
<div class='showpostmsg'>按照计划第二篇应是触摸按键例程分析
这个例程应在程序包路径下的:\EXAM\TouchKey\
首先手册上是这么介绍的:
17.3 Touch-Key 功能
电容检测步骤:
(1)、设置 TKEY_CTRL 寄存器中的 bTKC_2MS 和 bTKC_CHAN2~bTKC_CHAN0,选择周期和输入通道。被
选择的输入通道,其所在 GPIO 引脚必须设置为高阻输入模式、或者开漏输出模式并且处于输
出 1 的状态(相当于高阻输入),Pn_DIR_PU=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工作模式描述
00高阻输入模式,引脚没有上拉电阻
然后设为2MS定时:
TKEY_CTRL |= bTKC_2MS ;
再然后,采样要测通道的5次采样平均值做为初使值
for ( i = 0; i < TOUCH_NUM; i++ )
{
sum = 0;
j = SAMPLE_TIMES;
TK_SelectChannel( i );
// TKEY_CTRL |= TK_Code;
while( j-- )
{
OverTime = 0;
while( ( TKEY_CTRL & bTKC_IF ) == 0 )
{
if( ++OverTime == 0 )
{
return FAIL;
}
}
sum += TKEY_DAT; /**/
}
Key_FreeBuf = sum / SAMPLE_TIMES;
printf( "Key_FreeBuf[%d]=%d\t", (UINT16)(i), (UINT16)Key_FreeBuf );
}
而主程序只是判断哪个通道发生的按键动作:
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 - TH_VALUE ) )
{
Touch_IN |=1 << ( TK_Code - 1 );
}
// printf( "ch[%d]=%d\t", (UINT16)(TK_Code - 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;
return SUCCESS;
}
return FAIL;
}
可见,电容触摸是利用每次电容变化时,同初始值相比较而产生的动作,所以刚加电时绝对不要在触摸按键上边,放任何东东。
以下是运行的截图:
此内容由EEWORLD论坛网友ddllxxrr原创,如需转载或用于商业用途需征得作者同意并注明出处
</div><script> var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;" style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
if(parseInt(discuz_uid)==0){
(function($){
var postHeight = getTextHeight(400);
$(".showpostmsg").html($(".showpostmsg").html());
$(".showpostmsg").after(loginstr);
$(".showpostmsg").css({height:postHeight,overflow:"hidden"});
})(jQuery);
} </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script> :handshake:handshake 沁恒USB单片机 发表于 2018-4-2 16:31
:handshake
页:
[1]