[AIROC™ 蓝牙]

【英飞凌CYW20829测评】4、进阶任务之温湿度计

[复制链接]
220|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的结构,并对其进行赋值。
    mI2C_cfg.is_slave = false;
    mI2C_cfg.address = 0;
    mI2C_cfg.frequencyhal_hz = I2C_FREQ;

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

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

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

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

        return true;
}
bool sht3x_read_temperature_and_humidity(sht3x_handle_t *handle, float *temperature, float *humidity)
{
        sht3x_send_command(handle, SHT3X_COMMAND_MEASURE_HIGHREP_STRETCH);

        cyhal_system_delay_ms(1);

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

        uint8_t temperature_crc = calculate_crc(buffer, 2);
        uint8_t humidity_crc = calculate_crc(buffer + 3, 2);
        if (temperature_crc != buffer[2] || humidity_crc != buffer[5]) {
                return false;
        }

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

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

        return true;
}
英飞凌的i2c硬件读写,与stm32的hal库一样,也给了一次性写多个数据的函数封装,使用起来,非常之方便。
整体的代码结构如下:
15436680fef6b6882.png
【主函数代码】
主函数中,主要是初始化ssd1306与sht3x,然后在大循环中读取与显示数据,其代码如下:
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
#include "ssd1306.h"
#include "sht3x.h"
/*******************************************************************************
* Macros
*******************************************************************************/
/* Delay of 1000ms between commands */
#define CMD_TO_CMD_DELAY        (1000UL)

/* Packet positions */
#define PACKET_SOP_POS          (0UL)
#define PACKET_CMD_POS          (1UL)
#define PACKET_EOP_POS          (2UL)

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

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

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

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

/* Packet size */
#define PACKET_SIZE             (3UL)

#ifdef XMC7200D_E272K8384
#define KIT_XMC72
#endif

/*******************************************************************************
* Global Variables
*******************************************************************************/
cyhal_i2c_t mI2C;

/*******************************************************************************
* Function Prototypes
*******************************************************************************/


/*******************************************************************************
* Function Definitions
*******************************************************************************/

/*******************************************************************************
* Function Name: handle_error
********************************************************************************
* Summary:
* User defined error handling function
*
* Parameters:
*  uint32_t status - status indicates success or failure
*
* Return:
*  void
*
*******************************************************************************/
void handle_error(uint32_t status)
{
    if (status != CY_RSLT_SUCCESS)
    {
        CY_ASSERT(0);
    }
}


/*******************************************************************************
* Function Name: main
********************************************************************************
* Summary:
* This is the main function.
*   1. I2C Master sends command packet to the slave
*   2. I2C Master reads the response packet to generate the next command
*
* Parameters:
*  void
*
* Return:
*  int
*
*******************************************************************************/
int main(void)
{
    cy_rslt_t result;

    cyhal_i2c_cfg_t mI2C_cfg;
    uint8_t cmd = CYBSP_LED_STATE_ON;
    uint8_t show_buff[64];

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

#if defined(KIT_XMC72)
    /*Configure clock settings for KIT_XMC72_EVK */
    cyhal_clock_t clock_fll, clock_hf, clock_peri;
    result = cyhal_clock_reserve(&clock_hf, &CYHAL_CLOCK_HF[0]);
    result = cyhal_clock_reserve(&clock_fll, &CYHAL_CLOCK_FLL);
    if(result == CY_RSLT_SUCCESS){
    result = cyhal_clock_set_source(&clock_hf, &clock_fll);
    }
    /* Set divider to 1 for Peripheral Clock */
    result = cyhal_clock_reserve(&clock_peri, CYHAL_CLOCK_PERI);
    if(result == CY_RSLT_SUCCESS){
    result = cyhal_clock_set_divider(&clock_peri,1);
    }
#endif

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

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

    printf("****************** "
           "HAL: I2C Master "
           "****************** \r\n\n");

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

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

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

    printf("Done\r\n\n");
    if (ssd1306_Init(&mI2C) != 0) {
            printf("erro\r\n\n");
            handle_error(1);
    }

    cyhal_system_delay_ms(CMD_TO_CMD_DELAY);
    ssd1306_Fill(Black);
    ssd1306_UpdateScreen(&mI2C);



    // Write data to local screenbuffer
    ssd1306_SetCursor(0, 0);
    ssd1306_WriteString("ssd1306", Font_11x18, White);
    cyhal_system_delay_ms(CMD_TO_CMD_DELAY);
    ssd1306_SetCursor(0, 36);
    ssd1306_WriteString("4ilo", Font_11x18, White);
    ssd1306_UpdateScreen(&mI2C);


    // Create the handle for the sensor.
    sht3x_handle_t handle = {
        .i2c_handle = &mI2C,
        .device_address = SHT3X_I2C_DEVICE_ADDRESS_ADDR_PIN_LOW
    };

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

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

    /* Enable interrupts */
    __enable_irq();

    for (;;)
    {
            ssd1306_Fill(Black);
            ssd1306_SetCursor(0, 0);
            ssd1306_WriteString("CYW92 sht3x", Font_11x18, White);
            sht3x_read_temperature_and_humidity(&handle, &temperature, &humidity);
            ssd1306_SetCursor(0, 24);
            ssd1306_WriteString("Temp:", Font_11x18, White);
            ssd1306_SetCursor(0, 42);
            ssd1306_WriteString("HUM:", Font_11x18, White);
            ssd1306_SetCursor(52, 24);
            sprintf(show_buff,"%.2fC",temperature);
            ssd1306_WriteString(show_buff, Font_11x18, White);
            sprintf(show_buff,"%.2f%",humidity);
            ssd1306_SetCursor(52, 42);
            ssd1306_WriteString(show_buff, Font_11x18, White);
            ssd1306_UpdateScreen(&mI2C);
            cyhal_system_delay_ms(500);
            printf("Initial temperature: %.2fC, humidity: %.2f%%RH\n\r", temperature, humidity);

    }
}
【实验效果】
6684066810018f19ea.gif

使用特权

评论回复
和下土| | 2024-6-30 16:45 | 显示全部楼层
初始化了i2c总线,SDA为P4.0,SCL为P4.1

使用特权

评论回复
结合国际经验| | 2024-6-30 18:40 | 显示全部楼层
确保初始化和配置I2C总线,以便与OLED显示屏和SHT31温湿度传感器进行通信

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

144

主题

693

帖子

8

粉丝