本帖最后由 freeelectron 于 2021-1-23 17:32 编辑
1、硬件连接使用IIC接口驱动
同时需要上拉电阻4.7k。
2、IO口
SCL和SDA使用使用PB10和PB11,因此配置成复用功能5;
void i2c_pin_init(void)
{
md_gpio_init_t x;
/* Initialize scl pin */
x.mode = MD_GPIO_MODE_OUTPUT;
x.odos = MD_GPIO_OPEN_DRAIN;
x.pupd = MD_GPIO_PUSH_UP;
x.nodrv = MD_GPIO_OUT_DRIVE_1;
x.flt = MD_GPIO_FILTER_DISABLE;
x.type = MD_GPIO_TYPE_TTL;
x.func = MD_GPIO_FUNC_5;
md_gpio_init(GPIOB, MD_GPIO_PIN_10, &x);
/* Initialize sda pin */
x.mode = MD_GPIO_MODE_OUTPUT;
x.odos = MD_GPIO_OPEN_DRAIN;
x.pupd = MD_GPIO_PUSH_UP;
x.nodrv = MD_GPIO_OUT_DRIVE_1;
x.flt = MD_GPIO_FILTER_DISABLE;
x.type = MD_GPIO_TYPE_TTL;
x.func = MD_GPIO_FUNC_5;
md_gpio_init(GPIOB, MD_GPIO_PIN_11, &x);
return;
}
3、I2C外设配置
md_i2c_struct_init(&init);用于获取md_i2c_init_t结构体的值,也可以自己配置,库函数里面有个默认配置md_i2c_init(I2C1, &init);初始化I2C
md_i2c_set_addr_0_9_bit:用于设置从机地址,从机地址是0x78
md_i2c_set_transmit_length(I2C1,2); 设置发送的数据长度为2byte;
md_i2c_enable_auto_end(I2C1); 用于配置自动产生stop信号。
void I2C_PeriphInit(void)
{
md_i2c_init_t init;
memset(&init, 0, sizeof(md_i2c_init_t));
md_i2c_struct_init(&init);
md_i2c_init(I2C1, &init);
md_i2c_set_transmit_fifo_reset(I2C1);
md_i2c_set_transmit_length(I2C1,2);
md_i2c_set_addr_0_9_bit(I2C1, OLED_ADDRESS);
md_i2c_enable_auto_end(I2C1);
md_i2c_enable_master_write(I2C1);
}
4、I2C写数据
void I2C_WriteByte(uint8_t addr,uint8_t data)
{
md_i2c_set_start(I2C1); //START信号,启用会,会自动发送从机地址
md_i2c_set_tx_reg_data(I2C1, addr);
<b> while(!md_i2c_is_active_txe(I2C1 )); //特别重要,用于判断fifo为空。
</b>
md_i2c_set_tx_reg_data(I2C1, data);
}
用逻辑分析仪抓取波形,速度基本与配置的一样,100k,。
5、OLED写数据和命令
这里都是通用的,关于详细的原理可以参考:OLED驱动原理
void WriteCmd(uint8_t I2C_Command)//写命令
{
I2C_WriteByte(0x00, I2C_Command);
}
void WriteDat(uint8_t I2C_Data)//写数据
{
I2C_WriteByte(0x40, I2C_Data);
}
6、OLED显示
字库取模方式:共阴、列行式、逆向输出。
最后说一点,es32f369x的硬件i2c驱动方式与stm32有很大区别。
篇幅有限,附上完整代码:
periph_oled.rar
(5.12 KB)
|