这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【CH582M】CH582M的I2C外设(5)-----从机模式测试

共1条 1/1 1 跳转至页

【CH582M】CH582M的I2C外设(5)-----从机模式测试

专家
2026-10-12 20:58:23     打赏

一、实验内容

通常我们在使用I2C时,是以单片机作为I2C主设备驱动其他专门的I2C传感器使用。本次实验,把单片机CH582M作为I2C从机使用。在熟悉I2C相关寄存器只是的基础上,参考官方提供的I2C例程,我们按照以下方式设计本实验:

1、将CH582M开发板,通过编程,设计为I2C从机模式,地址为0x20,400KHz、7位地址。

2、使用ESP8266开发板,编程设计为I2C主机模式,400KHz、7位地址。

3、在ESP8266端首先通过I2C扫描方式,确认是否能扫描到CH582M开发板的I2C从机地址。

4、如果能扫描到,持续发送字节数据,在CH582M开发板由串口输出收集到的数据。

在官方例程中,应该使用两块CH582M开发板来测试。但我手里只有一块,所以将主机部分改用ESP8266开发板。

二、代码

1、CH582M开发板

1) app_i2c.h


#ifndef EVT_EXAM_I2C_SRC_APP_I2C_C
#define EVT_EXAM_I2C_SRC_APP_I2C_C
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#define I2C_BUFFER_LENGTH   32
#define I2C_READ      1
#define I2C_WRITE     0
typedef enum {
    I2C_READY,
    I2C_MRX,  
    I2C_MTX,  
    I2C_SRX,  
    I2C_STX,  
}i2c_state_t;
typedef enum {
    I2C_NO_MEM = 1,
    I2C_STATE,
    I2C_MT_NACK,
    I2C_ARB_LOST,
    I2C_BUS_ERROR,
    I2C_OVR,
    I2C_PECERR,
    I2C_TIMEOUT,
    I2C_SMBALERT,
}i2c_error_t;
/**
 * @brief   User callback function on I2C slave transmitting.
 * 
 * @param data  Pointer to user data to transmit.
 * 
 * @param len   Pointer to user data length.
 */
typedef void (*i2c_on_slave_transmit)(uint8_t *data, uint8_t *len);
/**
 * @brief   User callback function on I2C slave received.
 * 
 * @param data  Pointer to current received data.
 * 
 * @param len  Received data length.
 */
typedef void (*i2c_on_slave_receive)(uint8_t *data, uint8_t len);
struct i2c_slave_cb {
    i2c_on_slave_transmit on_transmit;
    i2c_on_slave_receive on_receive;
};
/**
 * @brief   I2C interrupt routine initialization.
 * 
 * @param address I2C address.
 */
void i2c_app_init(uint8_t address);
/**
 * @brief   I2C slave user callback function regiester.
 * 
 * @param cb    Pointer to user callback function.
 */
void i2c_slave_cb_register(struct i2c_slave_cb *cb);
/**
 * @brief   I2C master write data to slave.
 * 
 * @param addr_7bit I2C slave 7bit address.
 * @param data      Pointer to the write data.
 * @param length    Write data length.
 * @param wait      Choose to wait for the write process to end or not.
 * @param send_stop Choose to send stop or not.
 * @return          0 If successful. 
 */
int i2c_write_to(uint8_t addr_7bit, const uint8_t *data, uint8_t length,
        uint8_t wait, uint8_t send_stop);
/**
 * @brief   I2C master read data to slave
 * 
 * @param addr_7bit I2C slave 7bit address.
 * @param data      Pointer to the read data to put in. 
 * @param length    Read data length.
 * @param send_stop Choose to send stop or not
 * @param timeout   Read process timeout.
 * @return          Negative on error code otherwise indicates the actual read length.
 */
int i2c_read_from(uint8_t addr_7bit, uint8_t *data, uint8_t length,
        uint8_t send_stop, int timeout);
#ifdef __cplusplus
}
#endif
#endif /* EVT_EXAM_I2C_SRC_APP_I2C_C */

2) app_i2c.c


/********************************** (C) COPYRIGHT *******************************
 * File Name          : app_i2c.c
 * Author             : WCH
 * Version            : V1.0
 * Date               : 2022/11/04
 * Description        : 
 *********************************************************************************
 * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
 * Attention: This software (modified or not) and binary are used for 
 * microcontroller manufactured by Nanjing Qinheng Microelectronics.
 *******************************************************************************/
