[]【HarmonyOS HiSpark Wi-Fi IoT 套件试用连连载】基于鸿蒙OS移植OLED驱动程序

阅读量0
0
0
硬件连接
通过万用表测量,得到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)编译验证
  • 修改BUILD.gn文件:
  • 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,更多干货等着你。


回帖

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
链接复制成功,分享给好友