硬件连接通过万用表测量,得到I2C总线的OLED屏的引脚连接情况如上图所示,对比原理图,OLED屏幕的I2C总线使用到的是I2C0,SDA引脚对应GPIO13,SCL引脚对应GPIO14。
OLEDHi3861最小系统板备注
GNDGND
VCC3V3
SCLI2C0_SCLGPIO14
SDAI2C0_SDAGPIO13
引脚映射引脚映射定义的位置如下所示:
/* 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
文件所在路径:vendorhisihi3861hi3861appwifiiot_appinitapp_io_init.c
└── vendor
└── hisi
└── hi3861
└── hi3861
└── app
└── wifiiot_app
└── app_io_init.c
同时要把支持I2C的宏定义打开,该宏定义所在位置为:
CONFIG_I2C_SUPPORT=y
vendorhisihi3861hi3861buildconfigusr_config.mk
修改为如下:
OLED驱动移植我们之前分享过使用STM32驱动SPI总线的0.96寸OLED屏,网文链接如下:
STM32驱动0.96寸OLED液晶屏
OLED液晶屏如何显示中文呢?
今天我们在上面的基础上,完成鸿蒙OS对OLED的驱动。
(1)拷贝文件
将原工程目录HARDWARE目录下的OLED文件夹整体拷贝到鸿蒙系统的如下路径下:
└── applications
└── sample
└── wifi-iot
└── app
拷贝的OLED文件夹:
拷贝完毕,鸿蒙OS下工程目录结构如下:
(2)封装I2C操作函数
因为之前分享的网文是SPI总线与SSD1306控制器交互,这回改成了I2C总线,所以我们要重写下面的封装函数:
void OLED_WR_Byte(uint8_t dat,uint8_t cmd)
具体实现如下:
//向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); //0x78为模块的默认地址
if (status != HI_ERR_SUCCESS) {
printf("===== Error: I2C write status = 0x%x! =====rn", status);
return;
}
}
(3)修改OLED_Init函数
修改OLED_Init函数,删除STM32 GPIO初始化代码,修改后的代码如下所示:
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();
//OLED_ShowString(0,4,(u8 *)" 0.96 OLED Demo ");
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);
}
}
SYS_RUN(OLED_Demo);
(5)oled.h文件中删除STM32相关代码
(6)编译验证
- OLED文件夹下面的BUILD.gn文件修改如下:
static_library("OLED_Demo") {
sources = [
"oled.c"
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
]
}
- 上级目录(即app文件夹)下的BUILD.gn文件修改如下:
lite_component("app") {
features = [
#"startup",
"oled:OLED_Demo"
]
}
编译和下载固件参考下面网文操作:
鸿蒙系统固件编译及烧写——通过AT命令完成WLAN模组Hi3861联网
结果展示上图可以正常显示文字,证明鸿蒙OS驱动OLED移植成功,由上可以看出整个移植过程还是比较简单的,只需要将OLED_WR_Byte函数改写即可完成此部分工作,主控芯片换成其他芯片,比如51单片机、msp430等等移植方法都是类似的,大家可以试试哈。
资料获取公众号留言区置顶留言获取本文相关代码。
ps: 文章首发于电子发烧友。
欢迎关注程序员小哈带你玩转嵌入式,微信搜索:嵌入式从0到1,更多干货等着你。