#include "app_i2c.h"
#include "CH58x_common.h"
/**
 * Note: 主机与从机的DEBUG接口需要同时打开或关闭,
 * 否则会产生时序问题。
 */
// #define CONFIG_I2C_DEBUG
#ifdef CONFIG_I2C_DEBUG
#define I2C_DBG(...)    PRINT(__VA_ARGS__)
#else
#define I2C_DBG(...)
#endif
static volatile uint8_t i2c_state;
static volatile uint8_t i2c_slave_addr_rw;
static volatile uint8_t i2c_send_stop;  // should the transaction end with a stop
static volatile uint8_t i2c_in_repstart;     // in the middle of a repeated start
static uint8_t i2c_master_buffer[I2C_BUFFER_LENGTH];
static volatile uint8_t i2c_master_buffer_index;
static uint8_t i2c_master_buffer_length;
static uint8_t i2c_slave_txbuffer[I2C_BUFFER_LENGTH];
static volatile uint8_t i2c_slave_txbuffer_index;
static uint8_t i2c_slave_txbuffer_length;
static uint8_t i2c_slave_rxbuffer[I2C_BUFFER_LENGTH];
static volatile uint8_t i2c_slave_rxbuffer_index;
static uint8_t is_nack_sent = false;
static volatile uint8_t i2c_error;
static struct i2c_slave_cb *slave_cb = NULL;
void i2c_app_init(uint8_t address)
{
    i2c_state = I2C_READY;
    i2c_send_stop = true;
    i2c_in_repstart = false;
    GPIOB_ModeCfg(GPIO_Pin_13 | GPIO_Pin_12, GPIO_ModeIN_PU);
    I2C_Init(I2C_Mode_I2C, 400000, I2C_DutyCycle_16_9, I2C_Ack_Enable, I2C_AckAddr_7bit, address);
    I2C_ITConfig(I2C_IT_BUF, ENABLE);
    I2C_ITConfig(I2C_IT_EVT, ENABLE);
    I2C_ITConfig(I2C_IT_ERR, ENABLE);
   
    PFIC_EnableIRQ(I2C_IRQn);
}
void i2c_slave_cb_register(struct i2c_slave_cb *cb)
{
   slave_cb = cb;
}
int i2c_write_to(uint8_t addr_7bit, const uint8_t *data, uint8_t length,
        uint8_t wait, uint8_t send_stop)
{
    if (length > I2C_BUFFER_LENGTH) {
        return -I2C_NO_MEM;
    }
    if (i2c_state != I2C_READY) {
        return -I2C_STATE;
    }
    if (!length) {
        return 0;
    }
    i2c_state = I2C_MTX;
    i2c_send_stop = send_stop;
    i2c_error = 0;
    // initialize buffer iteration vars
    i2c_master_buffer_index = 0;
    i2c_master_buffer_length = length;
    memcpy(i2c_master_buffer, data, length);
    i2c_slave_addr_rw = I2C_WRITE;
    i2c_slave_addr_rw |= addr_7bit << 1;
    I2C_GenerateSTOP(DISABLE);
    if (i2c_in_repstart == true) {
        i2c_in_repstart = false;
        do {
            I2C_SendData(i2c_slave_addr_rw);
        } while(R16_I2C_STAR1 & RB_I2C_BTF);
        /* Disabled in IRS */
        I2C_ITConfig(I2C_IT_BUF, ENABLE);
        I2C_ITConfig(I2C_IT_EVT, ENABLE);
        I2C_ITConfig(I2C_IT_ERR, ENABLE);
    } else {
        I2C_GenerateSTART(ENABLE);
    }
    while(wait && (i2c_state == I2C_MTX)) {
        continue;
    }
    if (i2c_error) {
        return -i2c_error;
    }
    return 0;
}
int i2c_read_from(uint8_t addr_7bit, uint8_t *data, uint8_t length,
        uint8_t send_stop, int timeout)
{
    int to = 0;
    uint8_t forever = (timeout == -1);
    if (length > I2C_BUFFER_LENGTH) {
        return -I2C_NO_MEM;
    }
    if (i2c_state != I2C_READY) {
        return -I2C_STATE;
    }
    if (!length) {
        return 0;
    }
    i2c_state = I2C_MRX;
    i2c_send_stop = send_stop;
    i2c_error = 0;
    // initialize buffer iteration vars
    i2c_master_buffer_index = 0;
    i2c_master_buffer_length = length - 1;
    i2c_slave_addr_rw = I2C_READ;
    i2c_slave_addr_rw |= addr_7bit << 1;
    I2C_GenerateSTOP(DISABLE);
    if (i2c_in_repstart == true) {
        i2c_in_repstart = false;
        do {
            I2C_SendData(i2c_slave_addr_rw);
        } while(R16_I2C_STAR1 & RB_I2C_BTF);
        /* Disabled in IRS */
        I2C_ITConfig(I2C_IT_BUF, ENABLE);
        I2C_ITConfig(I2C_IT_EVT, ENABLE);
        I2C_ITConfig(I2C_IT_ERR, ENABLE);
    } else {
        I2C_GenerateSTART(ENABLE);
    }
    // wait for read operation to complete
    while (i2c_state == I2C_MRX) {
        mDelaymS(1);
        to++;
        if (!forever && (to >= timeout)) {
            break;
        }
    }
    if (i2c_master_buffer_index < length)
        length = i2c_master_buffer_index;
    // copy i2c buffer to data
    memcpy(data, i2c_master_buffer, length);
    return length;
}
#ifdef CONFIG_I2C_DEBUG
static void print_i2c_irq_sta(uint32_t state)
{
    I2C_DBG("i2c irq: ( ");
    if(state & RB_I2C_SB)
        I2C_DBG("SB ");
    if(state & RB_I2C_ADDR)
        I2C_DBG("ADDR ");
    if(state & RB_I2C_BTF)
        I2C_DBG("BTF ");
    if(state & RB_I2C_ADD10)
        I2C_DBG("ADD10 ");
    if(state & RB_I2C_STOPF)
        I2C_DBG("STOP ");
    if(state & RB_I2C_RxNE)
        I2C_DBG("RxNE ");
    if(state & RB_I2C_TxE)
        I2C_DBG("TxE ");
    if(state & RB_I2C_BERR)
        I2C_DBG("BERR ");
    if(state & RB_I2C_ARLO)
        I2C_DBG("ARLO ");
    if(state & RB_I2C_AF)
        I2C_DBG("AF ");
    if(state & RB_I2C_OVR)
        I2C_DBG("OVR ");
    if(state & RB_I2C_PECERR)
        I2C_DBG("PECERR ");
    if(state & RB_I2C_TIMEOUT)
        I2C_DBG("TIMEOUT ");
    if(state & RB_I2C_SMBALERT)
        I2C_DBG("SMBALERT ");
    if(state & (RB_I2C_MSL << 16))
        I2C_DBG("MSL ");
    if(state & (RB_I2C_BUSY << 16))
        I2C_DBG("BUSY ");
    if(state & (RB_I2C_TRA << 16))
        I2C_DBG("TRA ");
    if(state & (RB_I2C_GENCALL << 16))
        I2C_DBG("GENCALL ");
    if(state & (RB_I2C_SMBDEFAULT << 16))
        I2C_DBG("SMBDEFAULT ");
    if(state & (RB_I2C_SMBHOST << 16))
        I2C_DBG("SMBHOST ");
    if(state & (RB_I2C_DUALF << 16))
        I2C_DBG("DUALF ");
    I2C_DBG(")\n");
}
#else
static inline void print_i2c_irq_sta(uint32_t state)
{
    (void)state;
}
#endif
__INTERRUPT
__HIGH_CODE
void I2C_IRQHandler(void)
{
    uint32_t event = I2C_GetLastEvent();
    print_i2c_irq_sta(event);
    /* I2C Master */
    if (event & (RB_I2C_MSL << 16)) {
        if (event & RB_I2C_SB) {
            /* Start condition sent, send address */
            I2C_SendData(i2c_slave_addr_rw);
            I2C_DBG("Master selected, send address\n");
        }
        /* I2C Master transmitter */
        if (event & (RB_I2C_TRA << 16)) {
            I2C_DBG("Master transmitter:\n");
            /* Slave receiver acked address or sent bit */
            if (event & (RB_I2C_ADDR | RB_I2C_BTF | RB_I2C_TxE | (RB_I2C_TRA << 16))) {
                /* if there is data to send, send it, otherwise stop */
                if (i2c_master_buffer_index < i2c_master_buffer_length) {
                    I2C_SendData(i2c_master_buffer[i2c_master_buffer_index++]);
                    I2C_DBG("  send (%#x)\n",
                            i2c_master_buffer[i2c_master_buffer_index - 1]);
                } else {
                    if (i2c_send_stop) {
                        i2c_state = I2C_READY;
                        I2C_GenerateSTOP(ENABLE);
                        I2C_DBG("  send STOP\n");
                    } else {
                        i2c_in_repstart = true;
                        /* we're gonna send the START, don't enable the interrupt. */
                        I2C_ITConfig(I2C_IT_BUF, DISABLE);
                        I2C_ITConfig(I2C_IT_EVT, DISABLE);
                        I2C_ITConfig(I2C_IT_ERR, DISABLE);
                        I2C_GenerateSTART(ENABLE);
                        i2c_state = I2C_READY;
                        I2C_DBG("  restart\n");
                    }
                }
            }
            /* Address or data sent, nack received */
            if (event & RB_I2C_AF) {
                I2C_ClearFlag(I2C_FLAG_AF);
                i2c_error = I2C_MT_NACK;
                i2c_state = I2C_READY;
                I2C_GenerateSTOP(ENABLE);
                I2C_DBG("  NACK received, sent stop\n");
            }
        } else {
        /* I2C Master reveiver */
            I2C_DBG("Master receiver:\n");
            /* address sent, ack received */
            if(event & RB_I2C_ADDR) {
                /* ack if more bytes are expected, otherwise nack */
                if (i2c_master_buffer_length) {
                    I2C_AcknowledgeConfig(ENABLE);
                    I2C_DBG("  address sent\n");
                    I2C_DBG("  ACK next\n");
                } else {
                    //XXX: Should not delay too match before NACK 
                    I2C_AcknowledgeConfig(DISABLE);
                    is_nack_sent = true;
                    I2C_DBG("  address sent\n");
                    I2C_DBG("  NACK next\n");
                }
            }
            /* data reveived */
            if (event & (RB_I2C_RxNE)) {
                /* put byte into buffer */ 
                i2c_master_buffer[i2c_master_buffer_index++] = I2C_ReceiveData();
                if (i2c_master_buffer_index < i2c_master_buffer_length) {
                    I2C_AcknowledgeConfig(ENABLE);
                    I2C_DBG("  ACK next\n");
                } else {
                    //XXX: Should not delay too match before NACK 
                    I2C_AcknowledgeConfig(DISABLE);
                    I2C_DBG("  NACK next\n");
                    if (is_nack_sent) {
                        is_nack_sent = false;
                        if (i2c_send_stop) {
                            I2C_GenerateSTOP(ENABLE);
                            i2c_state = I2C_READY;
                            I2C_DBG("  send STOP\n");
                        } else {
                            i2c_in_repstart = true;
                            /* we're gonna send the START, don't enable the interrupt. */
                            I2C_ITConfig(I2C_IT_BUF, DISABLE);
                            I2C_ITConfig(I2C_IT_EVT, DISABLE);
                            I2C_ITConfig(I2C_IT_ERR, DISABLE);
                            I2C_GenerateSTART(ENABLE);
                            i2c_state = I2C_READY;
                            I2C_DBG("  restart\n");
                        }
                    } else {
                        is_nack_sent = true;
                    }
                }
                I2C_DBG("  received data (%#x)\n",
                        i2c_master_buffer[i2c_master_buffer_index - 1]);
            }
            /* nack received */
            if (event & RB_I2C_AF) {
                I2C_ClearFlag(I2C_FLAG_AF);
                /* put final byte into buffer */
                i2c_master_buffer[i2c_master_buffer_index++] = I2C_ReceiveData();
                if (i2c_send_stop) {
                    i2c_state = I2C_READY;
                    I2C_GenerateSTOP(ENABLE);
                    I2C_DBG("  NACK received, send STOP\n");
                } else {
                    i2c_in_repstart = true;
                    /* we're gonna send the START, don't enable the interrupt. */
                    I2C_ITConfig(I2C_IT_BUF, DISABLE);
                    I2C_ITConfig(I2C_IT_EVT, DISABLE);
                    I2C_ITConfig(I2C_IT_ERR, DISABLE);
                    I2C_GenerateSTART(ENABLE);
                    i2c_state = I2C_READY;
                    I2C_DBG("  restart\n");
                }
            }
        }
    } else {
    /* I2C slave */
        /* addressed, returned ack */
        if (event & RB_I2C_ADDR) {
            if (event & ((RB_I2C_TRA << 16) | RB_I2C_TxE)) {
                I2C_DBG("Slave transmitter address matched\n");
               
                i2c_state = I2C_STX;
                i2c_slave_txbuffer_index = 0;
                i2c_slave_txbuffer_length = 0;
                if (slave_cb && slave_cb->on_transmit) {
                    slave_cb->on_transmit(i2c_slave_txbuffer, &i2c_slave_txbuffer_length);
                }
            } else {
                I2C_DBG("Slave reveiver address matched\n");
                i2c_state = I2C_SRX;
                i2c_slave_rxbuffer_index = 0;
            }
        }
        if (event & (RB_I2C_TRA << 16)) { //TODO: STOP?
            /* Slave transmintter */
            I2C_AcknowledgeConfig(ENABLE);
            I2C_DBG("Slave transmitter:\n");
            if (event & RB_I2C_AF) {
                /* Nack received */
                I2C_ClearFlag(I2C_FLAG_AF);
                I2C_AcknowledgeConfig(ENABLE);
                I2C_DBG("  Nack received\n");
                /* leave slave receiver state */
                i2c_state = I2C_READY;
                /* clear status */
                event = 0;
            }
            if (event & (RB_I2C_BTF | RB_I2C_TxE)) {
                /* if there is more to send, ack, otherwise send 0xff */
                if (i2c_slave_txbuffer_index < i2c_slave_txbuffer_length) {
                    /* copy data to output register */
                    I2C_SendData(i2c_slave_txbuffer[i2c_slave_txbuffer_index++]);
                    I2C_DBG("  send (%#x)\n",
                        i2c_slave_txbuffer[i2c_slave_txbuffer_index - 1]);
                } else {
                    I2C_SendData(0xff);
                    I2C_DBG("  no more data, send 0xff\n");
                }
            }
        } else {
            /* Slave receiver */
            I2C_DBG("Slave receiver:\n");
            if (event & RB_I2C_RxNE) {
                /* if there is still room in the rx buffer */
                if (i2c_slave_rxbuffer_index < I2C_BUFFER_LENGTH) {
                    /* put byte in buffer and ack */
                    i2c_slave_rxbuffer[i2c_slave_rxbuffer_index++] = I2C_ReceiveData();
                    I2C_AcknowledgeConfig(ENABLE);
                    I2C_DBG("  received (%#x)\n",
                            i2c_slave_rxbuffer[i2c_slave_rxbuffer_index - 1]);
                } else {
                    // otherwise nack
                    I2C_AcknowledgeConfig(DISABLE);
                }
            }
            if (event & RB_I2C_STOPF) {
                /* ack future responses and leave slave receiver state */
                R16_I2C_CTRL1 |= RB_I2C_PE; //clear flag
                I2C_DBG("  reveive stop\n");
                /* callback to user defined callback */
                if (slave_cb && slave_cb->on_receive) {
                    slave_cb->on_receive(i2c_slave_rxbuffer, i2c_slave_rxbuffer_index);
                }
                /* since we submit rx buffer , we can reset it */
                i2c_slave_rxbuffer_index = 0;
            }
            if (event & RB_I2C_AF) {  
                I2C_ClearFlag(I2C_FLAG_AF);
                /* ack future responses */
                I2C_AcknowledgeConfig(ENABLE);
            }
        }
    }
    if (event & RB_I2C_BERR) {
        I2C_ClearFlag(RB_I2C_BERR);
        I2C_GenerateSTOP(ENABLE);
        i2c_error = I2C_BUS_ERROR;
        I2C_DBG("RB_I2C_BERR\n");
    }
    if (event & RB_I2C_ARLO) {
        I2C_ClearFlag(RB_I2C_ARLO);
       
        i2c_error = I2C_ARB_LOST;
        I2C_DBG("RB_I2C_ARLO\n");
    }
    if (event & RB_I2C_OVR) {
        I2C_ClearFlag(RB_I2C_OVR);
       
        i2c_error = I2C_OVR;
        I2C_DBG("RB_I2C_OVR\n");
    }
    if (event & RB_I2C_PECERR) {
        I2C_ClearFlag(RB_I2C_PECERR);
       
        i2c_error = I2C_PECERR;
        I2C_DBG("RB_I2C_PECERR\n");
    }
    if (event & RB_I2C_TIMEOUT) {
        I2C_ClearFlag(RB_I2C_TIMEOUT);
       
        i2c_error = I2C_TIMEOUT;
        I2C_DBG("RB_I2C_TIMEOUT\n");
    }
    if (event & RB_I2C_SMBALERT) {
        I2C_ClearFlag(RB_I2C_SMBALERT);
       
        i2c_error = I2C_SMBALERT;
        I2C_DBG("RB_I2C_SMBALERT\n");
    }
    I2C_DBG("\n");
}


