项目和设计思路介绍
非常开心能够参与并顺利完成Funpack 4-2的活动,本次项目的方向是SAME51J20A Curiosity Nano 评估套件 + 自制的触摸扩展板,实现通过触摸按键调节呼吸灯亮度,通过触摸滑条来调节呼吸灯“闪烁速度”。
项目的整体开发方向是
- 先熟悉Microchip官方关于触摸控制模块PTC的使用手册
- 设计原理图和PCB,自制触摸扩展板卡
- 结合MPLAB IDE中的MCC图形化外设配置功能自动生成代码,完成触摸初始代码
- 结合MPLAB X IDE内置的CapSense Tuner调试模块,验证触摸功能包括触摸按键与触摸滑条的准确度和灵敏度等
- 最后再扩展LED的呼吸灯效果:使用GPIO模拟PWM波。这种方式简单易处理。
硬件系统框图
软件流程图
硬件介绍(控制器及使用外设)
主控制器SAME51J20A介绍
SAME51J20A Curiosity Nano 评估套件(EV76S68A)是用于评估 SAME51J20A 微控制器(MCU)的硬件平台,该板由 MPLAB 集成工具开发环境和 MPLAB Harmony 提供支持。该评估套件可轻松访问 SAME51J20A 的功能,以将器件集成到定制设计中。Curiosity Nano 系列评估套件包括一个板载 Nano 调试器,因此无需外部工具即可对 SAME51J20A 器件进行编程。
针对本次使用的SAME51J20A 芯片,据数据手册了解到一个“SERCOM”的概念。这个是“SERIAL COMMUNICATION INTERFACE”的简写。不同于之前接触过的芯片,这个“SERCOM”竟然可以配置成I2C或者SPI或者USART还有LIN总线等不同的用法。
所有的带有x/y标记的引脚都具有触摸功能,非常方便进行触摸功能的开发。
触摸外设PTC
电容触摸技术有“互容”与“自容”两种感应技术,本项目使用硬件稍简单的“自容”技术,其基本原理如下:
电容式触摸是通过感知人体的电荷来检测触摸的技术。 当手指接触到触摸面板时,手指会引入电容,引起电容变化,触摸控制IC感知这些变化,做出响应。
当在触摸面板上布置电极,这些电极会与外部环境产生电容。当手指或其他物体接近或触摸电极时, 电容值会发生变化。
上述的“触摸控制IC”,Microchip已经将这个模块作为一个外设集成到了SAME51J20A单片机中,即PTC外设。SAME51的“自容”控制器PTC的框图如下:
自制电容触摸扩展板介绍
扩展板的设计参考了硬禾学堂开源的“基于SAMD21G17D MCU的综合开发平台 https://www.eetree.cn/platform/2586”。
此外,还参考了Microchip公司的AN2934: Capacitive-Touch-Sensor-Design-Guide-DS00002934-B https://ww1.microchip.com/downloads/en/AppNotes/Capacitive-Touch-Sensor-Design-Guide-DS00002934-B.pdf
一个触摸按键:PA21。和由三个相邻的触摸按键组成的“触摸滑条”,从左往右依次连接到:PB0, PB1, PB2。
MCC配置PTC触摸模块介绍
依次点击下图中的1,2,3,4,安装触摸解决方案包括QTouch库:
在左侧的Device Resources里面,找到Touch,然后添加到Project Resources中:
触摸外设的配置需要依次点击1,2:
分别添加一个触摸按键,3个按键组成的滑条:
分配触摸引脚:
在“Tune”中可设置是否需要开启“触摸调试”:
触摸调试可以使用ATMEL(现在属于Microchip)的Data Visualizer,也可以使用MPLAB IDE + “MPLAB Touch”插件。本项目使用后者。
Microchip的触摸算法驱动库是“QTouch”库,相关的触摸按键状态值如下:
实物验证触摸状态值:
触摸实物测试:
上述测试基本表面,自行设计的触摸扩展板的触摸功能能够被识别出来。为最终实现呼吸灯亮度和速度控制打好了基础。
软件代码介绍
主函数的实现非常简单:
int main(void) {
/* Initialize all modules */
SYS_Initialize(NULL);
SERCOM5_USART_Enable();
SYSTICK_TimerCallbackSet(SysTick_CallBackMy, (int) 0);
SYSTICK_TimerStart();
LED0_PA14_Toggle();
SYSTICK_DelayMs(200);
LED0_PA14_Toggle();
SYSTICK_DelayMs(200);
LED0_PA14_Toggle();
SYSTICK_DelayMs(200);
while (true) {
/* Maintain state machines of all polled MPLAB Harmony modules. */
SYS_Tasks();
BreathLED(currentIndex);
}//end of while
/* Execution should not come here during normal operation */
return ( EXIT_FAILURE);
}//end of main.
呼吸灯的核心代码:
void BreathLED(uint32_t X) {
int i, j;
if (TuneLED > 0) {
//printf("\r\nThis line not reach");
for (i = 0; (i < TuneLED)&&(TuneLED > 0); i += (TuneLED / 10)) {
for (j = 0; j <= X; j++) {
LED0_PA14_Clear();
SimpleDelay_us(i); /* Wait i microseconds */
LED0_PA14_Set();
//SimpleDelay_us(TuneLED - i); /* Wait i microseconds */
SimpleDelay_us(120 - i); /* Wait i microseconds */
}
}
for (i = TuneLED; (i > 0)&&(TuneLED > 0); i -= (TuneLED / 10)) {
for (j = 0; j <= X; j++) {
LED0_PA14_Clear();
SimpleDelay_us(i); /* Wait i microseconds */
LED0_PA14_Set();
SimpleDelay_us(120 - i); /* Wait i microseconds*/
}
}
} else {
LED0_PA14_Set();
//printf("\r\n*****This line reached, PA14 Set");
}
}
触摸按键控制参数“TuneLED”来实现亮度调节;触摸滑条控制参数X来实现呼吸间隔调节。
void SysTick_CallBackMy(uintptr_t context) {
touch_process();
if (measurement_done_touch == 1u) {
measurement_done_touch = 0u;
// process touch data
static uint8_t key_status = 0u;
static uint8_t key_status_prev = 0;
static uint8_t scroller_status = 0u;
//uint16_t scroller_position = 0u;
key_status_prev = key_status;
key_status = get_sensor_state(0) & KEY_TOUCHED_MASK;
scroller_status = get_scroller_state(0);
//printf("\r\n sensor state: %x", get_sensor_state(0));
//if (0u != key_status) {
if ((key_status_prev != key_status)&&(!key_status)) {
roungButtonCnt++;
//if (roungButtonCnt >> 2) {
ButtonOnOffChanged = 1;
roungButtonCntModified++;
TuneLED += 20;
if (TuneLED > 120)
TuneLED = 0;
sprintf(tempStr, "\r\nTouch Button, Number:%u, TuneLED = %u", roungButtonCntModified, TuneLED);
SERCOM5_USART_Write(tempStr, sizeof (tempStr));
//}
//Touch detect
} else if (SLIDER_CONTACTED_MASK == (scroller_status & SLIDER_CONTACTED_MASK)) {
currentIndex = get_scroller_position(0) << 2;
printf("\r\n Current Scroller Position: %lu", currentIndex);
SliderChanged = 1;
}
}
}
硬件实现功能展示
系统实物正面:
按键控制呼吸灯亮度:
滑条控制呼吸灯速度:
总结
通过本次Funpack活动,首次接触“电容触摸”作为一种输入,代替了传统的机械按键,旋转编码器等,直接在PCB板上设计并实现了电容触摸按键与滑动条。结合Microchip提供的QTouch库与图形化配置工具,非常方便的实现了通过触摸按键调节呼吸灯亮度,通过触摸滑条来调节呼吸灯“闪烁速度”。
本期活动获益良多,感谢硬禾与Digikey提供的平台,感谢zds老师和诸位网友提供的协助!