[STM32U3] 【STM32U385RG 测评】+ 通讯与触觉控制

[复制链接]
601|0
jinglixixi 发表于 2025-8-13 19:56 | 显示全部楼层 |阅读模式
本帖最后由 jinglixixi 于 2025-8-14 09:43 编辑

#申请原创#
对于听力障碍人来说,在意外来临前将感知的危险信息传递给他们是件非常重要的事情。那么如何来解决这个问题呢?
我们可以将采集到的危险信息以触觉的方式来传递给他们,如在火焰传感器感知到危险时,可以无线通讯的方式传递到配有触觉振动效果的手镯上来停止他们
为简化信息传递过程,这里先以串行通讯的方式来控制触觉马达的振动。
1. 触觉马达控制
1)触觉马达
在泰坦触觉TITAN Core开发套件中,提供了一块基于ESP32的高度集成触觉评估板4个不同型号的触觉马达,见图1和图2所示。别看该开发套件不起眼,它可是能进行蓝牙播放音乐的。
图片1.png
1 开发板


图片2.png
2 触觉马达


触觉评估板的引脚排列如图3所示,它支持以串口通讯的方式来控制触觉马达。
图片3.png
3 引脚排列


对于4个触觉马达来讲,其特点如下:
低频马达 (LF):非常适用营造深沉的超低音震感
中频马达 (MF):适用于通用的触觉反馈
高频马达 (HF):专为呈现高频质感和发出提醒设计
低频冲击马达 (LFi):结合了低频响应与冲击式振动


2)控制测试
利用STM32U385开发板的串行通讯功能,可以控制触觉马达的振动效果。
为便于控制,可将不同振动效果的指令存放到数组中。
以触觉指令"pulse 0.5 50 0.5;"为例,其字节内容为:70 75 6C 73 65 20 30 2E 35 20 35 30 20 30 2E 35 3B
对于触觉指令"tick 0.5 50 1.0;",其字节内容为:74 69 63 6B 20 30 2E 35 20 35 30 20 31 2E 30 3B
对于触觉指令"vibrate 250 1 10 0.5 1;"的字节内容则为:76 69 62 72 61 74 65 20 32 35 30 20 31 20 31 30 20 30 2E 35 20 31 3B
相应的指令数组如下
// "pulse 0.5 50 0.5;"
uint8_t CJMD_1[17]={0X70,0X75,0X6C,0X73,0X65,0X20,0X30,0X2E,0X35,0X20,0X35,0X30,0X20,0X30,0X2E,0X35,0X3B};
// "tick 0.5 50 1.0;"
uint8_t CJMD_2[16]={0X74,0X69,0X63,0X6B,0X20,0X30,0X2E,0X35,0X20,0X35,0X30,0X20,0X31,0X2E,0X30,0X3B};
// "vibrate 250 1 10 0.5 1;"
uint8_t CJMD3[23]={0X76,0X69,0X62,0X72,0X61,0X74,0X65,0X20,0X32,0X35,0X30,0X20,0X31,0X20,0X31,0X30,0X20,0X30,0X2E,0X35,0X20,0X31,0X3B};

此外,为进行字符串指令向为字节形式的转换,可先发送字符串指令,然后再以十六进制的方式来显示接收到的内容。见图4所示。
图片4.png
4 指令形式转换


2. 触发信号源
1)传感器触发
以火患预防为例,可使用火焰传感器来感知周围环境的火患情况,当检测到数据变化异常后,就通过串口发送相应的触觉提示指令以告知服务对象。
2)按键触发
出使用传感器感知异常情况外,还可以通过按键将感知的异常情况告知服务对象,即按键触发提示指令的发出。
实现按键触发的主程序为:
  1. int main(void)
  2. {
  3.   HAL_Init();
  4.   SystemClock_Config();
  5.   BSP_LED_Init(LD2);
  6.   MX_GPIO_Init();
  7.   MX_USART1_UART_Init();
  8.   MX_ICACHE_Init();
  9.   KEY_Config();        
  10.   while (1)
  11.   {
  12.            if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)==GPIO_PIN_SET)
  13.            {                                 
  14.                     HAL_UART_Transmit(&huart1, (uint8_t *)&CJMD_2, 16, 0xFFFF);
  15.            }
  16.           BSP_LED_Toggle(LD2);
  17.           HAL_Delay(500);
  18.   }
  19. }
图片5.png
5 触发测试


在使用串口通讯控制触觉马达时,使用的串口引脚为:
Tx Pin----PA9
Rx Pin----PA10


