KING_阿飞 发表于 2022-10-3 15:13

【上海航芯 ACM32F070开发板+触控功能评估板测评】触摸按键

本帖最后由 KING_阿飞 于 2022-10-3 15:13 编辑

<p style="text-align: center;"><span style="font-size:18px;"><strong>【上海航芯 ACM32F070开发板+触控功能评估板测评】触摸按键</strong></span></p>

<p style="text-align: center;"><strong>&nbsp;</strong>为了更好的方便大家,同时方便自己,按照我的习惯,放上我的Github地址:<a href="https://github.com/kings669/ACM32F070">kings669/ACM32F070: ACM32F070 (github.com)</a>,大家需要的可以自取。</p>

<p style="text-align: center;">在上一节中,我们可以通过LCD进行简单的时间显示,现在我们开始测试这款开发板的另一特性,<strong>触摸按键</strong></p>

<p><strong><span style="font-size:16px;">一、电容式触摸传感器</span></strong></p>

<p><strong><span style="font-size:16px;">&nbsp; &nbsp; &gt;&gt;</span></strong>自电容式触摸控制传感器通过检测电容的变化来检测手指是否触及触摸表面。通过调整检测到的电容变化量来调整触摸的灵敏度</p>

<p>&nbsp; &nbsp; 主要特性:</p>

<ul>
        <li>&nbsp;&nbsp;&nbsp;&nbsp;最大支持 16 个自电容检测通道</li>
        <li>&nbsp;&nbsp;&nbsp;&nbsp;支持通道补偿</li>
        <li>&nbsp;&nbsp;&nbsp;&nbsp;自电容检测范围 5~50pf,灵敏度 0.1pf</li>
        <li>&nbsp;&nbsp;&nbsp;&nbsp;支持扫描时钟扩频</li>
        <li>&nbsp;&nbsp;&nbsp;&nbsp;支持屏蔽通道</li>
        <li>&nbsp;&nbsp;&nbsp;&nbsp;支持睡眠模式</li>
</ul>

<p>&nbsp;&nbsp;&nbsp;&nbsp;</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p>&nbsp; &nbsp; &nbsp;其原理在官方用户手册中也给出:</p>

<p class="imagemiddle" style="text-align: center;"></p>

<p><span style="font-size:16px;"><strong>&nbsp;二、运行流程</strong></span></p>

<p>&nbsp; &nbsp; 1、按键初始化</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;</p>

<pre>
<code class="language-cpp">uint8_t TouchKey_Init(void)
{
    uint8_t ret = 0;
    TKEY_Init();
    TKEY_Calibrate_ParaInit();
    ret = TKEY_Quick_Calibrate();
    TKEY_Timer_ScanInit();
    TKEY_Timer_Scan_Start();
    TKEY_DEBUG("sgu16_RawDataRangRatio = %d\n", sgu16_RawDataRangRatio);
    TKEY_DEBUG("sgu8_TKEYScanTime = %d\n", sgu8_TKEYScanTime);
    return ret;
}</code></pre>

<p>2、扫描按键获取值</p>

<pre>
<code class="language-cpp">uint8_t TK_TimerSacn_GetKeyVal(void)
{
        uint8_tucKey = 0xFF;
        TKEY_Timer_Scan_Result(&amp;ucKey);
#ifdef TKEY_WAVEFORM_OUTPUT   
    TK_DebugDataOut();
#endif
    return ucKey;
}</code></pre>

<p>3、自校准处理</p>

