2024年寒假在家一起练 - 基于英飞凌PSoc62 MCU实现触摸滑条控制USB鼠标
该项目使用了Psoc触摸滑条,实现了USB鼠标的设计,它的主要功能为:Psoc触摸滑条控制USB鼠标左右滑动。
标签
嵌入式系统
参加活动/培训
yechoo
更新2024-03-28
223

基于英飞凌PSoC62 MCU的Capsense电脑鼠标控制方案

项目需求:

本项目旨在利用英飞凌PSoC62微控制器的特性,通过板卡上的CAPSENSE触摸滑条实现对电脑鼠标移动的控制。

硬件介绍

主要特性

  • MCU型号: CY8C624ALQI-S2D42,配备Cortex-M4核心主频150MHz和Cortex-M0核心主频100MHz。
  • 存储: 2MB Flash、1MB SRAM以及8KB数据闪存,提供EEPROM类似的数据存储功能。
  • 拓展性: 兼容Arduino接口,支持市面上大多数Arduino接口拓展板。
  • CAPSENSE技术: 支持CAPSENSE电容和电感式触摸感应,提供增强型电容触摸感应单元(CTSU2),适用于多种应用场景。
  • 调试器: 集成KitProg3-DAP-Link调试器,用于编程和调试通信固件。

软件选择

1、RTT studio:

RTT官方推荐软件,支持总多外设,如:GPIO、UART、I2C、RTC、PWM、DAC、SPI等,可使用RT-Thread操作系统。缺点目前没有适配USB驱动,若使用USB驱动需要自己适配。

2、 Modus

官方推荐开发软件,具有总多外设例程,可谓应有尽有。缺点:可能需要科学上网,软件功能强大,需要花费一定时间了解。

PSOC库的简单介绍

官方库包含HAL、PDL库等,其中关系见下图。

设计思路

  1. 驱动CAPSENSE触摸滑条,控制LED灯亮度。
  2. 驱动USB鼠标,实现鼠标在桌面左右移动。
  3. 结合以上两个设计,实现CAPSENSE触摸滑条控制USB鼠标移动。

实现过程

CAPSENSE触摸初始化

1、初始化触摸滑条接口

 static void initialize_capsense_tuner(void)
{
  cy_rslt_t result;

  /* Configure Capsense Tuner as EzI2C Slave */
  sEzI2C_sub_cfg.buf = (uint8 *)&cy_capsense_tuner;
  sEzI2C_sub_cfg.buf_rw_boundary = sizeof(cy_capsense_tuner);
  sEzI2C_sub_cfg.buf_size = sizeof(cy_capsense_tuner);
  sEzI2C_sub_cfg.slave_address = 8U;
   
  sEzI2C_cfg.data_rate = CYHAL_EZI2C_DATA_RATE_400KHZ;
  sEzI2C_cfg.enable_wake_from_sleep = false;
  sEzI2C_cfg.slave1_cfg = sEzI2C_sub_cfg;
  sEzI2C_cfg.sub_address_size = CYHAL_EZI2C_SUB_ADDR16_BITS;
  sEzI2C_cfg.two_addresses = false;
   
  result = cyhal_ezi2c_init(&sEzI2C, CYBSP_I2C_SDA, CYBSP_I2C_SCL, NULL, &sEzI2C_cfg);
  if (result != CY_RSLT_SUCCESS)
  {
      handle_error();
  }

}

2、初始化触摸滑条和中断

static uint32_t initialize_capsense(void)
{
  uint32_t status = CYRET_SUCCESS;

  /* CapSense interrupt configuration parameters */
  static const cy_stc_sysint_t capSense_intr_config =
  {
      .intrSrc = csd_interrupt_IRQn,
      .intrPriority = CAPSENSE_INTR_PRIORITY,
  };
   
  /* Capture the CSD HW block and initialize it to the default state. */
  status = Cy_CapSense_Init(&cy_capsense_context);
  if (CYRET_SUCCESS != status)
  {
      return status;
  }
   
  /* Initialize CapSense interrupt */
  cyhal_system_set_isr(csd_interrupt_IRQn, csd_interrupt_IRQn, CAPSENSE_INTR_PRIORITY, &capsense_isr);
  NVIC_ClearPendingIRQ(capSense_intr_config.intrSrc);
  NVIC_EnableIRQ(capSense_intr_config.intrSrc);
   
  /* Initialize the CapSense firmware modules. */
  status = Cy_CapSense_Enable(&cy_capsense_context);
  if (CYRET_SUCCESS != status)
  {
      return status;
  }
   
  /* Assign a callback function to indicate end of CapSense scan. */
  status = Cy_CapSense_RegisterCallback(CY_CAPSENSE_END_OF_SCAN_E,
          capsense_callback, &cy_capsense_context);
  if (CYRET_SUCCESS != status)
  {
      return status;
  }
   
  return status;

}

