#2020征文-开发板#基于HiSpark Wi-Fi IoT套件_4-IIC设备驱动
上一篇报告主要介绍了HI3861的GPIO操作,而本次报告主要是通过OLED驱动讲解下IIC接口的操作方式,本次报告主要内容如下:
1、 OLED规格书熟悉及电路图解读
2、 代码编写以
3、 烧录测试
一、OLED规格书熟悉及电路图解读
从HiSpark_WiFi_IoT智能家居套件硬件资料目录“\HiSpark_WiFi_IoT智能开发套件_原理图硬件资料\数据手册\HiSpark_WiFi_IoT_OLED_VER.A\金马鼎0.96白色30Pin.pdf”来看,oled屏幕采用的是ssd1306驱动芯片,此芯片支持并口、3/4线SPI、IIC接口。
芯片规格书在目录“\HiSpark_WiFi_IoT智能开发套件_原理图硬件资料\数据手册\HiSpark_WiFi_IoT_OLED_VER.A\SSD1306.pdf”内。
通过阅读屏幕跟芯片的规格书可以得知OLED屏幕为128X64点阵,驱动芯片内部显存128*64/8=1024字节。屏幕点阵每8行为一个page,每个page128列。
每个page内部与显存字节对应关系如下图,字节高位(MSB)在下,此对应关系与字体取模有关系。
资料里面有提供51单片机例程,在“\HiSpark_WiFi_IoT智能开发套件_原理图硬件资料\数据手册\HiSpark_WiFi_IoT_OLED_VER.A\c\SRC”目录下,经过阅读代码发现采用的是GPIO模拟时序方式控制的。
通过查看“E:\IOTSmarthomekit\doc\HiSpark_WiFi_IoT智能开发套件_原理图硬件资料\数据手册\HiSpark_WiFi_IoT_OLED_VER.A\原理图\接口原理图.pdf.pdf “可以发现OLED选用的接口方式是IIC方式。
通过“\HiSpark_WiFi_IoT智能开发套件_原理图硬件资料\原理图\HiSpark_WiFi_IoT_OLED_VER.A”可以看出是通过J7的3、4pin引出的IIC接口。
而J7在底板上对用的是J3,通过查看底板原理图“\HiSpark_WiFi_IoT智能开发套件_原理图硬件资料\原理图\HiSpark_WiFi_IoT_EXB_VER.A.pdf“J3的信号对应,可以确定IIC引脚分别对应HI3861 的GPIO13(IIC0_SDA)、GPIO14(IIC_SCL)。
二、代码编写与修改
首先要修改代码以及编译文件使能IIC0支持,默认是不支持的。主要有如下修改:
1、修改“vendor\hisi\hi3861\hi3861\app\wifiiot_app\init\app_io_init.c“,在”hi_void app_io_init(hi_void)“函数内将IIC0对应的两个GPIO修改为GPIO_13、GPIO_14,代码摘录如下。
/* I2C MUX: */
#ifdef CONFIG_I2C_SUPPORT
/* [Xwind]I2C IO复用也可以选择3/4; 9/10,根据产品设计选择 */
hi_io_set_func(HI_IO_NAME_GPIO_13, HI_IO_FUNC_GPIO_13_I2C0_SDA);
hi_io_set_func(HI_IO_NAME_GPIO_14, HI_IO_FUNC_GPIO_14_I2C0_SCL);
#endif
2、修改文件:”vendor\hisi\hi3861\hi3861\build\config\usr_config.mk, 增加 “CONFIG_I2C_SUPPORT= y”内容,添加IIC驱动支持。
3、修改hmos内部“\applications\sample\wifi-iot\app\xapp”下的用户代码,代码内容会在报告附件内体现,主要涉及的关键内容讲解如下。
hi_u32 hi_i2c_init(hi_i2c_idx id, hi_u32 baudrate) 函数:
IIC初始化函数,函数原型在“\vendor\hisi\hi3861\hi3861\platform\drivers\i2c\i2c.c”内,其中hi_i2c_idx 为IIC硬件设备枚举,定义在” \vendor\hisi\hi3861\hi3861\include\ hi_i2c.h“内,
typedef enum {
HI_I2C_IDX_0,
HI_I2C_IDX_1,
} hi_i2c_idx;
从此也可以看出HI3861支持两个IIC接口, 此次使用的是IIC0所以初始化的使用使用“HI_I2C_IDX_0“即可。
hi_u32 baudrate为IIC总线速度,一般IIC总线支持10Kbit/s、40Kbit/s、100Kbit/s,此处使用100Kbit/s,填入100000即可。
通过阅读SSD1306的规格书,发现当使用IIC接口时仅支持IIC写操作,因此此次IIC操作仅仅使用了IIC写函数,hi_u32 hi_i2c_write(hi_i2c_idx id,hi_u16 device_addr, const hi_i2c_data *i2c_data),函数原型在“\vendor\hisi\hi3861\hi3861\platform\drivers\i2c\i2c.c”内。
其中函数传入参数解释如下:
hi_i2c_idx id, //IIC硬件设备枚举
hi_u16 device_addr, //IIC设备地址,通过屏规格书跟原理可知地址为0x78
const hi_i2c_data *i2c_data //IIC总线操作定义结构体其中包含读写缓存、读写字节长度等。
hi_i2c_data 结构体定义在“\code-1.0\vendor\hisi\hi3861\hi3861\include\hi_i2c.h“头文内,摘录如下:
/**
*@ingroup iot_i2c
*
*I2C TX/RX data descriptor. CNcomment:I2C发送/接收数据描述符。CNend
*/
typedef struct {
hi_u8* send_buf; /**< Data TX pointer. The user needsto ensure that no null pointer is transferred.
CNcomment:数据发送指针CNend */
hi_u32 send_len; /**< Length of sent data (unit:byte).
CNcomment:发送数据长度(单位:byte)CNend */
hi_u8* receive_buf; /**< Data RX pointer. CNcomment:数据接收指针CNend */
hi_u32 receive_len; /**< Length of received data (unit:byte).
CNcomment:接收数据长度(单位:byte)CNend */
} hi_i2c_data;
4、向OLED写数据的时候,要先写控制字,表明下边要写的字节是命令还是数据,通过SSD1306规格书内的描述即可确定,如下图所示。按照规格书内启动顺序配置各个寄存器值,寄存器配置请注意行列反转显示均要启用,否则图像会旋转180度。
5、通过SSD1306规格书可以得知,字母取模的时候需要按照从左到右下高位取模方式。附件代码内有16x8字模文件。
三、编译测试
编译测试不多说了,下载后OLED显示内容如下图: