本帖最后由 mxkw0514 于 2025-4-11 09:39 编辑
#申请原创# @21小跑堂
触摸技术按照维度来分,有1D、2D和3D触摸技术(如图1),1D触摸技术的对象主要有按键、滑条、滑轮等;2D触摸技术的对象主要是触摸屏,是对x,y坐标的判断;3D触摸技术主要应用在手势的识别场景。
图1 Touch技术的分类
触摸技术根据工作原理来划分,包括自容式和互容式技术,自容式就是某个引脚自发自收,互容式技术是一个引脚激励另外一个引脚接受信号进行检测。
图2 自容和互容技术示意图
触摸技术基于检测的物理量来划分,涵盖了电阻式触摸、电感式触摸和电容式触摸技术等,目前来看,电容式技术是用得最多的,在低成本、高可靠性和干扰能力等方面有较大的优势。
图3 电容式静电场感应
目前很多通用型单片机内部都集成了Touch外设(如图4),在汽车电子、消费类电子和工业控制领域扮演者重要的角色,既降低了外部元器件的使用,缩小了PCB的尺寸,又减少了生产成本,提高了产品的竞争力和公司效益。
图4 通用MCU的Touch检测
刚好手上有一块DIP封装的PIC单片机,今天打算利用PIC单片机内部的Touch外设来做一个触摸按键和触摸滑条。PIC单片机的Touch外设是一个CVD(Capative Voltage Divide)电路,在早些年的PIC单片机中,就是一个HCVD外设,在最新的PIC单片机中,CVD电路被放在了ADCC外设中,不过就是PIC单片机中没有硬件CVD电路,只要有ADC外设,还是能基于官方的mTouch库实现软件CVD算法。既然谈到了CVD技术,那么就来简单介绍一下。
打开PIC单片机的数据手册,直接搜索CVD关键词,就能很快定位到CVD的框图,这个框图以及工作原理如图5所示。总的来说,就是利用外部等效触摸电容和内部采样电容之间的来回充放电,利用来回充放电的差分电压为触摸进行判断和检测。采样保持电容和外部触摸等效电容在一个周期的充放电波形图如图6所示。
图5 CVD技术原理
图6 CVD充放电波形示意图
使用示波器的探头捕捉了Touch Sensor上的实际充放电波形如图7所示,与图6中的外部等效电容的充放电波形示意图(红色虚线)基本一致。ADCC一次性在硬件上进行16次充放电并进行硬件上的处理计算,大大降低了软件上资源的消耗。
今天使用手上的PIC单片机加一个Touch小板(如图8),来实现LED灯的触摸控制。Touch小板包含了两个Button和一个Wheel,该小板的PCB三维图如图9所示,如果想学习Touch的布局和布线,可以从官方网站下载这个PCB源文件。 在熟悉了前面讲述的CVD的工作原理之后,就可以使用官方的mTouch库来编写程序了,首先,利用MPLAB的MCC插件(如图10)来建立Button和Wheel对象,编辑相应的Touch引脚,设置单片机的配置字,通过MCC插件生成底层代码。然后,基于MCC生成的Touch driver程序来编写应用层代码,实现对Button和Wheel触摸事件的检测和判断,实现对LED灯的控制;最后,利用MPLAB软件和PICkit工具对应用层程序调试、编译何下载。
图10 Touch外设的可视化配置界面
触摸事件检测和LED灯控制放在的主程序的While循环中,内层任务实现是采用轮询的机理。的仍无Button事件的判断和任务的处理使用了if和else语句,Whell事件的处理稍微复杂一点,主要是使用状态机对手在滑轮上的位置的检测和判断。 #include "mcc_generated_files/mcc.h"
void main(void)
{
// initialize the device
SYSTEM_Initialize();
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
while (1)
{
// Add your application code
if(MTOUCH_Service_Mainloop())
{
/* Button API*/
if (MTOUCH_Button_isPressed(0))
{
/* process if button is pressed */
/* LED_SetHigh();*/
Button_LED1_SetLow() ;
}
else
{
/* process if button is not pressed */
/* LED_SetLow();*/
Button_LED1_SetHigh() ;
}
}
/* Button API*/
if (MTOUCH_Button_isPressed(1))
{
/* process if button is pressed */
/* LED_SetHigh();*/
Butto_LED2_SetLow() ;
}
else
{
/* process if button is not pressed */
/* LED_SetLow();*/
Butto_LED2_SetHigh() ;
}
if(MTOUCH_Slider_isPositionChanged(0))
{
uint8_t sliderPostion = MTOUCH_Slider_Position_Get(0);
sliderPostion = sliderPostion >> 5;
// process slider position
switch(sliderPostion)
{
case 0:
Slider_LED1_SetHigh();
Slider_LED2_SetHigh();
Slider_LED3_SetHigh();
Slider_LED4_SetHigh();
Slider_LED5_SetHigh();
Slider_LED6_SetHigh();
break;
case 1:
Slider_LED1_SetHigh();
Slider_LED2_SetHigh();
Slider_LED3_SetHigh();
Slider_LED4_SetHigh();
Slider_LED5_SetLow();
Slider_LED6_SetLow();
break;
case 2:
Slider_LED1_SetHigh();
Slider_LED2_SetHigh();;
Slider_LED3_SetHigh();
Slider_LED4_SetLow();
Slider_LED5_SetLow();
Slider_LED6_SetLow();
break;
case 3:
Slider_LED1_SetHigh();
Slider_LED2_SetHigh();
Slider_LED3_SetHigh();
Slider_LED4_SetLow();
Slider_LED5_SetLow();
Slider_LED6_SetLow();
break;
case 4:
Slider_LED1_SetHigh();
Slider_LED2_SetHigh();
Slider_LED3_SetLow();
Slider_LED4_SetLow();
Slider_LED5_SetLow();
Slider_LED6_SetLow();
break;
case 5:
Slider_LED1_SetHigh();
Slider_LED2_SetLow();
Slider_LED3_SetLow();
Slider_LED4_SetLow();
Slider_LED5_SetLow();
Slider_LED6_SetLow();
break;
case 6:
Slider_LED1_SetLow();
Slider_LED2_SetLow();
Slider_LED3_SetLow();
Slider_LED4_SetLow();
Slider_LED5_SetLow();
Slider_LED6_SetLow();
break;
case 7:
break;
default:
Slider_LED1_SetHigh();
Slider_LED2_SetHigh();
Slider_LED3_SetHigh();
Slider_LED4_SetHigh();
Slider_LED5_SetHigh();
Slider_LED6_SetHigh();
break;
}
}
}
}
按键和滑条触摸板的实现效果如下所示,编写的应用层的程序如下所示。Button每按下一次,控制一个LED灯的点亮;Whell从上到下划过,LED灯点亮的数量逐渐增加,往上划过,LED灯逐渐熄灭。
使用Touch调试助手可以获取单片机上传的触摸信号值,可以结合实际应用产品对Touch的相关参数进行设置和调试。从图11可以看到两个重要的参数,一个Deviation,是是实际的经过量化的信号值;另外一个是Threhold,这是事先设置的判断阈值,可以通过改变判断阈值来调节Touch的灵敏度。
图11 Touch调试助手
MCC插件生成的driver方便了用户的代码编写工作量,缩减了开发时间,但是研究一下CVD工作原理还是比较有意思的。由于本人水平有限,在Touch技术的分享上难免存在纰漏,希望专业领域内的朋友批评指正。
|
从触摸识别的工作原理出发,借助PIC单片机内部的Touch外设和Touch调试助手开发滑条触摸控制。实现效果较好,原理介绍清晰。