所用接口及引脚如图6所示,与触觉马达的连接如图7所示。
图片6.png
6 所用接口及引脚

图片7.png
7 连接及测试


实现传感器及按键触发提示的主程序为:
  1. int main(void)
  2. {
  3.   HAL_Init();
  4.   SystemClock_Config();
  5.   MX_GPIO_Init();
  6.   MX_ADC1_Init();
  7.   MX_ICACHE_Init();
  8.   BSP_LED_Init(LD2);
  9.   MX_USART1_UART_Init();
  10.   KEY_Config();
  11.   if (HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED) != HAL_OK)
  12.   {
  13.     Error_Handler();
  14.   }
  15.   if (HAL_ADC_Start(&hadc1) != HAL_OK)
  16.   {
  17.     Error_Handler();
  18.   }
  19.   if (HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)
  20.   {
  21.     Error_Handler();
  22.   }
  23.   I2C_CONFIG();
  24.   HAL_Delay(50);
  25.   while (1)
  26.   {
  27.        uhADCxConvertedData = HAL_ADC_GetValue(&hadc1);
  28.        uhADCxConvertedData_Voltage_mVolt = __LL_ADC_CALC_DATA_TO_VOLTAGE(VDDA_APPLI,               uhADCxConvertedData, LL_ADC_RESOLUTION_12B);
  29.         if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)==GPIO_PIN_SET)
  30.         {                                 
  31.                     HAL_UART_Transmit(&huart1, (uint8_t *)&CJMD_2, 16, 0xFFFF);
  32.         }
  33.         if(uhADCxConvertedData_Voltage_mVolt >xz )
  34.         {                                 
  35.                     HAL_UART_Transmit(&huart1, (uint8_t *)&CJMD_3, 23, 0xFFFF);
  36.         }
  37.         BSP_LED_On(LD2);
  38.         HAL_Delay(LED_BLINK_SLOW);
  39.         BSP_LED_Off(LD2);
  40.         HAL_Delay(LED_BLINK_SLOW);  
  41.    }
  42. }
在采用界面化管理的情况下,其界面如图图8所示。
图片8.png
8 显示屏所用接口及引脚

图片9.png
9 按键所用接口及引脚

图片10.png
10 器件连接

在采用界面化管理的情况下,其界面如图图11所示。

图片11.png
11 界面形式

软键盘所用引脚连接关系为:
K1------PC10
K2------PC11
K3------PC12
K4------PD2


软键盘所用引脚初始化函数为:
  1. void KEY_Config(void)
  2. {  
  3.         static GPIO_InitTypeDef  GPIO_InitStruct;        
  4.         __HAL_RCC_GPIOC_CLK_ENABLE();
  5.         GPIO_InitStruct.Mode  = GPIO_MODE_INPUT;
  6.         GPIO_InitStruct.Pull  = GPIO_PULLUP;
  7.         GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  8.         GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
  9.         HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);        
  10.         __HAL_RCC_GPIOD_CLK_ENABLE();
  11.         GPIO_InitStruct.Pin = GPIO_PIN_2;
  12.         HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  13. }
