#include <stdio.h> #include "esp_log.h" #include "driver/i2c.h" #include "gw_grayscale_sensor.h" static const char *TAG = "gw gray i2c example"; #define I2C_MASTER_SCL_IO 22 /*!< I2C 时钟针脚号 */ #define I2C_MASTER_SDA_IO 21 /*!< I2C 数据针脚号 */ #define I2C_MASTER_NUM 0 /*!< I2C 通道 */ #define I2C_MASTER_FREQ_HZ 100000 /*!< I2C 主的时钟频率 */ #define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C 不设输出缓冲 */ #define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C 不设输入缓冲 */ #define I2C_MASTER_TIMEOUT_MS 0 uint8_t gw_gray_addr = 0; static esp_err_t gw_gray_write_cmd(uint8_t cmd) { esp_err_t err; err = i2c_master_write_to_device(I2C_MASTER_NUM, gw_gray_addr, &cmd, 1, pdMS_TO_TICKS(I2C_MASTER_TIMEOUT_MS)); return err; } static esp_err_t gw_gray_read_byte(uint8_t *byte_read) { esp_err_t err; err = i2c_master_read_from_device(I2C_MASTER_NUM, gw_gray_addr, byte_read, 1, pdMS_TO_TICKS(I2C_MASTER_TIMEOUT_MS)); return err; } static esp_err_t gw_gray_read(uint8_t *read_arr, size_t read_size) { esp_err_t err; err = i2c_master_read_from_device(I2C_MASTER_NUM, gw_gray_addr, read_arr, read_size, pdMS_TO_TICKS(I2C_MASTER_TIMEOUT_MS)); return err; } static esp_err_t gw_gray_write(const uint8_t *write_arr, size_t write_size) { esp_err_t err; err = i2c_master_write_to_device(I2C_MASTER_NUM, gw_gray_addr, write_arr, write_size, pdMS_TO_TICKS(I2C_MASTER_TIMEOUT_MS)); return err; } 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, .scl_io_num = I2C_MASTER_SCL_IO, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = I2C_MASTER_FREQ_HZ, }; i2c_param_config(i2c_master_port, &conf); return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); } /** * @brief 扫描和打印有回复的 任何i2c设备 */ static void i2c_scan_generic(void); /** * @brief 扫描和打印有回复的 感为灰度传感器设备 * @return 0: 无设备, 其他: 最后一个被扫描到的设备 */ static uint8_t i2c_scan_gw_gray(void); void app_main(void) { uint8_t ping_rsp = 0; uint8_t send_buff[8]; int err; ESP_ERROR_CHECK(i2c_master_init()); ESP_LOGI(TAG, "I2C initialized successfully"); vTaskDelay(pdMS_TO_TICKS(500)); i2c_scan_generic(); gw_gray_addr = i2c_scan_gw_gray(); // 更换地址 if (gw_gray_addr == 0) { ESP_LOGI(TAG, "没找到设备啊"); } else if (gw_gray_addr != 0x18) { // 对指定i2c地址更改地址,以下命令会发送到地址为gw_gray_addr ESP_LOGI(TAG, "对%x更改地址,新地址应为%x", gw_gray_addr, 0x18); send_buff[0] = GW_GRAY_CHANGE_ADDR; // 更新地址命令 send_buff[1] = 0x33; // 新地址, 实际地址为 0x18 = (0x33 & 0b111) >> 1, 详细请看文档8.6.1 err = gw_gray_write(send_buff, 2); // 传感器设备需要把地址写入EEPROM,需要1ms左右 vTaskDelay(pdMS_TO_TICKS(1)); ESP_LOGI(TAG, "软件重启设备"); gw_gray_write_cmd(GW_GRAY_REBOOT); // 再次扫描地址 i2c_scan_generic(); gw_gray_addr = i2c_scan_gw_gray(); } if ((gw_gray_addr & 0xFC) != GW_GRAY_ADDR_DEF){ ESP_LOGI(TAG, "i2c广播重置"); gw_gray_addr = 0; gw_gray_write((const uint8_t *)GW_GRAY_BROADCAST_RESET, 8); ESP_LOGI(TAG, "等待设备重启2..."); vTaskDelay(pdMS_TO_TICKS(10)); // 再次扫描地址 i2c_scan_generic(); gw_gray_addr = i2c_scan_gw_gray(); } while (1) { vTaskDelay(portMAX_DELAY); } } static void i2c_scan_generic(void) { uint8_t device_count = 0; printf("i2c 扫描开始: \n"); for (uint8_t i = 1; i < 127; i++) { int ret; i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (i << 1) | I2C_MASTER_WRITE, 1); i2c_master_stop(cmd); ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, pdMS_TO_TICKS(I2C_MASTER_TIMEOUT_MS)); i2c_cmd_link_delete(cmd); if (ret == ESP_OK) { device_count += 1; printf("找到i2c设备,地址为: 0x%2x\n", i); } vTaskDelay(pdMS_TO_TICKS(10)); } if (device_count == 0) { printf("无i2c设备\n"); } } static uint8_t i2c_scan_gw_gray(void) { printf("感为灰度传感器i2c 扫描开始: \n"); uint8_t i2c_cmd = GW_GRAY_PING; uint8_t ping_rsp; uint8_t gw_gray_device_addr = 0; for (uint8_t i = 1; i < 127; i++) { int ret; ping_rsp = 0; ret = i2c_master_write_read_device(I2C_MASTER_NUM, i, &i2c_cmd, 1, &ping_rsp, 1, pdMS_TO_TICKS(I2C_MASTER_TIMEOUT_MS)); if (ret != ESP_FAIL && ret != ESP_OK) { printf("%d, %s\n", i, esp_err_to_name(ret)); } if (ping_rsp == 0x66) { printf("找到感为传感器设备,地址为: 0x%2x\n", i); gw_gray_device_addr = i; } else if (ping_rsp != 0) { printf("设备: 0x%2x 回复 :%x\n", i, ping_rsp); } vTaskDelay(pdMS_TO_TICKS(2)); } return gw_gray_device_addr; }