[AIROC™ 蓝牙] 【英飞凌CYW20829测评】4、进阶任务之温湿度计

[复制链接]
1015|2
 楼主| lulugl 发表于 2024-6-30 14:50 | 显示全部楼层 |阅读模式
本帖最后由 lulugl 于 2024-7-1 13:09 编辑

【任务目标】
驱动i2c总线,实现数据的发送与读取,本实验驱动i2c的OLED屏,读取sht31的温湿度,并实现显示。
【实验器材】
1、英飞凌CYW20829评估版。
2、OLED显示屏
3、sht31温湿度计。
【实验步骤】
1、新建一个基本i2c的基本示例。在示例中,初始化了i2c总线,SDA为P4.0,SCL为P4.1。在示例中先声明了i2c的结构,并对其进行赋值。
  1.     mI2C_cfg.is_slave = false;
  2.     mI2C_cfg.address = 0;
  3.     mI2C_cfg.frequencyhal_hz = I2C_FREQ;

  4.     /* Init I2C master */
  5.     result = cyhal_i2c_init(&mI2C, CYBSP_I2C_SDA, CYBSP_I2C_SCL, NULL);
  6.     /* I2C master init failed. Stop program execution */
  7.     handle_error(result);

  8.     /* Configure I2C Master */
  9.     result = cyhal_i2c_configure(&mI2C, &mI2C_cfg);
  10.     /* I2C master configuration failed. Stop program execution */
  11.     handle_error(result);
2、创建ssd1306的文件夹,并实现对OLED的写命令函数:
  1. static uint8_t ssd1306_WriteCommand(cyhal_i2c_t *hi2c, uint8_t command)
  2. {
  3.    return cyhal_i2c_master_mem_write(hi2c, SSD1306_I2C_ADDR, 0x00, 1, &command, 1, 10);

  4. }
3、其余的代码均为公版的驱动,无需更多的变动。
4、创建sht3x.c/h函数,也实现sht3x的读写驱动,代码如下:
  1. static bool sht3x_send_command(sht3x_handle_t *handle, sht3x_command_t command)
  2. {
  3.         uint8_t command_buffer[2] = {(command & 0xff00u) >> 8u, command & 0xffu};

  4.         if (cyhal_i2c_master_write(handle->i2c_handle, handle->device_address << 1u, command_buffer, sizeof(command_buffer),
  5.                                     SHT3X_I2C_TIMEOUT, true) != CY_RSLT_SUCCESS) {
  6.                 return false;
  7.         }

  8.         return true;
  9. }
  1. bool sht3x_read_temperature_and_humidity(sht3x_handle_t *handle, float *temperature, float *humidity)
  2. {
  3.         sht3x_send_command(handle, SHT3X_COMMAND_MEASURE_HIGHREP_STRETCH);

  4.         cyhal_system_delay_ms(1);

  5.         uint8_t buffer[6];
  6.         if (cyhal_i2c_master_read(handle->i2c_handle, handle->device_address << 1u, buffer, sizeof(buffer), SHT3X_I2C_TIMEOUT, true) != CY_RSLT_SUCCESS) {
  7.                 return false;
  8.         }

  9.         uint8_t temperature_crc = calculate_crc(buffer, 2);
  10.         uint8_t humidity_crc = calculate_crc(buffer + 3, 2);
  11.         if (temperature_crc != buffer[2] || humidity_crc != buffer[5]) {
  12.                 return false;
  13.         }

  14.         uint16_t temperature_raw = uint8_to_uint16(buffer[0], buffer[1]);
  15.         uint16_t humidity_raw = uint8_to_uint16(buffer[3], buffer[4]);

  16.         *temperature = -45.0f + 175.0f * (float)temperature_raw / 65535.0f;
  17.         *humidity = 100.0f * (float)humidity_raw / 65535.0f;

  18.         return true;
  19. }
英飞凌的i2c硬件读写,与stm32的hal库一样,也给了一次性写多个数据的函数封装,使用起来,非常之方便。
整体的代码结构如下:

