LOADING

加载过慢请开启缓存 浏览器默认开启

arduino的IIC通信

2024/12/29 arduino arduino

arduino的IIC

首先arduino的IIC是硬件IIC,硬件IIC一般都是固定引脚的
所以需要自己先去查一下自己芯片的第一组IIC接口是哪两个引脚
(esp32例外)
然后,需要芯片支持Wire.h库。一般芯片都会自带有的。
(这是官方库)
最后说明:读写缓存只有 32 字节
文件宏定义:

//这个为IIC头文件
#include <Wire.h>
//

esp32iic可以是任意的IO

主机模式

IIC初始化

Wire.begin(address);          // 初始化IIC
参数 数据类型 作用 选项
address int 注册成为从机模式 0到128之间
返回值
Wire.begin();          // 初始化IIC
参数 数据类型 作用 选项
啥也不填直接调用就是主机模式
返回值

esp32iic可以是任意的IO

所以

初始化主机模式

Wire.begin(sda,scl);          // 初始化IIC
参数 数据类型 作用 选项
sda int 定义sda的引脚 单片机引脚
scl int 定义scl的引脚 单片机引脚
返回值

初始化从机模式

Wire.begin(sda,scl,address);          // 初始化IIC
参数 数据类型 作用 选项
sda int 定义sda的引脚 单片机引脚
scl int 定义scl的引脚 单片机引脚
address int 注册成为从机模式 0到128之间
返回值

主机准备向从机读数据

Wire.requrstFrom(addtess,quantity)
Wire.requrstFrom(addtess,quantity,stop)
参数 数据类型 作用 选项
address int 向指定从机请求数据 0到128之间
quantity int 请求数据的长度(单位字节) 0到32之间
stop 布尔形 ‘真’ 则在请求结束后发送一个停止命令,并释放总线。‘假’则继续发送请求保持连接 真或者假
返回值 int 主机从从机接受到的字节数目,主机接受到一个数据返回的字节数就会减少一个

主机准备向从机写数据

Wire.beginTransmission(addtess);
参数 数据类型 作用 选项
address int 向指定从机请求数据 0到128之间
返回值

发送停止位

Wire.endTransmission()
Wire.endTransmission(stop)
参数 数据类型 作用 选项
stop 布尔形 ‘真’ 发送一个停止信息,并释放总线。‘假’则继续发送请求保持连接 真或者假
返回值 int 0、成功 1、数据溢出 2、发送addtess时从机接受到NACK 3、发送数据时接受到 NACK 4、其他错误

发送数据

Wire.write(value)
Wire.write(string)
Wire.write(data, length)
参数 数据类型 作用 选项
value int 要发送的数值 int
string string 发送的字符组的指针 字符组
data 数组 要发送的数组 数组
length int 发送的数组的长度(单位字节) int
返回值

返回读到的字节数

Wire. available()
参数 数据类型 作用 选项
返回值 int 主机从从机接受到的字节数目,主机接受到一个数据返回的字节数就会减少一个

读取数据

Wire.read()
参数 数据类型 作用 选项
返回值 uint8_t 读到的字节数据,通常一次返回一个字节的数据

从机模式

当从机接受到主机写的请求

Wire.onReceive(handler)
参数 数据类型 作用 选项
handler 回调函数 当从机接受到数据就执行回调函数,回调函数需要带一个int型参数(无返回值) void handler(int howMany){}
返回值 uint8_t 主机从从机接受到的字节数目,主机接受到一个数据返回的字节数就会减少一个

当从机接受到主机读的请求

Wire.onRequest(handler)
参数 数据类型 作用 选项
handler 回调函数 当从机接受到数据就执行回调函数(无返回值) 回调函数
返回值 uint8_t 主机从从机接受到的字节数目,主机接受到一个数据返回的字节数就会减少一个

参考代码bh1750通信

//addr接高电平设备地址为1011100也就是0x5c
//低电平0100011也就是0x23
uint8_t data[1];
uint16_t Rx_Data;
int i;
#include <Wire.h>
void setup() {
// put your setup code here, to run once:
Wire.begin();
Serial.begin(115200);
bh711 ();
}
void loop() {
// put your main code here, to run repeatedly
i=0;
Wire.requestFrom(0x5c, 2);//请求两个字节数据
    // 当从从设备接收到信息时值为true
    while (Wire.available())
    {
    Serial.println(i);
        // 接受并读取从设备发来的一个字节的数据
        data[i] = Wire.read();
        i++;
        // 向串口打印该字节
        if (i=2)
        {
        Rx_Data = ((uint16_t)data[0] << 8) + data[1];//0高位1地位
        }
    }
    Serial.println(Rx_Data/ 1.2f);//合并数据并打印
    delay(500);
}

void bh711 ()
{
Wire.beginTransmission(0x5c);//请求设备地址
Wire.write(0x00);//关闭电源
Wire.endTransmission();//结束通信
Wire.beginTransmission(0x5c);
Wire.write(0x01);//打开电源
Wire.endTransmission();
Wire.beginTransmission(0x5c);
Wire.write(0x07);//初始化扫描
Wire.endTransmission();
    Wire.beginTransmission(0x5c);
Wire.write(0x11);//连续h分辨率模式2
Wire.endTransmission();
}

从机和主机通信

目前已知air001(py32f002a)iic从机有问题
从机代码

#include <Wire.h>

#define I2C_ADDR  2
int a;
char adb[0];
void setup()
{
Wire.begin(I2C_ADDR);         // join i2c bus with address #4
Wire.onRequest(requestEvent); // register event
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600);           // start serial for output
}

void loop()
{
//empty loop

}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
a++;
int cc;
while( Wire.available()) // loop through all but the last
{
    cc = Wire.read();     // receive byte as a character
    if (cc)
    {
    a++;
    }
    //Serial.print(cc);          // print the character
}
//int x = Wire.read();        // receive byte as an integer
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{

sprintf(adb, "%d",a);
Wire.write(a);  // respond with message of 6 bytes
                        // as expected by master
}

主机代码

#include <Wire.h>
void setup() {
// put your setup code here, to run once:
Wire.begin();
Serial.begin(115200);
}

void loop() {
// put your main code here, to run repeatedly:

    // 向从设备#8请求1个字节

    Wire.requestFrom(2, 1);
    // 当从从设备接收到信息时值为true
    while (Wire.available())
    {
        // 接受并读取从设备发来的一个字节的数据
        char c = Wire.read();
        // 向串口打印该字节
        Serial.print(c);
    }
    Wire.endTransmission();

    Wire.beginTransmission(2);
    Wire.write(0x78);
Wire.endTransmission();
    
    delay(500);
}