文章
博客 网店

 ESP8266 IDF开发4-i2c总线读写AT24C256


硬件准备


原理图


SCL,SDA默认引脚画反了,但是ESP8266的i2c引脚是可以任意的GPIO口。

实物图


代码





#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "driver/gpio.h"
#include "driver/uart.h"
#include "driver/i2c.h"

 
#define GPIO_LED_PIN    16
#define GPIO_RLY_PIN    12
#define GPIO_DIR_PIN    5
#define GPIO_OUTPUT_PIN_SEL  ((1ULL << GPIO_LED_PIN) | (1ULL << GPIO_RLY_PIN)|(1ULL << GPIO_DIR_PIN))

//i2c
#define I2C_MASTER_SCL_IO           14                /*!< gpio number for I2C master clock */
#define I2C_MASTER_SDA_IO           2                 /*!< gpio number for I2C master data  */
#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 */
#define LAST_NACK_VAL                       0x2              /*!< I2C last_nack value */

#define BUF_SIZE (1024)

void LED_TOGGLE(void)
{
  static uint8_t sta=0;
  sta=sta?0:1;
  gpio_set_level(GPIO_LED_PIN,sta);  
}

void At24cxxInit(void)
{
    int i2c_master_port = I2C_NUM_0;
    i2c_config_t conf;
    conf.mode = I2C_MODE_MASTER;
    conf.sda_io_num = I2C_MASTER_SDA_IO;
    conf.sda_pullup_en = 0;
    conf.scl_io_num = I2C_MASTER_SCL_IO;
    conf.scl_pullup_en = 0;
    conf.clk_stretch_tick = 300; // 300 ticks, Clock stretch is about 210us, you can make changes according to the actual situation.
    ESP_ERROR_CHECK(i2c_driver_install(i2c_master_port, conf.mode));
    ESP_ERROR_CHECK(i2c_param_config(i2c_master_port, &conf));  
}

//AT24CXX通用随机写一字节函数
void At24cxxWriteByte(uint16_t addr,uint8_t dat)
{
  i2c_cmd_handle_t cmd = i2c_cmd_link_create();
  i2c_master_start(cmd);
  i2c_master_write_byte(cmd, 0xA0, ACK_CHECK_EN);//器件地址+写位
  i2c_master_write_byte(cmd, (uint8_t)(addr>>8), ACK_CHECK_EN);//存储地址高字节
  i2c_master_write_byte(cmd,(uint8_t)addr,ACK_CHECK_EN);//存储地址低字节
  i2c_master_write_byte(cmd,dat,ACK_CHECK_EN);
  i2c_master_stop(cmd);
  i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
  i2c_cmd_link_delete(cmd);
}

//AT24CXX通用随机读一字节函数
int At24cxxRead(uint16_t addr,uint8_t *data,uint8_t len)
{
  int ret;
  i2c_cmd_handle_t cmd = i2c_cmd_link_create();//创建命令队列
  //填充命令……
  i2c_master_start(cmd);
  i2c_master_write_byte(cmd, 0xa0, ACK_CHECK_EN);
  i2c_master_write_byte(cmd, (uint8_t)(addr>>8), ACK_CHECK_EN);
  i2c_master_write_byte(cmd, (uint8_t)addr, ACK_CHECK_EN);    
  //i2c_master_stop(cmd);
  ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);//发送命令队列
  i2c_cmd_link_delete(cmd);

  if (ret != ESP_OK) {
      return ret;
  }

  cmd = i2c_cmd_link_create();
  i2c_master_start(cmd);
  i2c_master_write_byte(cmd, 0xa1, ACK_CHECK_EN);
  i2c_master_read(cmd, data, len, LAST_NACK_VAL);
  i2c_master_stop(cmd);
  ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS);
  i2c_cmd_link_delete(cmd);

  return ret;  
}

static void echo_task()
{
    gpio_config_t io_conf;
    io_conf.intr_type = GPIO_INTR_DISABLE;
    io_conf.mode = GPIO_MODE_OUTPUT;
    io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
    io_conf.pull_down_en = 0;
    io_conf.pull_up_en = 0;
    gpio_config(&io_conf);
    
    gpio_set_level(GPIO_LED_PIN, 0);//
     gpio_set_level(GPIO_RLY_PIN,0);
     gpio_set_level(GPIO_DIR_PIN,0);
    
    // Configure parameters of an UART driver,
    // communication pins and install the driver
    uart_config_t uart_config = {
        .baud_rate = 9600,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    uart_param_config(UART_NUM_0, &uart_config);
    uart_driver_install(UART_NUM_0, BUF_SIZE * 2, 0, 0, NULL, 0);

    // Configure a temporary buffer for the incoming data
    uint8_t *data = (uint8_t *) malloc(BUF_SIZE);
    
    //测试代码
    At24cxxInit();
    At24cxxWriteByte(0x0010,0x33);//写入一个字节
    
    while (1) {
       
        LED_TOGGLE();
        vTaskDelay(1000 / portTICK_RATE_MS);
        At24cxxRead(0x0010,data,1);//读取上面写入的一字节数据
        
        gpio_set_level(GPIO_DIR_PIN,1);
        uart_write_bytes(UART_NUM_0, (const char *) data, 1);
        uart_wait_tx_done(UART_NUM_0, portMAX_DELAY);
        gpio_set_level(GPIO_DIR_PIN,0);        
       
    }
}

void app_main()
{
    xTaskCreate(echo_task, "uart_echo_task", 1024, NULL, 10, NULL);
}


程序功能就是向0x0010地址处写入一个字节0x33,然后循环读取并从UART发出来。

编译





下载





运行测试






芯艺工作室    蒙ICP备06005492号
Copyright© 2004-2023 ChipArt Studio All Rights Reserved