<pre>
<code>void TKEY_Calibrate_Process(void)
{
    uint8_t ucI;
    const TKEY_ChannelDataDef *ChannelData;
    uint16_t average, differ;
    for(ucI = 0; TKEY_Handle.ChannelData.ChannelId != 0xFFFF; ucI++)
    {
      ChannelData = &amp;TKEY_Handle.ChannelData;
      if(ChannelData-&gt;Tkey_CalData-&gt;CalFlag == TKEY_CALIBRAT_SELF)//×ÔÎòD£×¼
      {
            Bubble_Sort(ChannelData-&gt;Tkey_CalData-&gt;Caldata, TKEY_CALIBRATE_BUFF_MAX);
            average = Calculate_Sample_Average(&amp;ChannelData-&gt;Tkey_CalData-&gt;Caldata, TKEY_CALIBRATE_BUFF_MAX-4);
            differ = Calculate_Sample_differ(&amp;ChannelData-&gt;Tkey_CalData-&gt;Caldata, TKEY_CALIBRATE_BUFF_MAX-4, average);   
            
            if(differ &lt;= TKEY_Handle.ChannelData.Tkey_Data-&gt;RawData / sgu16_RawDataRangRatio)
            {
                ChannelData-&gt;Tkey_Data-&gt;BaseLine = average;
            }
            ChannelData-&gt;Tkey_CalData-&gt;CalFlag = TKEY_CALIBRAT_IDLE;
            ChannelData-&gt;Tkey_Data-&gt;StateId = TKEY_STATEID_RELEASE;
      }
      else if(ChannelData-&gt;Tkey_CalData-&gt;CalFlag == TKEY_CALIBRAT_QUICK)
      {
            ChannelData-&gt;Tkey_CalData-&gt;CalFlag = TKEY_CALIBRAT_IDLE;
            TKEY_DEBUG("TK_%d:TKEY_Quick_Calibrate\n",TKEY_Handle.ChannelData.ChannelId);
            TKEY_DEBUG("TK_%d:Baseline[%d]-Rawdata[%d]\n", TKEY_Handle.ChannelData.ChannelId, \
            TKEY_Handle.ChannelData.Tkey_Data-&gt;BaseLine, TKEY_Handle.ChannelData.Tkey_Data-&gt;RawData);
            //HAL_TKEY_Quick_Calibrate_RefData(&amp;TKEY_Handle,TKEY_QUICK_QUICK_CALIBRATE_TIMES);
            HAL_TKEY_Quick_Calibrate_RefData_OneChannel(&amp;TKEY_Handle, TKEY_Handle.ChannelData.ChannelId, TKEY_QUICK_QUICK_CALIBRATE_TIMES);
            TKEY_DEBUG("TK_%d:TKEY_CALIBRAT_SELF BaseLine=%d\n",TKEY_Handle.ChannelData.ChannelId,TKEY_Handle.ChannelData.Tkey_Data-&gt;BaseLine);
            ChannelData-&gt;Tkey_Data-&gt;StateId = TKEY_STATEID_RELEASE;
      }
    }
}</code></pre>

<pre>
<code class="language-cpp">int main(void)
{
                uint8_tret = 0;
                uint8_tfu8_Tkey_state = 0xff;
                Uart_Init(115200);
                ret = TouchKey_Init();
                if(ret)
    {
      printfS("TouchKey_Init is Fail!\r\n");
    }
    else
    {
      printfS("TouchKey_Init is Success!\r\n");      
    }
    while (1)
    {
                        fu8_Tkey_state = TK_TimerSacn_GetKeyVal();
                        if(fu8_Tkey_state != 0xFF)
      {
            Beep_On(5);
      #ifndef TKEY_WAVEFORM_OUTPUT
            printfS("TK_%d\r\n", fu8_Tkey_state);
      #endif
      }
      TKEY_Calibrate_Process();
                        rt_thread_mdelay(100);
    }
}
</code></pre>

<p>同时配合官方的软件包,可以使用官方自带的软件进行分析。</p>

<p>&nbsp;</p>

<p><span style="font-size:16px;"><strong>三、实现效果</strong></span></p>

<p style="text-align: center;">e7016fc31fe79621030d7146d4e9b80b<br />
&nbsp;</p>

lugl4313820 发表于 2022-10-4 06:45

<p>自电容式触摸控制传感器通过检测电容的变化来检测手指是否触及触摸表面。通过调整检测到的电容变化量来调整触摸的灵敏度。</p>

<p>电容触控,相比传统按键,灵敏许多吧。这个会有抖动这类的问题吗?</p>

KING_阿飞 发表于 2022-10-4 15:03

<p>与传统按键来说,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上就稳定的接通,在断开时也不会一下子彻底断开,而是在闭合和断开的瞬间伴随了一连串的抖动;对于电容按键,按键电容 Cx 扫描,得到比较稳定的计数值 Nx,通过检测 Cx 的增加量, 获得新的 Nx&rsquo;值, 和原来的 Nx 相减得到 &Delta;Nx 值, 通过 &Delta;Nx的大小变化来判断是否产生了触摸按键事件。</p>

秦天qintian0303 发表于 2022-10-4 19:35

<p>电容式触摸按键确实是非常方便,主要问题还是误碰没有机械按键可靠</p>

KING_阿飞 发表于 2022-10-4 20:08

秦天qintian0303 发表于 2022-10-4 19:35
电容式触摸按键确实是非常方便,主要问题还是误碰没有机械按键可靠

<p>确实容易误触,没有传统按键的机械反馈</p>

太白金星 发表于 2022-11-16 19:55

<p>没听到蜂鸣器的声音</p>
页: [1]
查看完整版本: 【上海航芯 ACM32F070开发板+触控功能评估板测评】触摸按键