3) main.c

#include "CH58x_common.h"
#include "app_i2c.h"
/* I2C Mode Definition */
#define HOST_MODE     0
#define SLAVE_MODE    1
/* I2C Communication Mode Selection */
//#define I2C_MODE      HOST_MODE
#define I2C_MODE      SLAVE_MODE
/* Global define */
#define SIZE            7
#define MASTER_ADDR     0x10
#define SLAVE_ADDR      0x20
/* Global Variable */
uint8_t TxData[SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
uint8_t RxData[SIZE];
#if (I2C_MODE == SLAVE_MODE)
// 从机发送回调函数
static void i2c_on_slave_transmit_user(uint8_t *data, uint8_t *len)
{
    *len = sizeof(TxData);
    memcpy(data, TxData, sizeof(TxData));
}
// 从机接收回调函数
static void i2c_on_slave_receive_user(uint8_t *data, uint8_t len)
{
    PRINT("I2C slave receiver callback: received (");
    for(int i = 0; i < len; i++) {
        PRINT(" %#x", data[i]);
    }
    PRINT(" )\n");
}
#endif
int main()
{
    uint8_t i = 0;
    SetSysClock(CLK_SOURCE_PLL_60MHz);
    GPIOA_SetBits(GPIO_Pin_9);
    GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
    GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
    UART1_DefInit();
    GPIOB_ModeCfg(GPIO_Pin_13 | GPIO_Pin_12, GPIO_ModeIN_PU);
    PRINT("IIC Slave mode\r\n");
    struct i2c_slave_cb slave_user = {
        .on_receive = i2c_on_slave_receive_user,
        .on_transmit = i2c_on_slave_transmit_user,
    };
    i2c_app_init(SLAVE_ADDR);
    i2c_slave_cb_register(&slave_user);
    while(1) {
    }
}

2、ESP8266开发板,Arduino代码


#include <Wire.h>  // 包含I2C库
void setup() {
  Serial.begin(115200);  // 初始化串口通信
  while (!Serial);       // 等待串口连接(仅对某些开发板需要)
 
  Serial.println("\nI2C Scanner");
  Wire.begin();          // 初始化I2C总线,SDA和SCL使用默认引脚
   Wire.setClock(400000L);       // 设置 I2C 时钟为 400KHz
  // 对于ESP8266,默认I2C引脚是:
  // SDA - GPIO4 (D2)
  // SCL - GPIO5 (D1)
}
byte dev_address = 0, dat = 0;
void loop() {
  byte error, address;
  int nDevices = 0;
 
  if (dev_address == 0) {
     
    Serial.println("Scanning I2C bus...");
    for (address = 1; address < 127; address++) {
      // 使用返回值进行错误检测
      Wire.beginTransmission(address);
      error = Wire.endTransmission();
      if (error == 0) {
        Serial.print("I2C 地址 : 0x");
        Serial.print(address, HEX);
        Serial.print("\r\n");
        dev_address = address;
        Serial.print("I2C device found at address 0x");
        if (address < 16) {
          Serial.print("0");
        }
        Serial.print(address, HEX);
        Serial.println();
        nDevices++;
        break;
      } else if (error == 4) {
        Serial.print("Unknown error at address 0x");
        if (address < 16) {
          Serial.print("0");
        }
        Serial.println(address, HEX);
      }
    }
    if (nDevices == 0) {
      Serial.println("No I2C devices found\n");
    } else {
      Serial.println("Scan completed\n");
    }
  } 
  if (dev_address > 0) {
    Serial.print("发送数据到 0x");
    Serial.print(dev_address, HEX);
    Serial.print(" : 0x");
    Serial.print(dat, HEX);
    Serial.print("\r\n");
    Wire.beginTransmission(dev_address);
    Wire.write(dat);
    Wire.endTransmission();
    dat++;
 
  }
  delay(1000);
}


三、测试结果

 1、ESP8266侧

image.png

2、CH582M侧

image.png

注: 在CH582M侧设置的从机地址为0x20,而在ESP8266侧检测出的地址是0x10(是0x20的二分之一),这是正常的。是由于不同的处理方式造成的结果。这一点在,在使用其他I2C设备时,也是一样的。测试时将在CH582M侧设置的从机地址改为0x10,在ESP8266侧检测出的地址就是0x08,这一点已经被验证了。





关键词: CH582M     I2C     从机模式    

共1条 1/1 1 跳转至页

回复

匿名不能发帖!请先 [ 登陆 注册 ]