- void init_cycfg_pins(void)
- {
- Cy_GPIO_Pin_Init(CYBSP_LED2_PORT, CYBSP_LED2_PIN, &CYBSP_LED2_config);
- Cy_GPIO_Pin_Init(CYBSP_LED3_PORT, CYBSP_LED3_PIN, &CYBSP_LED3_config);
- Cy_GPIO_Pin_Init(CYBSP_SWDIO_PORT, CYBSP_SWDIO_PIN, &CYBSP_SWDIO_config);
- Cy_GPIO_Pin_Init(CYBSP_SWDCK_PORT, CYBSP_SWDCK_PIN, &CYBSP_SWDCK_config);
- }
函数对LED2 与LED3 进行初始化。通过调线J6 来选择LED功能还是按键功能 ,这里选择的是按键功能
- Cy_SysInt_Init(&switch_intr_config, Switch_ISR);
初始化按键的中断
switch_intr_config 来设置引脚的中断源于中断优先级
- void Switch_ISR()
- {
- /* Clears the triggered pin interrupt */
- Cy_GPIO_ClearInterrupt(CYBSP_USER_BTN_PORT, CYBSP_USER_BTN_NUM);
- NVIC_ClearPendingIRQ(switch_intr_config.intrSrc);
- /* Set interrupt flag */
- interrupt_flag = true;
- }
中断处理函数用来清楚中断标志位。
- cy_stc_syspm_callback_t sysClkCallback =
- {
- .callback = &Cy_SysClk_DeepSleepCallback,
- .type = CY_SYSPM_DEEPSLEEP,
- .skipMode = 0UL,
- .callbackParams = &sysClkCallbackParams,
- .prevItm = NULL,
- .nextItm = NULL,
- .order = 0
- };
- /* Register Deep Sleep callback */
- Cy_SysPm_RegisterCallback(&sysClkCallback);
初始化时钟回调结构体,与注册深度睡眠回调函数
循环中主要是led3的闪烁动作设置。
2. Inductive Sensing传感器的配置于测试
接线图
TX2 --P2_0
RX2 --P2_1
TX1 --P2_4
RX1 --P2_5
LED2 -- P0_2
LED1 --P0_3
原理仔细看手册 AN239751 Flyback inductive sensing (ISX) design guide
应用说明文档
感应式传感的工作原理是,在传感器线圈与待检测的金属 / 高导电性物体之间实现电磁耦合。当金属目标物进入由传感器线圈感应产生的电磁场时,部分电磁能量会转移到该金属目标物中,如下图所示。这种转移的能量会产生一种被称为涡流的环形电流。在金属目标物中流动的涡流会在传感器线圈上感应出一个反向的电磁场,这会导致传感器线圈的有效电感降低。
Sensor 结构说明
原理说明
MCU 内部处理数据简图
软件配置使用Device pin configure 将引脚 P2_0 P2_1 P2_4 P2_5 配置称模拟的 CAPSENSE™ I/O模式
然后使用 CAPSENSE™ Configurator CAPSENSE lib的一些 功能
这个直接按照mtb-example-psoc4-msclp-isx-tom-keypad-2-buttons
readme中配置 CAPSENSE的相关参数就可以实现功能,这里不在赘述。
因为后面要用到I2C master来驱动oled12864 所以这里面没有添加 CAPSENSE™ Tuner的 功能,所有配置参数都与参考例子一样
传感器按键的状态可以通过下面函数获取到
- if (CAPSENSE_WIDGET_INACTIVE != Cy_CapSense_IsWidgetActive(CY_CAPSENSE_BUTTON0_WDGT_ID, &cy_capsense_context))
这里面我们将其当做 read_gpio()读接口状态的这种功能。后面在具体详细看其实现代码
此处需要在软件中截图
3. CAP Sensing 传感器
有图可知这个CAP 传感器俺键盘 有 3层组层
Arylic overlay 覆盖物层 ,按键感应层 ,还有GND 层 三层组成
- Cy_CapSense_ScanAllWidgets(&cy_capsense_context);
- /* This is a place where all interrupt handlers will be executed */
- 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);
- /* Process all th widgets */
- Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);
- /* Send capsense data to the Tuner */
- Cy_CapSense_RunTuner(&cy_capsense_context);
- led_control();
for 循环中主要处理 Cap Widgets的 扫描,休眠状态进入,还有就是对于读取到的sense数据的 处理。将数据上传到 tunner(这里没有到)。 按键过程的处理 (按下,对于的led会亮起)Cy_CapSense_IsWidgetActive(CY_CAPSENSE_BUTTON1_WDGT_ID, &cy_capsense_context)通过这个函数来读取当前按键的状态
4. CAP 液位传感器配置测试原理
通过检测相连两两两之间的电极的电容变化来测量液位
建立了0~8 9个slot
- uint32_t level_w_FR, level_wo_FR; /* Scan the normal Liquid Level Widget */
- Cy_CapSense_ScanWidget(CY_CAPSENSE_LIQUIDLEVEL0_WDGT_ID, &cy_capsense_context); /* Wait until the scan is finished */
- while (Cy_CapSense_IsBusy(&cy_capsense_context))
- {
- } /* Scan the Foam Rejection Widget */
- Cy_CapSense_ScanWidget(CY_CAPSENSE_LIQUIDLEVEL0_FR_WDGT_ID, &cy_capsense_context); /* Wait until the scan is finished */
- while (Cy_CapSense_IsBusy(&cy_capsense_context))
- {
- } /* Process all th widgets */
- Cy_CapSense_ProcessAllWidgets(&cy_capsense_context); /* Send capsense data to the Tuner */
- Cy_CapSense_RunTuner(&cy_capsense_context); /* store the liquid level before and after foam rejection */
- level_wo_FR = CY_CAPSENSE_LIQUIDLEVEL0_PTRPOSITION_VALUE->x;
- level_w_FR = CY_CAPSENSE_LIQUIDLEVEL0_FR_PTRPOSITION_VALUE->x;
扫描读取液位的slot与泡沫的 slot 然后处理通过CapSense_rununer把相关数据发送出去
5. SCBI2C 配置于测试实验(驱动oled12864)板子的I2C的信号线SDA ,SCL 是P2.3与P2.2. 通过拨码开关SW2可以切换与Debug IC 通过UART连接或者是 I2C连接。这里我直接用杜邦线连接OLED与板子上的24pin引脚。
这里借助于系统的历程 I2C_Master_EzI2C_Slave
我们将EzI2C_Slave的部分注释调只是用I2C Master 的部分
其代码配置与 Inductive 类似 只是要选择CAP Sensor的属性
I2C 结构体初始化
- cy_stc_scb_i2c_master_xfer_config_t masterTransferCfg = { //.slaveAddress = I2C_SLAVE_ADDR, .slaveAddress = SSD1306_I2C_ADDR, .buffer = NULL, .bufferSize = 0U, .xferPending = false};
- 将一下代码替换 static uint8_t ssd1306_WriteCommand(CySCB_Type * hi2c, uint8_t command){uint8_t buf[2] = {0};
- buf[1] = command;
- return HAL_I2C_Mem_Write(hi2c, SSD1306_I2C_ADDR, 0x00, 1, &command, 1, 10);
- }
- static uint8_t ssd1306_WriteCommand(CySCB_Type *hi2c, uint8_t command)
- {
- uint8_t buf[2] = {0};
- buf[1] = command;
- return WritePacketToEzI2C(buf, 2); // return HAL_I2C_Mem_Write(hi2c, SSD1306_I2C_ADDR, 0x00, 1, &command, 1, 10);}
在ssd1306.c中添加Cy的头文件 与I2C的头文件 还有oled1306的头文件
我们在程序中加入 测试
6. TCPWM 计数器配置于测试试验由于DIY以后会用到MultiButton的,里面要添加一个5ms的定时器功能。我们将MultiButton 的代码 clone 到我们的工程路径下,然后在path中添加MultiButton 的路径。包含原文件,并且include 头文件 。然后使用 Device Configurator 工具配置 TCPWM的相关内容,这里面 我们选择 时钟48Mhz ,3分配, counter模式 。
分频后时钟16Mhz
在Device config中配置相关外设
在终端处理函数中加入一下代码
- void timer_Cnt0_init(void)
- {
- if (CY_TCPWM_SUCCESS != Cy_TCPWM_Counter_Init(TCPWM, MY_TCPWM_CNT_NUM, &tcpwm_0_cnt_0_config))
- {
- /* Handle possible errors */
- // Cy_SCB_UART_PutString(CYBSP_UART_HW, "TCPWM_Error\r\n");
- }
- NVIC_ClearPendingIRQ(tcpwm_0_cnt_0_IRQ);
- NVIC_EnableIRQ(tcpwm_0_cnt_0_IRQ);
- /* Enable the initialized counter */
- Cy_TCPWM_Counter_Enable(TCPWM, MY_TCPWM_CNT_NUM);
- //Cy_TCPWM_TriggerStart(TCPWM, MY_TCPWM_CNT_MASK);
- }
-
- void time_count_start(void){
- Cy_TCPWM_TriggerStart(TCPWM, MY_TCPWM_CNT_MASK);
- }
终端处理函数
- static uint32_t mystick = 0;
- void tcpwm_interrupts_0_IRQHandler(void)
- {
- uint32_t interrupts = Cy_TCPWM_GetInterruptStatus(TCPWM, MY_TCPWM_CNT_NUM); /* Now the 'interrupts' contains all the currently pending interrupt masks */
- if (0UL != (CY_TCPWM_INT_ON_TC & interrupts))
- {
- mystick++;
- if (mystick == 5)
- { /* There is a pending Terminal Count interrupt */
- button_ticks();
- // Cy_GPIO_Write(CYBSP_USER_LED_PORT, CYBSP_USER_LED_NUM,state);
- mystick = 0;
- //Cy_SCB_UART_PutString(CYBSP_UART_HW,"tcpwm_open\r\n");
- }
- }
- /* Get all the enabled pending interrupts */
- if (0UL != (CY_TCPWM_INT_ON_CC & interrupts))
- {
- /* Handle the Compare/Capture event */
-
- } /* Clear the interrupt */
- Cy_TCPWM_ClearInterrupt(TCPWM, MY_TCPWM_CNT_NUM, interrupts);
- }
- // 写一个测试程序 ,当P0.1 按键按下时 P3_0 会点亮
- int testbutton(void)
- {
- button_init(&btn1, read_button_GPIO, 0, btn1_id);
- button_attach(&btn1, PRESS_DOWN, BTN1_PRESS_DOWN_Handler);
- button_attach(&btn1, PRESS_UP, BTN1_PRESS_UP_Handler);
- // button_attach(&btn1, PRESS_REPEAT, BTN1_PRESS_REPEAT_Handler);//
-
- }
7. TCPPWM PWM配置于测试实验配置TCPWM1 为PWM模式,这里主要将PWM频率设置为2.7Khz左右 然后使得LED2 以呼吸灯形式显示。
测试代码
- <div class="blockcode"><blockquote>#define MY_TCPWM_PWM_NUM (1UL)
- #define MY_TCPWM_PWM_MASK(1UL << MY_TCPWM_PWM_NUM)
- int test()
- {
- if (CY_TCPWM_SUCCESS != Cy_TCPWM_PWM_Init(TCPWM, MY_TCPWM_PWM_NUM, &tcpwm_0_cnt_1_config))
- { /* Handle possible errors */
- } /* Enable the initialized PWM */
- Cy_TCPWM_PWM_Enable(TCPWM, MY_TCPWM_PWM_NUM); /* Then start the PWM */
- Cy_TCPWM_TriggerReloadOrIndex(TCPWM, MY_TCPWM_PWM_MASK);
- int i = 0;
- int dirc = 0;
- if (!dirc)
- {
- i = i + 10;
- if (i > 370)
- dirc = 1;
- }
- if (dirc)
- {
- i -= 10;
- if (i <= 0)
- {
- dirc = 0;
- }
- }
- Cy_TCPWM_PWM_SetCompare0(TCPWM, MY_TCPWM_PWM_NUM, i);
- }
心得1 CapSense 触摸感应
PSoC 4000T的CapSense模块支持自电容和互电容检测,适合按钮、滑条、接近感应等应用
使用时可以通过相关工具可以很轻松的配置一个触摸传感按键,或者液位应有
看手册,在制作按键或者液位传感器时 对于布局布线,材料有着很严格的要求需要画一些时间对于硬件校验已达到产品要求
2 低功耗
PSoc 4000T 有很好的低功耗特性非常适合与这类传感或可穿戴触摸之类的应用。
3 配置工具
配置工具界面操作很方便,对照手册很方便可以配置相关的功能。