本帖最后由 南来之风 于 2025-4-12 11:44 编辑
非常感谢英飞凌与21ic联合赠送的PSOC™ 4000T Multi-Sense Kit,这是一个完整的触摸方案验证原型,包含了接触、隔空和液体等多种应用场景。
官网资料介绍:CY8CPROTO-040T-MS PSOC™ 4000T Multi-Sense Prototyping Kit https://www.infineon.com/cms/cn/product/evaluation-boards/cy8cproto-040t-ms/#!designsupport
三块触摸模块:2按键、4按键与悬浮触控
主控板:
参数信息 CY8CPROTO-040T-MS蓝牙标准 无
电容式感应技术 按键(悬停触摸)、金属表面触摸、液位传感器
内核 ARM Cortex - M0+
器件 CY8C4046LQI-T452
系列 赛普拉斯(PSoC™)4000T 微控制器
特性 电感式感应、液位感应、悬停触摸、金属表面触摸、可扩展的引脚头,用于定制人机界面(HMI)板
编程器 / 调试器 板载 KitProg
传感器 电容式、电感式、液位传感器
软件支持 ModusToolbox
开发环境的安装从ModusToolBox工具箱开始:
在创建项目的时候,选择本次活动板卡:CY8CPROTO-040T-MS
本次体验直奔主题“触摸”,选择4按键扩展板触摸demo:
之后需要从Git上克隆项目到本地,如果遇到下载错误,可以参考英飞凌社区的帖子:
ModusToolbox URL Modifier https://community.infineon.com/t5/Code-Examples/ModusToolbox-URL-Modifier/m-p/366015#.
等待项目下载,点击小锤子图标进行编译
==============================================================================
= Build complete =
==============================================================================
Calculating memory consumption: CY8C4046LQI-T452 GCC_ARM
----------------------------------------------------
| Section Name | Address | Size |
----------------------------------------------------
| .text | 0x00000000 | 24184 |
| .ARM.exidx | 0x00005e78 | 8 |
| .copy.table | 0x00005e80 | 12 |
| .zero.table | 0x00005e8c | 8 |
| .ramVectors | 0x20000000 | 192 |
| .data | 0x200000c0 | 1252 |
| .noinit | 0x200005a8 | 32 |
| .bss | 0x200005c8 | 900 |
| .heap | 0x2000094c | 4788 |
| .stack | 0x20001c00 | 1024 |
----------------------------------------------------
Total Internal Flash (Available) 65536
Total Internal Flash (Utilized) 25464
09:53:25 Build Finished. 0 errors, 0 warnings. (took 51s.833ms)
连接硬件
在设备->端口,查看是否有KitProg3设备
主要代码分析:通过调用cybsp_init()来初始化设备与板载外设。
cy_rslt_t cybsp_init(void)
{
cy_rslt_t result = CY_RSLT_SUCCESS;
#if defined(CY_USING_HAL)
result = cyhal_hwmgr_init();
if (CY_RSLT_SUCCESS == result)
{
result = cyhal_syspm_init();
}
#ifdef CY_CFG_PWR_VDDA_MV
if (CY_RSLT_SUCCESS == result)
{
cyhal_syspm_set_supply_voltage(CYHAL_VOLTAGE_SUPPLY_VDDA, CY_CFG_PWR_VDDA_MV);
}
#endif
#endif // if defined(CY_USING_HAL)
init_cycfg_all();
if (CY_RSLT_SUCCESS == result)
{
#if defined(CYBSP_CUSTOM_SYSCLK_PM_CALLBACK)
result = cybsp_register_custom_sysclk_pm_callback();
#else
result = cybsp_register_sysclk_pm_callback();
#endif
}
return result;
}
代码里有初始化tuner模块,通过调用initialize_capsense_tuner()。这里应该是有一个电容触摸调试的功能。
接下来初始化电容触摸模块:
/* Initialize MSC CAPSENSE™ */
initialize_capsense();
/* Measures the actual ILO frequency and compensate MSCLP wake up timers */
Cy_CapSense_IloCompensate(&cy_capsense_context);
/* Configure the MSCLP wake up timer as per the ACTIVE mode refresh rate */
Cy_CapSense_ConfigureMsclpTimer(ACTIVE_MODE_TIMER, &cy_capsense_context);
之后有个for循环来根据是否在TimeOut时间内检测到触摸等分成了三个状态:ACTIVE_MODE、ALR_MODE (Active Low Refresh-rate Mode)和WOT_MODE (Wake On Touch Mode)。
for (;;)
{
switch(capsense_state)
{
case ACTIVE_MODE:
Cy_CapSense_ScanAllSlots(&cy_capsense_context);
interruptStatus = Cy_SysLib_EnterCriticalSection();
while (Cy_CapSense_IsBusy(&cy_capsense_context))
{
Cy_SysPm_CpuEnterDeepSleep();
Cy_SysLib_ExitCriticalSection(interruptStatus);
/* This is a place where all interrupt handlers will be executed */
interruptStatus = Cy_SysLib_EnterCriticalSection();
}
Cy_SysLib_ExitCriticalSection(interruptStatus);
#if ENABLE_RUN_TIME_MEASUREMENT
active_processing_time=0;
start_runtime_measurement();
#endif
Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);
/* Scan, process and check the status of the all Active mode sensors */
if(Cy_CapSense_IsAnyWidgetActive(&cy_capsense_context))
{
capsense_state_timeout = ACTIVE_MODE_TIMEOUT;
}
else
{
capsense_state_timeout--;
if(TIMEOUT_RESET == capsense_state_timeout)
{
capsense_state = ALR_MODE;
capsense_state_timeout = ALR_MODE_TIMEOUT;
/* Configure the MSCLP wake up timer as per the ALR mode refresh rate */
Cy_CapSense_ConfigureMsclpTimer(ALR_MODE_TIMER, &cy_capsense_context);
}
}
#if ENABLE_RUN_TIME_MEASUREMENT
active_processing_time=stop_runtime_measurement();
#endif
break;
/* End of ACTIVE_MODE */
/* Active Low Refresh-rate Mode */
case ALR_MODE :
Cy_CapSense_ScanAllSlots(&cy_capsense_context);
interruptStatus = Cy_SysLib_EnterCriticalSection();
while (Cy_CapSense_IsBusy(&cy_capsense_context))
{
Cy_SysPm_CpuEnterDeepSleep();
Cy_SysLib_ExitCriticalSection(interruptStatus);
/* This is a place where all interrupt handlers will be executed */
interruptStatus = Cy_SysLib_EnterCriticalSection();
}
Cy_SysLib_ExitCriticalSection(interruptStatus);
#if ENABLE_RUN_TIME_MEASUREMENT
alr_processing_time=0;
start_runtime_measurement();
#endif
Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);
/* Scan, process and check the status of the all Active mode sensors */
if(Cy_CapSense_IsAnyWidgetActive(&cy_capsense_context))
{
capsense_state = ACTIVE_MODE;
capsense_state_timeout = ACTIVE_MODE_TIMEOUT;
/* Configure the MSCLP wake up timer as per the ACTIVE mode refresh rate */
Cy_CapSense_ConfigureMsclpTimer(ACTIVE_MODE_TIMER, &cy_capsense_context);
}
else
{
capsense_state_timeout--;
if(TIMEOUT_RESET == capsense_state_timeout)
{
capsense_state = WOT_MODE;
}
}
#if ENABLE_RUN_TIME_MEASUREMENT
alr_processing_time=stop_runtime_measurement();
#endif
break;
/* End of Active-Low Refresh Rate(ALR) mode */
/* Wake On Touch Mode */
case WOT_MODE :
Cy_CapSense_ScanAllLpSlots(&cy_capsense_context);
interruptStatus = Cy_SysLib_EnterCriticalSection();
while (Cy_CapSense_IsBusy(&cy_capsense_context))
{
Cy_SysPm_CpuEnterDeepSleep();
Cy_SysLib_ExitCriticalSection(interruptStatus);
/* This is a place where all interrupt handlers will be executed */
interruptStatus = Cy_SysLib_EnterCriticalSection();
}
Cy_SysLib_ExitCriticalSection(interruptStatus);
if (Cy_CapSense_IsAnyLpWidgetActive(&cy_capsense_context))
{
capsense_state = ACTIVE_MODE;
capsense_state_timeout = ACTIVE_MODE_TIMEOUT;
/* Configure the MSCLP wake up timer as per the ACTIVE mode refresh rate */
Cy_CapSense_ConfigureMsclpTimer(ACTIVE_MODE_TIMER, &cy_capsense_context);
}
else
{
capsense_state = ALR_MODE;
capsense_state_timeout = ALR_MODE_TIMEOUT;
/* Configure the MSCLP wake up timer as per the ALR mode refresh rate */
Cy_CapSense_ConfigureMsclpTimer(ALR_MODE_TIMER, &cy_capsense_context);
}
break;
/* End of "WAKE_ON_TOUCH_MODE" */
default:
/** Unknown power mode state. Unexpected situation. **/
CY_ASSERT(CY_ASSERT_FAILED);
break;
}
#if ENABLE_LED
led_control();
#endif
#if ENABLE_TUNER
/* Establishes synchronized communication with the CAPSENSE™ Tuner tool */
Cy_CapSense_RunTuner(&cy_capsense_context);
#endif
}
之后根据4个按键的状态来点亮或者熄灭扩展板上的4个LED。
void led_control()
{
if (CAPSENSE_WIDGET_INACTIVE != Cy_CapSense_IsWidgetActive(CY_CAPSENSE_BUTTON0_WDGT_ID, &cy_capsense_context))
{
Cy_GPIO_Write(CYBSP_KEYPAD_LED1_PORT, CYBSP_KEYPAD_LED1_NUM, CYBSP_LED_ON);
}
else
{
Cy_GPIO_Write(CYBSP_KEYPAD_LED1_PORT, CYBSP_KEYPAD_LED1_NUM, CYBSP_LED_OFF);
}
if (CAPSENSE_WIDGET_INACTIVE != Cy_CapSense_IsWidgetActive(CY_CAPSENSE_BUTTON1_WDGT_ID, &cy_capsense_context))
{
Cy_GPIO_Write(CYBSP_KEYPAD_LED2_PORT, CYBSP_KEYPAD_LED2_NUM, CYBSP_LED_ON);
}
else
{
Cy_GPIO_Write(CYBSP_KEYPAD_LED2_PORT, CYBSP_KEYPAD_LED2_NUM, CYBSP_LED_OFF);
}
if (CAPSENSE_WIDGET_INACTIVE != Cy_CapSense_IsWidgetActive(CY_CAPSENSE_BUTTON2_WDGT_ID, &cy_capsense_context))
{
Cy_GPIO_Write(CYBSP_KEYPAD_LED3_PORT, CYBSP_KEYPAD_LED3_NUM, CYBSP_LED_ON);
}
else
{
Cy_GPIO_Write(CYBSP_KEYPAD_LED3_PORT, CYBSP_KEYPAD_LED3_NUM, CYBSP_LED_OFF);
}
if (CAPSENSE_WIDGET_INACTIVE != Cy_CapSense_IsWidgetActive(CY_CAPSENSE_BUTTON3_WDGT_ID, &cy_capsense_context))
{
Cy_GPIO_Write(CYBSP_KEYPAD_LED4_PORT, CYBSP_KEYPAD_LED4_NUM, CYBSP_LED_ON);
}
else
{
Cy_GPIO_Write(CYBSP_KEYPAD_LED4_PORT, CYBSP_KEYPAD_LED4_NUM, CYBSP_LED_OFF);
}
}
最后调试后全速运行:
看一下代码运行在PSCOC400T实物上:
整体开发感受是ModusToolbox生态非常完善,通过ToobBOx的Setup程序可以添加项目上用到的模块;通过Toolbox的IDE可以从官方GIT克隆样例程序,同时也内置了编译器、调试器等必须组件。
硬件做工配得上英飞凌全球微控制器领导者的形象,扎实,硬件布局合理,质量非常好。
下一步计划体验一下电容触摸调试模块的用法。
|