[其他ST产品] 【STM32G4评测+使用串口驱动voc温湿度传感器svm40】

[复制链接]
937|0
 楼主| dql2015 发表于 2021-3-24 19:36 | 显示全部楼层 |阅读模式
手头正好有一个VOC传感器&温湿度传感器模块svm40,可以输出空气质量相关的参数:VOC指数、温度、湿度。后面打算用它进行一个综合demo的设计,将传感器数据推送到物联网平台云端。svm40使用串口接口,这里配置stm32g491的串口中断方式接收,使用stm32cubemx工具只需要简单的点几下鼠标,用户体验very nice。


11.PNG

22.PNG

在main.c中添加自己的代码,首先初始化传感器,然后进行数据的读取。
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * [url=home.php?mod=space&uid=288409]@file[/url]           : main.c
  5.   * [url=home.php?mod=space&uid=247401]@brief[/url]          : Main program body
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>© Copyright (c) 2021 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under BSD 3-Clause license,
  13.   * the "License"; You may not use this file except in compliance with the
  14.   * License. You may obtain a copy of the License at:
  15.   *                        opensource.org/licenses/BSD-3-Clause
  16.   *
  17.   ******************************************************************************
  18.   */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22. #include "usart.h"
  23. #include "tim.h"
  24. #include "gpio.h"

  25. /* Private includes ----------------------------------------------------------*/
  26. /* USER CODE BEGIN Includes */
  27. #include "ringBuffer.h"
  28. #include "svm40_port.h"
  29. #include <stdbool.h>
  30. /* USER CODE END Includes */

  31. /* Private typedef -----------------------------------------------------------*/
  32. /* USER CODE BEGIN PTD */

  33. #define MY_DEBUG
  34. #ifdef MY_DEBUG
  35. #define MY_LOG printf
  36. #else
  37. #define MY_LOG
  38. #endif
  39.                         

  40. uint8_t aRxBufferSvm40=0;
  41. uint8_t tx_buff[64]={0};
  42. uint8_t rx_buff[64]={0};
  43. static uint8_t rbBuf[128];
  44. int len;
  45. rb_t rb_svm40;
  46. int idle_mode=0;
  47. int ready=0;
  48. float v_f;
  49. float h_f;
  50. float t_f;

  51. /* USER CODE END PTD */

  52. /* Private define ------------------------------------------------------------*/
  53. /* USER CODE BEGIN PD */
  54. /* USER CODE END PD */

  55. /* Private macro -------------------------------------------------------------*/
  56. /* USER CODE BEGIN PM */

  57. /* USER CODE END PM */

  58. /* Private variables ---------------------------------------------------------*/

  59. /* USER CODE BEGIN PV */

  60. /* USER CODE END PV */

  61. /* Private function prototypes -----------------------------------------------*/
  62. void SystemClock_Config(void);
  63. /* USER CODE BEGIN PFP */

  64. /* USER CODE END PFP */

  65. /* Private user code ---------------------------------------------------------*/
  66. /* USER CODE BEGIN 0 */

  67. void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)  
  68. {  
  69.     if(UartHandle->Instance == USART1)
  70.     {
  71.         if(rbWrite(&rb_svm40, &aRxBufferSvm40, 1) != 1)
  72.         {
  73.             printf("ERR: Failed to rbWrite\n");
  74.         }
  75.         HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBufferSvm40, 1);
  76.     }               
  77. }  

  78. #define sw16(x) \
  79.     ((short)( \
  80.         (((short)(x) & (short)0x00ffU) << 8 ) | \
  81.         (((short)(x) & (short)0xff00U) >> 8 ) ))

  82. void SerialSend(uint8_t* ptr,uint32_t len)
  83. {
  84.     if(HAL_OK!=HAL_UART_Transmit(&huart1, ptr,len, HAL_MAX_DELAY))
  85.     {
  86.         MY_LOG("Serial Send Error!\n");
  87.     }
  88. }

  89. int ProcRecvProtocol(uint8_t* ptr,uint32_t len,uint8_t cmd, uint8_t state)
  90. {
  91.     if (state & 0x80)
  92.     {
  93.         MY_LOG("device error flag\n");
  94.         MY_LOG("execution error code=0x%02x\n", state & 0x7F);
  95.     }
  96.     else
  97.         {
  98.         switch (cmd)
  99.         {
  100.             case _cmd_t_svm40_get_version:
  101.                 {
  102.                 uint8_t firmware_major_version;
  103.                 uint8_t firmware_minor_version;
  104.                 uint8_t firmware_debug_state;
  105.                 uint8_t hardware_major_version;
  106.                 uint8_t hardware_minor_version;
  107.                 uint8_t protocol_major_version;
  108.                 uint8_t protocol_minor_version;

  109.                 int ret3 = f_unpack_svm40_get_version_res_frame(rx_buff, 1024, &firmware_major_version,
  110.                                                                 &firmware_minor_version, &firmware_debug_state,
  111.                                                                 &hardware_major_version, &hardware_minor_version,
  112.                                                                 &protocol_major_version, &protocol_minor_version);
  113.                 printf("firmware version:V%d.%d\n",firmware_major_version,firmware_minor_version);
  114.                                                                 printf("firmware_debug_state:%d\n",firmware_debug_state);
  115.                                                                 printf("hardware version:V%d.%d\n",hardware_major_version,hardware_minor_version);
  116.                                                                 printf("protocol version:V%d.%d\n",protocol_major_version,protocol_minor_version);
  117.             }
  118.             case _cmd_t_svm40_start_measurement:
  119.             {
  120.                 MY_LOG("_cmd_t_svm40_start_measurement\n");
  121.                 ready=1;
  122.             }
  123.                 break;
  124.             case _cmd_t_svm40_device_reset:
  125.             {
  126.                 MY_LOG("_cmd_t_svm40_device_reset\n");
  127.                 idle_mode=1;
  128.             }
  129.                 break;
  130.             case _cmd_t_svm40_get_signals:
  131.             {
  132.                 MY_LOG("_cmd_t_svm40_get_signals\n");
  133.                 uint16_t voc_index=0,humidity=0,temperature=0;
  134.                 int ret=f_unpack_svm40_get_signals_res_frame(rx_buff,64,&voc_index,&humidity,&temperature);
  135.                 if(ret>0)
  136.                 {
  137.                     int16_t v=sw16(voc_index);
  138.                     int16_t h=sw16(humidity);
  139.                     int16_t t=sw16(temperature);
  140.                     v_f=v/10.0;
  141.                     h_f=h/100.0;
  142.                     t_f=t/200.0;
  143.                     printf("voc_index:%0.1f humidity:%0.2f temperature:%0.2f\r\n",v_f,h_f,t_f);
  144.                 }
  145.             }
  146.                 break;
  147.         }
  148.     }

  149. }

  150. int ProcRecvData(uint8_t* ptr,uint32_t len)
  151. {
  152.     for (int i = 0; i < len; ++i) {
  153.         if(ptr[i]==0x7D && ptr[i+1]==0x33)
  154.         {
  155.             MY_LOG("detect Byte-Stuffing!\n");
  156.             ptr[i]=0x13;
  157.             for(int j=i+1;j<len;j++)
  158.             {
  159.                 ptr[j]=ptr[j+1];
  160.             }
  161.             len=len-1;
  162.             break;
  163.         }
  164.         else if(ptr[i]==0x7D && ptr[i+1]==0x31)
  165.         {
  166.             MY_LOG("detect Byte-Stuffing!\n");
  167.             ptr[i]=0x11;
  168.             for(int j=i+1;j<len;j++)
  169.             {
  170.                 ptr[j]=ptr[j+1];
  171.             }
  172.             len=len-1;
  173.             break;
  174.         }
  175.         else if(ptr[i]==0x7D && ptr[i+1]==0x5D)
  176.         {
  177.             MY_LOG("detect Byte-Stuffing!\n");
  178.             ptr[i]=0x7D;
  179.             for(int j=i+1;j<len;j++)
  180.             {
  181.                 ptr[j]=ptr[j+1];
  182.             }
  183.             len=len-1;
  184.             break;
  185.         }
  186.         else if(ptr[i]==0x7D && ptr[i+1]==0x5E)
  187.         {
  188.             MY_LOG("detect Byte-Stuffing!\n");
  189.             ptr[i]=0x7E;
  190.             for(int j=i+1;j<len;j++)
  191.             {
  192.                 ptr[j]=ptr[j+1];
  193.             }
  194.             len=len-1;
  195.             break;
  196.         }
  197.     }

  198.     int cret,ret = -1;
  199.     uint32_t shift;
  200.     uint8_t cmd, state;;
  201.     for(shift = 0;shift < len;++shift)
  202.     {
  203.         cret = f_check(ptr + shift,len - shift,&cmd, &state);
  204.         if(cret > 0)
  205.         {
  206.             ret = cret + shift;
  207.             ProcRecvProtocol(ptr + shift,cret,cmd,state);
  208.         }
  209.     }
  210.     return ret;
  211. }


  212. /* USER CODE END 0 */

  213. /**
  214.   * @brief  The application entry point.
  215.   * @retval int
  216.   */
  217. int main(void)
  218. {
  219.   /* USER CODE BEGIN 1 */

  220.   /* USER CODE END 1 */

  221.   /* MCU Configuration--------------------------------------------------------*/

  222.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  223.   HAL_Init();

  224.   /* USER CODE BEGIN Init */

  225.   /* USER CODE END Init */

  226.   /* Configure the system clock */
  227.   SystemClock_Config();

  228.   /* USER CODE BEGIN SysInit */

  229.   /* USER CODE END SysInit */

  230.   /* Initialize all configured peripherals */
  231.   MX_GPIO_Init();
  232.   MX_LPUART1_UART_Init();
  233.   MX_USART1_UART_Init();
  234.   MX_UART4_Init();
  235.   MX_TIM6_Init();
  236.   /* USER CODE BEGIN 2 */
  237.        
  238.         printf("nucleo-stm32g491 test,by 21ic dql2015!2021-03-24\r\n");
  239.        
  240.         HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBufferSvm40, 1);

  241.         rb_svm40.rbCapacity = 512;
  242.         rb_svm40.rbBuff = rbBuf;
  243.         if(0 == rbCreate(&rb_svm40))
  244.         {
  245.                         MY_LOG("rbCreate Success\n");
  246.         }
  247.         else
  248.         {
  249.                         MY_LOG("rbCreate Faild\n");
  250.         }
  251.        
  252.         HAL_Delay(100);
  253.        
  254.         len = f_pack_svm40_get_version_frame(tx_buff, 64);
  255.         MY_LOG("Serial Send To SVM40 <svm40_get_version> [len:%d]", len);
  256.         if (len > 0)
  257.         {
  258.                 for (int i = 0; i < len; ++i)
  259.                 {
  260.                                 MY_LOG("0x%02X ", tx_buff[i]);
  261.                 }
  262.                 MY_LOG("\n");
  263.                 SerialSend(tx_buff, len);
  264.         }

  265.         len=f_pack_svm40_device_reset_frame(tx_buff,64);
  266.         MY_LOG("Serial Send To SVM40 <cmd:svm40_device_reset> [len:%d]", len);
  267.         if (len > 0)
  268.                 {
  269.                         for (int i = 0; i < len; ++i)
  270.                         {
  271.                                         MY_LOG("0x%02X ", tx_buff[i]);
  272.                         }
  273.                         MY_LOG("\n");
  274.                         SerialSend(tx_buff, len);
  275.         }
  276.                
  277.   /* USER CODE END 2 */

  278.   /* Infinite loop */
  279.   /* USER CODE BEGIN WHILE */
  280.   while (1)
  281.   {
  282.     /* USER CODE END WHILE */

  283.     /* USER CODE BEGIN 3 */
  284.                
  285.                         int ret=rbCanRead(&rb_svm40);
  286.       if(ret>=7)
  287.       {
  288.           if(ret==rbRead(&rb_svm40, (uint8_t*)rx_buff, ret))
  289.           {
  290.               MY_LOG("Serial Receive From SVM40[len:%d]", ret);
  291.               for (int i = 0; i < ret; ++i)
  292.               {
  293.                   MY_LOG("%02X ", rx_buff[i]);
  294.               }
  295.               MY_LOG("\n");
  296.               ProcRecvData(rx_buff,ret);
  297.           }
  298.       }

  299.       if(idle_mode) {
  300.           idle_mode=0;
  301.           len=f_pack_svm40_start_measurement_frame(tx_buff,64);
  302.           MY_LOG("Serial Send To SVM40 <cmd:svm40_start_measurement> [len:%d]", len);
  303.           if (len > 0) {
  304.               for (int i = 0; i < len; ++i) {
  305.                   MY_LOG("0x%02X ", tx_buff[i]);
  306.               }
  307.               MY_LOG("\n");
  308.               SerialSend(tx_buff, len);
  309.           }
  310.       }
  311.       if(ready)
  312.       {
  313.           static uint32_t lastTimer = 0;

  314.           if((HAL_GetTick()-lastTimer ) > 1000)
  315.           {
  316.               len=f_pack_svm40_get_signals_frame(tx_buff,64);
  317.               MY_LOG("Serial Send To SVM40 <cmd:svm40_get_signals> [len:%d]", len);
  318.               if (len > 0) {
  319.                   for (int i = 0; i < len; ++i) {
  320.                       MY_LOG("0x%02X ", tx_buff[i]);
  321.                   }
  322.                   MY_LOG("\n");
  323.                   SerialSend(tx_buff, len);
  324.               }

  325.               lastTimer = HAL_GetTick();
  326.           }
  327.       }
  328.       HAL_Delay(50);
  329.   }
  330.   /* USER CODE END 3 */
  331. }

  332. /**
  333.   * @brief System Clock Configuration
  334.   * @retval None
  335.   */
  336. void SystemClock_Config(void)
  337. {
  338.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  339.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  340.   RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  341.   /** Configure the main internal regulator output voltage
  342.   */
  343.   HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
  344.   /** Initializes the RCC Oscillators according to the specified parameters
  345.   * in the RCC_OscInitTypeDef structure.
  346.   */
  347.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  348.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  349.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  350.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  351.   RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV6;
  352.   RCC_OscInitStruct.PLL.PLLN = 85;
  353.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  354.   RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  355.   RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  356.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  357.   {
  358.     Error_Handler();
  359.   }
  360.   /** Initializes the CPU, AHB and APB buses clocks
  361.   */
  362.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  363.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  364.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  365.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  366.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  367.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  368.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  369.   {
  370.     Error_Handler();
  371.   }
  372.   /** Initializes the peripherals clocks
  373.   */
  374.   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_UART4
  375.                               |RCC_PERIPHCLK_LPUART1;
  376.   PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
  377.   PeriphClkInit.Uart4ClockSelection = RCC_UART4CLKSOURCE_PCLK1;
  378.   PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
  379.   if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  380.   {
  381.     Error_Handler();
  382.   }
  383. }

  384. /* USER CODE BEGIN 4 */

  385. /* USER CODE END 4 */

  386. /**
  387.   * @brief  This function is executed in case of error occurrence.
  388.   * @retval None
  389.   */
  390. void Error_Handler(void)
  391. {
  392.   /* USER CODE BEGIN Error_Handler_Debug */
  393.   /* User can add his own implementation to report the HAL error return state */
  394.   __disable_irq();
  395.   while (1)
  396.   {
  397.   }
  398.   /* USER CODE END Error_Handler_Debug */
  399. }

  400. #ifdef  USE_FULL_ASSERT
  401. /**
  402.   * @brief  Reports the name of the source file and the source line number
  403.   *         where the assert_param error has occurred.
  404.   * @param  file: pointer to the source file name
  405.   * @param  line: assert_param error line source number
  406.   * @retval None
  407.   */
  408. void assert_failed(uint8_t *file, uint32_t line)
  409. {
  410.   /* USER CODE BEGIN 6 */
  411.   /* User can add his own implementation to report the file name and line number,
  412.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  413.   /* USER CODE END 6 */
  414. }
  415. #endif /* USE_FULL_ASSERT */

  416. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


驱动svm40.jpg

驱动传感器.gif
测试工程源码:
nucleo_stm32g491_svm40.rar (7.47 MB, 下载次数: 2)

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

本版积分规则

104

主题

384

帖子

8

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