实现多键值分析处理的主程序为:
  1. int main(void)
  2. {
  3.   HAL_Init();
  4.   SystemClock_Config();
  5.   MX_GPIO_Init();
  6.   MX_ADC1_Init();
  7.   MX_ICACHE_Init();
  8.   BSP_LED_Init(LD2);
  9.   if (HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED) != HAL_OK)
  10.   {
  11.     Error_Handler();
  12.   }
  13.   if (HAL_ADC_Start(&hadc1) != HAL_OK)
  14.   {
  15.     Error_Handler();
  16.   }
  17.   if (HAL_ADC_PollForConversion(&hadc1, 10) != HAL_OK)
  18.   {
  19.     Error_Handler();
  20.   }
  21.   HAL_Delay(50);
  22.   SPI_CONFIG();
  23.   tft_Init();
  24.   LCD_Clear(RED);
  25.   BACK_COLOR=RED;
  26.   POINT_COLOR=WHITE;
  27.   LCD_ShowString(240,10," 8:30:00");
  28.   show_tbh(20,45,7);
  29.   show_tbh(97,45,0);
  30.   show_tbh(174,45,5);
  31.   show_tbh(250,45,6);        
  32.   show_tbh(20,145,1);
  33.   show_tbh(97,145,2);
  34.   show_tbh(174,145,4);
  35.   show_tbh(250,145,3);        
  36.   POINT_COLOR=YELLOW;
  37.   LCD_DrawLine(0, 32, 319,32);
  38.   showhanzi16h(90,10,0,0);
  39.   showhanzi16h(110,10,1,0);        
  40.   showhanzi16h(130,10,2,0);
  41.   showhanzi16h(150,10,3,0);
  42.   showhanzi16h(170,10,4,0);
  43.   showhanzi16h(190,10,5,0);
  44.   showhanzi16h(210,10,6,0);
  45.   showhanzi16h(255,110,7,0);
  46.   showhanzi16h(275,110,8,0);               
  47.   showhanzi16h(180,110,9,0);
  48.   showhanzi16h(200,110,10,0);               
  49.   showhanzi16h(102,110,11,0);
  50.   showhanzi16h(122,110,12,0);               
  51.   showhanzi16h(27,110,13,0);
  52.   showhanzi16h(47,110,14,0);
  53.   showhanzi16h(255,210,15,0);
  54.   showhanzi16h(275,210,16,0);               
  55.   showhanzi16h(180,210,17,0);
  56.   showhanzi16h(200,210,18,0);               
  57.   showhanzi16h(102,210,19,0);
  58.   showhanzi16h(122,210,17,0);               
  59.   showhanzi16h(27,210,20,0);
  60.   showhanzi16h(47,210,19,0);
  61.   KEY_Config();
  62.   MX_USART1_UART_Init();
  63.   HAL_UART_Transmit(&huart1, (uint8_t *)CJMD3, 23, 0xFFFF);        
  64.   while (1)
  65.   {        
  66.                  if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_10)==GPIO_PIN_RESET)
  67.                 {
  68.                         showhanzi16h(255,210,15,1);
  69.                         showhanzi16h(275,210,16,1);
  70.                        HAL_UART_Transmit(&huart1, (uint8_t *)&CJMD_1, 16, 0xFFFF);
  71.                 }
  72.                 else
  73.                 {
  74.                         showhanzi16h(255,210,15,0);
  75.                         showhanzi16h(275,210,16,0);
  76.                 }
  77.                                                                
  78.                 if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_11)==GPIO_PIN_RESET)
  79.                 {
  80.                         showhanzi16h(180,210,17,1);
  81.                         showhanzi16h(200,210,18,1);
  82.                         HAL_UART_Transmit(&huart1, (uint8_t *)&CJMD_2, 16, 0xFFFF);
  83.                 }
  84.                 else
  85.                 {
  86.                         showhanzi16h(180,210,17,0);
  87.                         showhanzi16h(200,210,18,0);
  88.                 }
  89.                                 
  90.                 if(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_12)==GPIO_PIN_RESET)
  91.                 {
  92.                         showhanzi16h(102,210,19,1);
  93.                         showhanzi16h(122,210,17,1);
  94.                         HAL_UART_Transmit(&huart1, (uint8_t *)&CJMD_3, 16, 0xFFFF);
  95.                 }
  96.                 else
  97.                 {
  98.                         showhanzi16h(102,210,19,0);
  99.                         showhanzi16h(122,210,17,0);
  100.                 }
  101.                 if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_2)==GPIO_PIN_RESET)
  102.                 {
  103.                               showhanzi16h(27,210,20,1);
  104.                         showhanzi16h(47,210,19,1);
  105.                         HAL_UART_Transmit(&huart1, (uint8_t *)&CJMD_4, 16, 0xFFFF);
  106.                 }
  107.                 else
  108.                 {
  109.                         showhanzi16h(27,210,20,0);
  110.                         showhanzi16h(47,210,19,0);
  111.                 }
  112.                 uhADCxConvertedData = HAL_ADC_GetValue(&hadc1);
  113.                uhADCxConvertedData_Voltage_mVolt = __LL_ADC_CALC_DATA_TO_VOLTAGE(VDDA_APPLI, uhADCxConvertedData, LL_ADC_RESOLUTION_12B);
  114.                 if(uhADCxConvertedData_Voltage_mVolt > xz)
  115.                 {                                 
  116.                          HAL_UART_Transmit(&huart1, (uint8_t *)&CJMD_5, 23, 0xFFFF);
  117.                 }
  118.                 HAL_Delay(LED_BLINK_SLOW);                                
  119.    }
  120. }
经程序的编译及下载,使用按键操作的效果如图12所示,即在按下按键时所的功能会呈反白显示效果。

12 操作测试

由于时间的原因,目前暂未完成以无线通讯的方式来发送提示指令。若完成该功能,则可摆脱线路连接的制约,从而达到佩戴式的应用。



您需要登录后才可以回帖 登录 | 注册

本版积分规则

525

主题

2957

帖子

39

粉丝
快速回复 在线客服 返回列表 返回顶部