[STM32H5] 【STM32 Nucleo-64测评】+I2C接口外接设备测试

[复制链接]
1887|6
 楼主| wuxiubo 发表于 2024-8-9 18:43 | 显示全部楼层 |阅读模式
ST目前来说硬件I2C使用来说没啥问题,所以我们外接传感器可以直接测试他功能。
436189708a462623fc6dbae9e1dc2096
注意接线,使用双排针接口时注意错开一个针连接。
测试函数我们还是用上次测试极海单片机的代码。
  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. }

8b0276754864adb60fa87732415f8b55
正好加入我们昨天做的串口打印测试函数,这样直接通过串口就能打印信息了。
e01ab2993bb72c8d1d215db4d7d2af5c
fa3c6e505e4ac647ce513d2a365d9e78

呐咯密密 发表于 2024-8-13 18:14 来自手机 | 显示全部楼层
实现的挺好的,硬件IIC还是很好用的
9dome猫 发表于 2024-12-31 19:26 | 显示全部楼层
注释的部分可以再做一些完善,尤其是对于 CRC 校验部分的说明。
地瓜patch 发表于 2024-12-31 20:24 来自手机 | 显示全部楼层
硬件iic有时不能读写某些硬件
OKAKAKO 发表于 2024-12-31 21:34 | 显示全部楼层
I2C硬件通讯比较稳定
LOVEEVER 发表于 2024-12-31 23:15 | 显示全部楼层
I2C接口外接设备速率多少?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

67

主题

259

帖子

2

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