#include <stdio.h>

#include "esp_log.h"

#include "driver/i2c.h"

#include "sdkconfig.h"

static const char *TAG = "i2c-example";

#define _I2C_NUMBER(num) I2C_NUM_##num

#define I2C_NUMBER(num) _I2C_NUMBER(num)


 

#define I2C_MASTER_SCL_IO 22               /*!< gpio number for I2C master clock */

#define I2C_MASTER_SDA_IO 21               /*!< gpio number for I2C master data  */

#define I2C_MASTER_NUM I2C_NUMBER(CONFIG_I2C_MASTER_PORT_NUM) /*!< I2C port number for master dev */

#define I2C_MASTER_FREQ_HZ CONFIG_I2C_MASTER_FREQUENCY        //IIC主机时钟频率

#define I2C_MASTER_TX_BUF_DISABLE 0                           /*!< I2C master doesn't need buffer */

#define I2C_MASTER_RX_BUF_DISABLE 0                           /*!< I2C master doesn't need buffer */

#define BH1750_SENSOR_ADDR CONFIG_BH1750_ADDR   /*!< slave address for BH1750 sensor */

#define BH1750_CMD_START CONFIG_BH1750_OPMODE   /*!< Operation mode */

#define ESP_SLAVE_ADDR CONFIG_I2C_SLAVE_ADDRESS /*!< ESP32 slave address, you can set any 7bit value */

#define WRITE_BIT I2C_MASTER_WRITE              /*!< I2C master write */

#define READ_BIT I2C_MASTER_READ                /*!< I2C master read */

#define ACK_CHECK_EN 0x1                        /*!< I2C master will check ack from slave*/

#define ACK_CHECK_DIS 0x0                       /*!< I2C master will not check ack from slave */

#define ACK_VAL 0x0                             /*!< I2C ack value */

#define NACK_VAL 0x1                            /*!< I2C nack value */

SemaphoreHandle_t print_mux = NULL;


 

//读取光照强度

static esp_err_t i2c_master_sensor_test(i2c_port_t i2c_num, uint8_t *data_h, uint8_t *data_l)

{

    int ret;

    i2c_cmd_handle_t cmd = i2c_cmd_link_create();

    i2c_master_start(cmd);

    i2c_master_write_byte(cmd, BH1750_SENSOR_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);

    i2c_master_write_byte(cmd, BH1750_CMD_START, ACK_CHECK_EN);

    i2c_master_stop(cmd);

    ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);

    i2c_cmd_link_delete(cmd);

    if (ret != ESP_OK) {

        return ret;

    }

    vTaskDelay(30 / portTICK_RATE_MS);

    cmd = i2c_cmd_link_create();

    i2c_master_start(cmd);

    i2c_master_write_byte(cmd, BH1750_SENSOR_ADDR << 1 | READ_BIT, ACK_CHECK_EN);

    i2c_master_read_byte(cmd, data_h, ACK_VAL);

    i2c_master_read_byte(cmd, data_l, NACK_VAL);

    i2c_master_stop(cmd);

    ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);

    i2c_cmd_link_delete(cmd);

    return ret;

}

//LM75A获取温度值

static uint16_t LM75A_ReadTemper(void)

{

    uint8_t TempH,TempL;

    uint16_t data;

    //创建并初始化IIC命令链接

    i2c_cmd_handle_t cmd = i2c_cmd_link_create();

    i2c_master_start(cmd);//起始信号

    i2c_master_write_byte(cmd, 0x90, ACK_CHECK_EN);//发送设备地址+写

    i2c_master_write_byte(cmd, 0x00, ACK_CHECK_EN);//发送寄存器地址

    i2c_master_stop(cmd); //停止信号

    //IIC主设备发送排队的命令

    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);

    //释放命令链接

    i2c_cmd_link_delete(cmd);

    vTaskDelay(30 / portTICK_RATE_MS);

    cmd = i2c_cmd_link_create();

    i2c_master_start(cmd);

    i2c_master_write_byte(cmd, 0x91, ACK_CHECK_EN);//发送设备地址+读

    i2c_master_read_byte(cmd, &TempH, ACK_VAL);  

    i2c_master_read_byte(cmd, &TempL, NACK_VAL);

    i2c_master_stop(cmd);

    i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);

    i2c_cmd_link_delete(cmd);

    data=((uint16_t)TempH<<8)|TempL;

    data=(data>>5);

    return data;

}


 

//IIC主机初始化

static esp_err_t i2c_master_init(void)

{

    int i2c_master_port = I2C_MASTER_NUM;

    i2c_config_t conf = {

        .mode = I2C_MODE_MASTER,//主机模式

        .sda_io_num = I2C_MASTER_SDA_IO,    //SDA引脚

        .sda_pullup_en = GPIO_PULLUP_ENABLE,//上拉

        .scl_io_num = I2C_MASTER_SCL_IO,    //SCL引脚

        .scl_pullup_en = GPIO_PULLUP_ENABLE,//上拉

        .master.clk_speed = I2C_MASTER_FREQ_HZ,//时钟频率

        // .clk_flags = 0,        

    };

    esp_err_t err = i2c_param_config(i2c_master_port, &conf);

    if (err != ESP_OK) {

        return err;

    }

    return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);

}





 

static void i2c_test_task(void *arg)

{

    int ret;

    uint16_t temper;

    uint8_t sensor_data_h, sensor_data_l;

    while (1)

    {

   

        ret=i2c_master_sensor_test(I2C_MASTER_NUM, &sensor_data_h, &sensor_data_l);

        temper=LM75A_ReadTemper();

        xSemaphoreTake(print_mux, portMAX_DELAY);

        if (ret == ESP_ERR_TIMEOUT)

        {

            ESP_LOGE(TAG, "I2C Timeout");

        }

        else if (ret == ESP_OK)

        {

            printf("光照强度: %.02f [Lux]\n", (sensor_data_h << 8 | sensor_data_l) / 1.2);

        }

        printf("温度:%.2f℃\n",temper*0.125);

        xSemaphoreGive(print_mux);

        vTaskDelay(1000/ portTICK_RATE_MS);

    }

    vSemaphoreDelete(print_mux);

    vTaskDelete(NULL);

}

void app_main(void)

{

    print_mux = xSemaphoreCreateMutex();

    ESP_ERROR_CHECK(i2c_master_init());

    xTaskCreate(i2c_test_task, "i2c_test_task", 1024 * 2, NULL, 10, NULL);

}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