[APM32F4] 【APM32F411V开发板测评】+SHT31温湿度传感器测试

[复制链接]
 楼主| wuxiubo 发表于 2024-5-22 17:02 | 显示全部楼层 |阅读模式
SHT31温湿度传感器
6a396be49ef4312e56545170a23cdd4e
在SHT20的基础上提升了精度,缩小了体积。同时通信命令增加了一位。
在群里知道了这款板子是和ST芯片兼容的,ST的代码可以烧录进去,所以我也尝试用ST的HAL库进行这次的IIC实验。
594b3c98a153d1708f3acd254a56a694
在cubemx中进行配置,芯片选择一样,然后选择硬件IIC1。就配置这一点。
  1. #define    SHT30_ADDR_WRITE    0x44<<1         //10001000,根据用户手册的指示,这个就是SHT30的写入地址
  2. #define    SHT30_ADDR_READ        (0x44<<1)+1        //10001011,根据用户手册的指示,这个就是SHT30的读取地址
  3. extern I2C_HandleTypeDef hi2c1;//开启I2C1的接口,你用的哪个就改哪个

  4. typedef enum                                //命令的定义
  5. {
  6.     /* 软件复位命令 */

  7.     SOFT_RESET_CMD = 0x30A2,
  8.     /*
  9.     单次测量模式
  10.     命名格式:Repeatability_CS_CMD
  11.     CS: Clock stretching
  12.     */
  13.     HIGH_ENABLED_CMD    = 0x2C06,
  14.     MEDIUM_ENABLED_CMD  = 0x2C0D,
  15.     LOW_ENABLED_CMD     = 0x2C10,
  16.     HIGH_DISABLED_CMD   = 0x2400,
  17.     MEDIUM_DISABLED_CMD = 0x240B,
  18.     LOW_DISABLED_CMD    = 0x2416,

  19.     /*
  20.     周期测量模式
  21.     命名格式:Repeatability_MPS_CMD
  22.     MPS:measurement per second
  23.     */
  24.     HIGH_0_5_CMD   = 0x2032,
  25.     MEDIUM_0_5_CMD = 0x2024,
  26.     LOW_0_5_CMD    = 0x202F,
  27.     HIGH_1_CMD     = 0x2130,
  28.     MEDIUM_1_CMD   = 0x2126,
  29.     LOW_1_CMD      = 0x212D,
  30.     HIGH_2_CMD     = 0x2236,
  31.     MEDIUM_2_CMD   = 0x2220,
  32.     LOW_2_CMD      = 0x222B,
  33.     HIGH_4_CMD     = 0x2334,
  34.     MEDIUM_4_CMD   = 0x2322,
  35.     LOW_4_CMD      = 0x2329,
  36.     HIGH_10_CMD    = 0x2737,
  37.     MEDIUM_10_CMD  = 0x2721,
  38.     LOW_10_CMD     = 0x272A,
  39.     /* 周期测量模式读取数据命令 */
  40.     READOUT_FOR_PERIODIC_MODE = 0xE000,
  41. } SHT30_CMD;

  42. /**
  43. * [url=home.php?mod=space&uid=247401]@brief[/url]    向SHT30发送一条指令(16bit)
  44. * @param    cmd —— SHT30指令(在SHT30_MODE中枚举定义)
  45. * @retval    成功返回HAL_OK
  46. */
  47. static uint8_t    SHT30_Send_Cmd(SHT30_CMD cmd)
  48. {
  49.     uint8_t cmd_buffer[2];
  50.     cmd_buffer[0] = cmd >> 8;
  51.     cmd_buffer[1] = cmd;
  52.     return HAL_I2C_Master_Transmit(&hi2c1, SHT30_ADDR_WRITE, (uint8_t*)cmd_buffer, 2, 0xFFFF);
  53. }

  54. /**
  55. * @brief    复位SHT30
  56. * @param    none
  57. * @retval    none
  58. */
  59. void SHT30_Reset(void)                       
  60. {
  61.     SHT30_Send_Cmd(SOFT_RESET_CMD);
  62.     HAL_Delay(20);
  63. }

  64. /**
  65. * @brief    初始化SHT30
  66. * @param    none
  67. * @retval    成功返回HAL_OK
  68. * [url=home.php?mod=space&uid=536309]@NOTE[/url]    周期测量模式
  69. */
  70. uint8_t SHT30_Init(void)
  71. {
  72.     return SHT30_Send_Cmd(MEDIUM_2_CMD);
  73. }

  74. /**
  75. * @brief    从SHT30读取一次数据
  76. * @param    dat —— 存储读取数据的地址(6个字节数组)
  77. * @retval    成功 —— 返回HAL_OK
  78. */
  79. uint8_t SHT30_Read_Dat(uint8_t* dat)
  80. {
  81.     SHT30_Send_Cmd(READOUT_FOR_PERIODIC_MODE);
  82.     return HAL_I2C_Master_Receive(&hi2c1, SHT30_ADDR_READ, dat, 6, 0xFFFF);
  83. }
  84. /*************************************************
  85. * 本驱动最大的难点,CRC验证;没看懂,懂行的来讲讲
  86. * 不管了会用就行
  87. */

  88. #define CRC8_POLYNOMIAL 0x31

  89. uint8_t CheckCrc8(uint8_t* const message, uint8_t initial_value)
  90. {
  91.     uint8_t  remainder;        //余数
  92.     uint8_t  i = 0, j = 0;  //循环变量

  93.     /* 初始化 */
  94.     remainder = initial_value;

  95.     for(j = 0; j < 2;j++)
  96.     {
  97.         remainder ^= message[j];

  98.         /* 从最高位开始依次计算  */
  99.         for (i = 0; i < 8; i++)
  100.         {
  101.             if (remainder & 0x80)
  102.             {
  103.                 remainder = (remainder << 1)^CRC8_POLYNOMIAL;
  104.             }
  105.             else
  106.             {
  107.                 remainder = (remainder << 1);
  108.             }
  109.         }
  110.     }

  111.     /* 返回计算的CRC码 */
  112.     return remainder;
  113. }
  114. /**
  115. * @brief    将SHT30接收的6个字节数据进行CRC校验,并转换为温度值和湿度值
  116. * @param    dat  —— 存储接收数据的地址(6个字节数组)
  117. * @retval    校验成功  —— 返回0
  118. *             校验失败  —— 返回1,并设置温度值和湿度值为0
  119. */
  120. uint8_t SHT30_Dat_To_Float(uint8_t* const dat, float *temperature,float *humidity)
  121. {
  122.     uint16_t recv_temperature = 0;
  123.     uint16_t recv_humidity = 0;

  124.     /* 校验温度数据和湿度数据是否接收正确 */
  125.     if(CheckCrc8(dat, 0xFF) != dat[2] || CheckCrc8(&dat[3], 0xFF) != dat[5])
  126.         return 1;

  127.     /* 转换温度数据 */
  128.     recv_temperature = ((uint16_t)dat[0]<<8)|dat[1];
  129.     *temperature = -45 + 175*((float)recv_temperature/65535);

  130.     /* 转换湿度数据 */
  131.     recv_humidity = ((uint16_t)dat[3]<<8)|dat[4];
  132.     *humidity = 100 * ((float)recv_humidity / 65535);

  133.     return 0;
  134. }