【主函数代码】
主函数中,主要是初始化ssd1306与sht3x,然后在大循环中读取与显示数据,其代码如下:
  1. #include "cyhal.h"
  2. #include "cybsp.h"
  3. #include "cy_retarget_io.h"
  4. #include "ssd1306.h"
  5. #include "sht3x.h"
  6. /*******************************************************************************
  7. * Macros
  8. *******************************************************************************/
  9. /* Delay of 1000ms between commands */
  10. #define CMD_TO_CMD_DELAY        (1000UL)

  11. /* Packet positions */
  12. #define PACKET_SOP_POS          (0UL)
  13. #define PACKET_CMD_POS          (1UL)
  14. #define PACKET_EOP_POS          (2UL)

  15. /* Start and end of packet markers */
  16. #define PACKET_SOP              (0x01UL)
  17. #define PACKET_EOP              (0x17UL)

  18. /* I2C slave address to communicate with */
  19. #define I2C_SLAVE_ADDR          (0x78UL)

  20. /* I2C bus frequency */
  21. #define I2C_FREQ                (400000UL)

  22. /* Command valid status */
  23. #define STATUS_CMD_DONE         (0x00UL)

  24. /* Packet size */
  25. #define PACKET_SIZE             (3UL)

  26. #ifdef XMC7200D_E272K8384
  27. #define KIT_XMC72
  28. #endif

  29. /*******************************************************************************
  30. * Global Variables
  31. *******************************************************************************/
  32. cyhal_i2c_t mI2C;

  33. /*******************************************************************************
  34. * Function Prototypes
  35. *******************************************************************************/


  36. /*******************************************************************************
  37. * Function Definitions
  38. *******************************************************************************/

  39. /*******************************************************************************
  40. * Function Name: handle_error
  41. ********************************************************************************
  42. * Summary:
  43. * User defined error handling function
  44. *
  45. * Parameters:
  46. *  uint32_t status - status indicates success or failure
  47. *
  48. * Return:
  49. *  void
  50. *
  51. *******************************************************************************/
  52. void handle_error(uint32_t status)
  53. {
  54.     if (status != CY_RSLT_SUCCESS)
  55.     {
  56.         CY_ASSERT(0);
  57.     }
  58. }


  59. /*******************************************************************************
  60. * Function Name: main
  61. ********************************************************************************
  62. * Summary:
  63. * This is the main function.
  64. *   1. I2C Master sends command packet to the slave
  65. *   2. I2C Master reads the response packet to generate the next command
  66. *
  67. * Parameters:
  68. *  void
  69. *
  70. * Return:
  71. *  int
  72. *
  73. *******************************************************************************/
  74. int main(void)
  75. {
  76.     cy_rslt_t result;

  77.     cyhal_i2c_cfg_t mI2C_cfg;
  78.     uint8_t cmd = CYBSP_LED_STATE_ON;
  79.     uint8_t show_buff[64];

  80.     /* Initialize the device and board peripherals */
  81.     result = cybsp_init();
  82.     /* Board init failed. Stop program execution */
  83.     handle_error(result);

  84. #if defined(KIT_XMC72)
  85.     /*Configure clock settings for KIT_XMC72_EVK */
  86.     cyhal_clock_t clock_fll, clock_hf, clock_peri;
  87.     result = cyhal_clock_reserve(&clock_hf, &CYHAL_CLOCK_HF[0]);
  88.     result = cyhal_clock_reserve(&clock_fll, &CYHAL_CLOCK_FLL);
  89.     if(result == CY_RSLT_SUCCESS){
  90.     result = cyhal_clock_set_source(&clock_hf, &clock_fll);
  91.     }
  92.     /* Set divider to 1 for Peripheral Clock */
  93.     result = cyhal_clock_reserve(&clock_peri, CYHAL_CLOCK_PERI);
  94.     if(result == CY_RSLT_SUCCESS){
  95.     result = cyhal_clock_set_divider(&clock_peri,1);
  96.     }
  97. #endif

  98.     /* Initialize the retarget-io */
  99.     result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX,
  100.                                   CY_RETARGET_IO_BAUDRATE);
  101.     /* Retarget-io init failed. Stop program execution */
  102.     handle_error(result);

  103.     /* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */
  104.     printf("\x1b[2J\x1b[;H");

  105.     printf("****************** "
  106.            "HAL: I2C Master "
  107.            "****************** \r\n\n");

  108.     /* I2C Master configuration settings */
  109.     printf(">> Configuring I2C Master..... ");
  110.     mI2C_cfg.is_slave = false;
  111.     mI2C_cfg.address = 0;
  112.     mI2C_cfg.frequencyhal_hz = I2C_FREQ;

  113.     /* Init I2C master */
  114.     result = cyhal_i2c_init(&mI2C, CYBSP_I2C_SDA, CYBSP_I2C_SCL, NULL);
  115.     /* I2C master init failed. Stop program execution */
  116.     handle_error(result);

  117.     /* Configure I2C Master */
  118.     result = cyhal_i2c_configure(&mI2C, &mI2C_cfg);
  119.     /* I2C master configuration failed. Stop program execution */
  120.     handle_error(result);

  121.     printf("Done\r\n\n");
  122.     if (ssd1306_Init(&mI2C) != 0) {
  123.             printf("erro\r\n\n");
  124.             handle_error(1);
  125.     }

  126.     cyhal_system_delay_ms(CMD_TO_CMD_DELAY);
  127.     ssd1306_Fill(Black);
  128.     ssd1306_UpdateScreen(&mI2C);



  129.     // Write data to local screenbuffer
  130.     ssd1306_SetCursor(0, 0);
  131.     ssd1306_WriteString("ssd1306", Font_11x18, White);
  132.     cyhal_system_delay_ms(CMD_TO_CMD_DELAY);
  133.     ssd1306_SetCursor(0, 36);
  134.     ssd1306_WriteString("4ilo", Font_11x18, White);
  135.     ssd1306_UpdateScreen(&mI2C);


  136.     // Create the handle for the sensor.
  137.     sht3x_handle_t handle = {
  138.         .i2c_handle = &mI2C,
  139.         .device_address = SHT3X_I2C_DEVICE_ADDRESS_ADDR_PIN_LOW
  140.     };

  141.     // Initialise sensor (tests connection by reading the status register).
  142.     if (!sht3x_init(&handle)) {
  143.         printf("SHT3x access failed.\n\r");
  144.     }

  145.     // Read temperature and humidity.
  146.     float temperature, humidity;

  147.     /* Enable interrupts */
  148.     __enable_irq();

  149.     for (;;)
  150.     {
  151.             ssd1306_Fill(Black);
  152.             ssd1306_SetCursor(0, 0);
  153.             ssd1306_WriteString("CYW92 sht3x", Font_11x18, White);
  154.             sht3x_read_temperature_and_humidity(&handle, &temperature, &humidity);
  155.             ssd1306_SetCursor(0, 24);
  156.             ssd1306_WriteString("Temp:", Font_11x18, White);
  157.             ssd1306_SetCursor(0, 42);
  158.             ssd1306_WriteString("HUM:", Font_11x18, White);
  159.             ssd1306_SetCursor(52, 24);
  160.             sprintf(show_buff,"%.2fC",temperature);
  161.             ssd1306_WriteString(show_buff, Font_11x18, White);
  162.             sprintf(show_buff,"%.2f%",humidity);
  163.             ssd1306_SetCursor(52, 42);
  164.             ssd1306_WriteString(show_buff, Font_11x18, White);
  165.             ssd1306_UpdateScreen(&mI2C);
  166.             cyhal_system_delay_ms(500);
  167.             printf("Initial temperature: %.2fC, humidity: %.2f%%RH\n\r", temperature, humidity);

  168.     }
  169. }
【实验效果】

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
和下土 发表于 2024-6-30 16:45 | 显示全部楼层
初始化了i2c总线,SDA为P4.0,SCL为P4.1
结合国际经验 发表于 2024-6-30 18:40 | 显示全部楼层
确保初始化和配置I2C总线,以便与OLED显示屏和SHT31温湿度传感器进行通信
您需要登录后才可以回帖 登录 | 注册

本版积分规则

188

主题

843

帖子

12

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