[MCU] 【HC32F448测评】+ I2C及OLED显示

dmzdmz666666   2023-8-19 15:25 楼主

第四篇:I2C通讯及OLED显示

这篇文章将来测评HC32F448的硬件I2C和用I2C驱动OLED。

我选用的OLED是市面上常见的0.96寸OLED,它支持I2C和SPI接口,常见的驱动方式是使用软件I2C或者SPI,这里我将用HC32的硬件I2C将其驱动。

首先,因为市面上用0.96寸的OLED的人很多,所以一些开发者或商家就编写其的通用驱动,为了提高开发效率,避免重复造轮子,我选用某园的驱动,它提供了非常多的例程,我就在其基础上修改。

首先,在Hardware文件夹中新建I2C.c、0_96_OLED.c等C文件及其对应的h头文件。然后在Drivers中添加对应组件如下图所示

image-20230819152353-1.png  

第二步,配置HC32F448的硬件I2C,这里参考官方提供的HC32F448_DDL_Rev1.0.0\HC32F448_DDL_Rev1.0.0\projects\ev_hc32f448_lqfp80\examples\i2c\i2c_master_polling

首先是MY_I2C_Init(void),包含对I2C的GPIO的选择和复用功能初始化、使能I2C的时钟、配置I2C的分频系数、传输速率等。

然后就是I2C_Master_Transmit(),该函数负责发送数据,输入参数包括从机地址、待传输数据地址、数据数量、超时时间。

然后就是I2C_Master_Receive(),该函数负责接收数据,输入参数包括从机地址、待接收数据地址、数据接收数量、超时时间。

第三步,将某园的OLED的I2C驱动复制到0_96_OLED.c,面对不同的MCU,只需要移植驱动层,包括OLED指令发送函数和OLED数据发送函数,应用层脱离于具体硬件,不需要移植。

OLED指令发送函数Write_IIC_Command()和OLED数据发送函数Write_IIC_Data()类似,首先发送第一个8位数据:7位从机地址+读写位,因为都是向OLED发送的,所以读写位为0;第二个8位数据为控制字节,如果接下来发送为指令,那么为0x00,如果是数据,那么为0x40;第三个8位数据就是具体的指令或者数据。具体如下。

image-20230819152353-2.png  

这里一定一定要注意从机的地址,原来用模拟I2C的时候比如Write_IIC_Command()是下面这样子的:

image-20230819152353-3.png  

我想当然是从机地址为0x78,可实际是这个0x78是包含了最后一位的读写位0,实际的地址应该是0x78>>1,而使用I2C_Master_Transmit()填入的从机地址需要真实的地址0x3C(0x78>>1),因为其会调用I2C_TransAddr()来发送地址,I2C_TransData()来发送数据,而I2C_TransAddr()内部是通过下面的语句发送地址,可以看到其会自动将从机地址右移一位并加上读写位,经过它处理才是0x78,所以你填入的从机地址一定要是真实的从机地址,这里纪念一下我踩了几天的坑,呜呜呜呜!!!

I2C_WriteData(I2Cx, (uint8_t)(u16Addr << 1U) | u8Dir);

移植好这两个核心函数后,其他基本就没什么问题了。然后在主函数屏蔽掉BSP_IO_Init()和BSP_LED_Init(),因为这两个函数会使用I2C1驱动IO口扩展芯片TCA9539,而我OLED使用的正是I2C1,要防止冲突。

image-20230819152353-4.png  

最后写入对应的API,就能显示对应的效果了。

image-20230819152353-5.jpeg  

回复评论 (2)

UI设计还是很优雅的,i2c的地址,还真要的读一下协议才能知道正确的写地址,就是地址后面增加写数据与写指令的位。

点赞  2023-8-20 07:05
引用: lugl4313820 发表于 2023-8-20 07:05 UI设计还是很优雅的,i2c的地址,还真要的读一下协议才能知道正确的写地址,就是地址后面增加写数据与写指 ...

主要之前都是软件I2C 直接参考别人的 改GPIO就好了 用硬件I2C就要适配其库函数 下次就会注意了 

点赞  2023-8-21 21:58
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复