0x01:IIC详解
iic详解
0x02:硬件
本次采用外接0.96寸OLED iic屏幕来测试软件IIC
因为是软件IIC,所以OLED的SDA,SCL随便连IO就行
0x03:软件
oled驱动可以使用自己的,也可以使用官方的。
在参照官方例程移植soft - iic时,发现AB32VG1的库函数不全,导致GET_PIN()函数没有被声明和实现
因此该函数需要被用户自己声明与实现。那么GET_PIN()到底有什么用呢?
调用函数rt_pin_get()去获取PIN时,编译器会报“initializer element is not constant” 错误,原因是在编译时,rt_pin_get()返回的是一个不确定值,无法初始化IIC的引脚结构体。所以要实现GET_PIN()。
如何实现GET_PIN()?
上面说到rt_pin_get()几乎等同于GET_PIN(),因此,要从rt_pin_get()函数下手。本次不将rt_pin_get()贴出。经过分析得到其核心函数为PIN_NUM()。再将PIN_NUM()进行分析,可发现所有引脚都来自于port_table[]这个数组。
struct port_info
{
uint8_t start_pin; // 开始引脚
uint8_t delta_pin; // 引脚数量
uint8_t total_pin; // 总共的引脚
};
static const struct port_info port_table[] =
{
{0, 8, 0}, /* PA0-PA7 /
{0, 5, 8}, / PB0-PB5 / 8 = delta_pin+total_pin = 8+0
{0, 8, 13}, / PE0-PE7 / 13 = 5+8
{0, 6, 21}, / PF0-PF6 */ 21 = 8 + 13
};
#define PIN_NUM(port, no) ((uint8_t)(port_table[port].total_pin + no - port_table[port].start_pin))
// 自己实现GET_PIN()
#define __AB32_GET_PIN_A(PIN) PIN
#define __AB32_GET_PIN_B(PIN) 8 + PIN
#define __AB32_GET_PIN_E(PIN) 13 + PIN
#define __AB32_GET_PIN_F(PIN) 21 + PIN
#define GET_PIN(PORTx,PIN) (uint8_t)_AB32_GET_PIN##PORTx(PIN)
已向rt-thread贡献一个PR
0x04:使用
// 1. 先声明一个iic句柄
static struct rt_i2c_bus_device * i2c;
// 2. 初始化iic句柄
i2c = (struct rt_i2c_bus_device *)rt_device_find("i2c1");
// 3. iic发送数据
uint8_t buf[2] = {0x00, I2C_Command};
rt_i2c_master_send(i2c, 0x3c, RT_I2C_WR, buf, 2);
具体代码详见gitee
效果展示
原作者:JiangYangJie