然后用HAL的硬件IIC发送函数,比较简单一条函数就搞定了。
  1. void SHT30_Reset(void);

  2. uint8_t SHT30_Init(void);

  3. uint8_t SHT30_Read_Dat(uint8_t* dat);

  4. uint8_t CheckCrc8(uint8_t* const message, uint8_t initial_value);

  5. uint8_t SHT30_Dat_To_Float(uint8_t* const dat, float* temperature, float* humidity);

  6. uint8_t dat[6]={0};

  7. float temperature ,humidity;

  8. /* USER CODE END 0 */

  9. /**

  10. * @brief The application entry point.

  11. * @retval int

  12. */

  13. int main(void)

  14. {

  15. /* USER CODE BEGIN 1 */

  16. /* USER CODE END 1 */

  17. /* MCU Configuration--------------------------------------------------------*/

  18. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */

  19. HAL_Init();

  20. /* USER CODE BEGIN Init */

  21. /* USER CODE END Init */

  22. /* Configure the system clock */

  23. SystemClock_Config();

  24. /* USER CODE BEGIN SysInit */

  25. /* USER CODE END SysInit */

  26. /* Initialize all configured peripherals */

  27. MX_GPIO_Init();

  28. MX_I2C1_Init();

  29. /* USER CODE BEGIN 2 */

  30. SHT30_Reset();

  31. SHT30_Init();

  32. /* USER CODE END 2 */

  33. /* Infinite loop */

  34. /* USER CODE BEGIN WHILE */

  35. while (1)

  36. {

  37. /* USER CODE END WHILE */

  38. /* USER CODE BEGIN 3 */

  39. SHT30_Read_Dat(dat);

  40. SHT30_Dat_To_Float(dat,&temperature,&humidity);

  41. }

  42. /* USER CODE END 3 */

  43. }

Main函数,这里先借鉴别人的代码,搞的复杂了。然后就是修改芯片,换成极海的。
b67f4455a10fd85699b871de8e1c1b76
然后烧录仿真,看结果。
bfae2d3e387afad2cedcda03b1856c05
是可以读到正确温度数值的。

szt1993 发表于 2024-5-23 16:35 | 显示全部楼层
用ST的代码可以直接在极海上进行适用?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

67

主题

259

帖子

2

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