电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
基于鸿蒙OS移植OLED驱动程序
分 享
扫描二维码分享
基于鸿蒙OS移植OLED驱动程序
Harmony
鸿蒙
Hi3861
嵌入式从0到1
关注
发布时间: 2020-10-28
丨
阅读: 2507
### 硬件连接 ![](http://www.xiaohage.com/wp-content/uploads/2020/10/17655_1-1024x664.png) 通过万用表测量,得到I2C总线的OLED屏的引脚连接情况如上图所示,对比原理图,OLED屏幕的I2C总线使用到的是I2C0,SDA引脚对应GPIO13,SCL引脚对应GPIO14。 ![](http://www.xiaohage.com/wp-content/uploads/2020/10/17659_1-1024x616.png) | **OLED** | **Hi3861最小系统板** | **说明** | | :---: | :---: | :--- | | GND | GND | | | VCC | 3V3 | | | SCL | I2C0_SCL | GPIO14 | | SDA | I2C0_SDA | GPIO13 | ### 引脚映射 引脚映射定义的位置如下所示: ![](http://www.xiaohage.com/wp-content/uploads/2020/10/17667_1-1024x618.png) ```C /@@* I2C MUX: */ #ifdef CONFIG_I2C_SUPPORT /@@* The I2C I/O multiplexing mode can also be 3/4 or 9/10 based on the product design. */ hi_io_set_func(HI_IO_NAME_GPIO_0, HI_IO_FUNC_GPIO_0_I2C1_SDA); hi_io_set_func(HI_IO_NAME_GPIO_1, HI_IO_FUNC_GPIO_1_I2C1_SCL); #endif ``` 文件所在路径: vendor\hisi\hi3861\hi3861\app\wifiiot_app\init\app_io_init.c └── vendor └── hisi └── hi3861 └── hi3861 └── app └── wifiiot_app └── app_io_init.c 同时要把支持I2C的宏定义打开,该宏定义所在位置为: ```C CONFIG_I2C_SUPPORT=y ``` vendor\hisi\hi3861\hi3861\build\config\usr_config.mk 修改为如下: ![](http://www.xiaohage.com/wp-content/uploads/2020/10/17669_1.png) ### OLED驱动移植 我们之前分享过使用STM32驱动SPI总线的0.96寸OLED屏,网文链接如下: [STM32驱动0.96寸OLED液晶屏](https://mp.weixin.qq.com/s/Wd-wpGl8F4ssu7X4po_bPw) [OLED液晶屏如何显示中文呢?](https://mp.weixin.qq.com/s/Xr3RpYrVL5kyH-eTP0Skyg) 今天我们在上面的基础上,完成鸿蒙OS对OLED的驱动。 (1)拷贝文件 将原工程目录HARDWARE目录下的OLED文件夹整体拷贝到鸿蒙系统的如下路径下: └── applications └── sample └── wifi-iot └── app 拷贝的OLED文件夹: ![](http://www.xiaohage.com/wp-content/uploads/2020/10/17671_1.png) 拷贝完毕,鸿蒙OS下工程目录结构如下: ![](http://www.xiaohage.com/wp-content/uploads/2020/10/17294_0-1024x710.png) (2)封装I2C操作函数 因为之前分享的网文是SPI总线与SSD1306控制器交互,这回改成了I2C总线,所以我们要重写下面的封装函数: ```C void OLED_WR_Byte(uint8_t dat,uint8_t cmd) ``` 具体实现如下: ```C //向SSD1106写入一个字节。 //dat:要写入的数据/命令 //cmd:数据/命令标志 0,表示命令;1,表示数据; void OLED_WR_Byte(uint8_t dat,uint8_t cmd) { hi_u8 m_send_data[2] = { 0 }; hi_u32 status; hi_i2c_data hi3861_i2c_data = { 0 }; if(cmd) { m_send_data[0] = 0x40; } else { m_send_data[0] = 0x00; } m_send_data[1] = dat; hi3861_i2c_data.send_buf = m_send_data; hi3861_i2c_data.send_len = 2; status = hi_i2c_write(HI_I2C_IDX_0, 0x78, &hi3861_i2c_data); if (status != HI_ERR_SUCCESS) { printf("===== Error: I2C write status = 0x%x! =====\r\n", status); return; } } ``` (3)修改OLED_Init函数 修改OLED_Init函数,删除STM32 GPIO初始化代码,修改后的代码如下所示: ```C void OLED_Init(void) { OLED_WR_Byte(0xAE,OLED_CMD); //--turn off oled panel OLED_WR_Byte(0x00,OLED_CMD); //---set low column address OLED_WR_Byte(0x10,OLED_CMD); //---set high column address OLED_WR_Byte(0x40,OLED_CMD); //--set start line address Set Mapping RAM Display Start Line (0x00~0x3F) OLED_WR_Byte(0x81,OLED_CMD); //--set contrast control register OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness OLED_WR_Byte(0xA1,OLED_CMD); //--Set SEG/Column Mapping 0xa0左右反置 0xa1正常 OLED_WR_Byte(0xC8,OLED_CMD); //Set COM/Row Scan Direction 0xc0上下反置 0xc8正常 OLED_WR_Byte(0xA6,OLED_CMD); //--set normal display OLED_WR_Byte(0xA8,OLED_CMD); //--set multiplex ratio(1 to 64) OLED_WR_Byte(0x3f,OLED_CMD); //--1/64 duty OLED_WR_Byte(0xD3,OLED_CMD); //-set display offset Shift Mapping RAM Counter (0x00~0x3F) OLED_WR_Byte(0x00,OLED_CMD); //-not offset OLED_WR_Byte(0xd5,OLED_CMD); //--set display clock divide ratio/oscillator frequency OLED_WR_Byte(0x80,OLED_CMD); //--set divide ratio, Set Clock as 100 Frames/Sec OLED_WR_Byte(0xD9,OLED_CMD); //--set pre-charge period OLED_WR_Byte(0xF1,OLED_CMD); //Set Pre-Charge as 15 Clocks & Discharge as 1 Clock OLED_WR_Byte(0xDA,OLED_CMD); //--set com pins hardware configuration OLED_WR_Byte(0x12,OLED_CMD); OLED_WR_Byte(0xDB,OLED_CMD); //--set vcomh OLED_WR_Byte(0x40,OLED_CMD); //Set VCOM Deselect Level OLED_WR_Byte(0x20,OLED_CMD); //-Set Page Addressing Mode (0x00/0x01/0x02) OLED_WR_Byte(0x02,OLED_CMD); // OLED_WR_Byte(0x8D,OLED_CMD); //--set Charge Pump enable/disable OLED_WR_Byte(0x14,OLED_CMD); //--set(0x10) disable OLED_WR_Byte(0xA4,OLED_CMD); // Disable Entire Display On (0xa4/0xa5) OLED_WR_Byte(0xA6,OLED_CMD); // Disable Inverse Display On (0xa6/a7) OLED_WR_Byte(0xAF,OLED_CMD); //--turn on oled panel OLED_WR_Byte(0xAF,OLED_CMD); /@@*display ON*/ OLED_Clear(); OLED_Set_Pos(0,0); } ``` (4)入口函数 将之前STM32工程的main函数改名为:void OLED_Demo(void) ,放置在oled.c文件底部,作为入口函数,该函数的具体实现如下所示: ``` void OLED_Demo(void) { //初始化 hi_i2c_init(HI_I2C_IDX_0, 100000); OLED_Init(); OLED_Clear(); for(i=0;i<8;i++) { OLED_ShowCHinese(i*16,0,i+0); } for(i=0;i<7;i++) { OLED_ShowCHinese(i*16,2,i+8); } for(i=0;i<4;i++) { OLED_ShowCHinese(i*16,4,i+15); } for(i=0;i<4;i++) { OLED_ShowCHinese(i*16,6,i+19); } } #endif SYS_RUN(OLED_Demo); ``` (5)oled.h文件中删除STM32相关代码 (6)编译验证 1. 修改BUILD.gn文件: * OLED文件夹下面的BUILD.gn文件修改如下: ```C static_library("OLED_Demo") { sources = [ "oled.c" ] include_dirs = [ "//utils/native/lite/include", "//kernel/liteos_m/components/cmsis/2.0", ] } ``` * 上级目录(即app文件夹)下的BUILD.gn文件修改如下: ```C lite_component("app") { features = [ #"startup", "oled:OLED_Demo" ] } ``` 2. 编译并下载 ![](http://www.xiaohage.com/wp-content/uploads/2020/10/17290_0.png) 编译和下载固件参考下面网文操作: [**鸿蒙系统固件编译及烧写——通过AT命令完成WLAN模组Hi3861联网**](https://mp.weixin.qq.com/s/S_oI5iPG8G1xcg-DNAJeDw) ### 结果展示 ![](http://www.xiaohage.com/wp-content/uploads/2020/10/17292_0-1024x721.png) 上图可以正常显示文字,证明鸿蒙OS驱动OLED移植成功,由上可以看出整个移植过程还是比较简单的,只需要将OLED_WR_Byte函数改写即可完成此部分工作,主控芯片换成其他芯片,比如51单片机、msp430等等移植方法都是类似的,大家可以试试哈。 ### 资料获取 公众号**留言区置顶留言**获取本文相关代码。 ps: 文章首发于电子发烧友。 ### 欢迎关注 程序员小哈带你玩转嵌入式,微信搜索:**嵌入式从0到1**,更多干货等着你。
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
嵌入式从0到1
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交