添加鼠标类到USB

static void usb_add_hid(void) {
  USB_HID_INIT_DATA InitData;
  USB_ADD_EP_INFO   EPIntIn;

  memset(&InitData, 0, sizeof(InitData));
  memset(&EPIntIn, 0, sizeof(EPIntIn));
  EPIntIn.Flags           = 0;                             /* Flags not used */
  EPIntIn.InDir           = USB_DIR_IN;                   /* IN direction (Device to Host) */
  EPIntIn.Interval       = 64;                           /* Interval of 8 ms (125 us * 64) */
  EPIntIn.MaxPacketSize   = USB_FS_INT_MAX_PACKET_SIZE;   /* Maximum packet size (64 for Interrupt) */
  EPIntIn.TransferType   = USB_TRANSFER_TYPE_INT;         /* Endpoint type - Interrupt */
   
  InitData.EPIn = USBD_AddEPEx(&EPIntIn, NULL, 0);
  InitData.pReport = usb_HIDReport;
  InitData.NumBytesReport = sizeof(usb_HIDReport);
  usb_hidContext = USBD_HID_Add(&InitData);

}

核心控制代码

for (;;)
{

  /* Wait for configuration */
  while ((USBD_GetState() & USB_STAT_CONFIGURED ) != USB_STAT_CONFIGURED)
  {
  cyhal_system_delay_ms(50);
  }

  counter++;

  memset(mouse_data, 0, MOUSE_DATA_LEN);

  if (capsense_scan_complete)
  {
  /* Process all widgets */
  Cy_CapSense_ProcessAllWidgets(&cy_capsense_context);

  /* Process touch input */
  /* Get slider status */
  slider_touch_info = Cy_CapSense_GetTouchInfo(
  CY_CAPSENSE_LINEARSLIDER0_WDGT_ID, &cy_capsense_context);
  slider_touch_status = slider_touch_info->numPosition;
  slider_pos = slider_touch_info->ptrPosition->x;

  /* Detect the new touch on slider */
  if ((0 != slider_touch_status) &&
  (slider_pos > slider_pos_prev))
  {
  mouse_data[CURSOR_STEP_POS] = 10;
  }

  if ((0 != slider_touch_status) &&
  (slider_pos < slider_pos_prev))
  {
  mouse_data[CURSOR_STEP_POS] = -10;
  }

  slider_pos_prev = slider_pos;
  /* Establishes synchronized operation between the CapSense
  * middleware and the CapSense Tuner tool.
  */
  Cy_CapSense_RunTuner(&cy_capsense_context);

  /* Initiate next scan */
  Cy_CapSense_ScanAllWidgets(&cy_capsense_context);

  capsense_scan_complete = false;
  }

  /* Write data to host*/
  USBD_HID_Write(usb_hidContext, &mouse_data[0], MOUSE_DATA_LEN, 0);      

  cyhal_system_delay_ms(10);

}

主要难题

modus软件使用问题

1、modus软件创建工程问题

科学上网

2、modus软件添加capsense库的问题

在左下角中找到Tools模块内的Library Manager管理添加自己使用到的库

3、modus软件修改引脚等配置问题

在左下角中找到Tools模块内的BSP Assistant进行设置

未来建议

提高触摸滑条精度

目前触摸滑条控制USB鼠标精度不高,经常移动的过程中出现小幅度反方向移动

探索其他传感器和接口,以实现扩展应用。

代码下载链接

链接:https://pan.baidu.com/s/1X0cpB77S49mgoCzbovv3TA?pwd=q8dr
提取码:q8dr

团队介绍
江洛涵-湖北工业大学
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号