RVB2601应用开发实战系列三: GUI图形显示

news/2024/11/6 23:23:22/

关键词:RISC-V开发板、RVB2601、WiFi&BLE,低功耗,玄铁E906,AliOS Things,RISC-V  MCU,上手 好用,控制,开关

1. 前言

基于RVB2601的GUI程序是利用Lvgl开源组件实现在OLED屏幕上的字符和图形显示。开发者可以利用Lvgl组件在OLED屏幕上实现Label控件显示功能。

建议在看本文之前,先详细看下RVB2601资源。本例程名为ch2601_gui_demo,可以通过CDK直接从OCC拉取。

2. 硬件配置

2.1 显示屏

RVB2601开发板采用的是OLED显示屏, 位于开发板正面。

https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/userFiles/3773052466552311808/postdetail/1618319511173/6c34263c82364cacdcb6360403ab9339.png

2.2 屏幕物理接口

CH2601开发板采用单彩色图形显示面板,屏幕分辨率128x64 pixel,屏幕背景颜色可选,该程序中采用的是一块黄色背景的屏幕。屏幕控制器采用SSD1309,通过4 wire SPI接口与主芯片连接, 原理图如下所示, 对应的pin引脚分别为PA27、PA28、PA29、PA30。 原理图如下: 

https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/userFiles/3773052466552311808/postdetail/1618319629675/d0af0a9eaab28b62f62a03776b613014.png

软件通过对SPI进行读写操作来实现对OLED屏上的像素进行点操作,从而实现整个屏的点亮操作。

3. GUI软件开发

3.1 LVGL介绍

LVGL全称Light and Versatile Graphics Library,是一个自由的,开源的GUI库,具有界面精美,资源消耗小,可移植度高, 响应式布局等特点, 全库采用纯 c 语言开发.

主要特性如下.

  • 具有非常丰富的内置控件,像 buttons, charts, lists, sliders, images 等
  • 高级图形效果:动画,反锯齿,透明度,平滑滚动
  • 支持多种输入设备,像 touchpad, mouse, keyboard, encoder 等
  • 支持多语言的 UTF-8 编码
  • 支持多个和多种显示设备,例如同步显示在多个彩色屏或单色屏上
  • 完全自定制的图形元素
  • 硬件独立于任何微控制器或显示器
  • 可以缩小到最小内存 (64 kB Flash, 16 kB RAM)
  • 支持操作系统、外部储存和 GPU(非必须)
  • 仅仅单个帧缓冲设备就可以呈现高级视觉特效
  • 使用 C 编写以获得最大兼容性(兼容 C++)
  • 支持 PC 模拟器
  • 为加速 GUI 设计,提供教程,案例和主题,支持响应式布局
  • 提供了在线和离线文档
  • 基于自由和开源的 MIT 协议
  • 支持MicroPython

3.2 例程下载

打开CDK,点击HOME图标,查找ch2601_gui_demo后,打开工程可以看到以下目录:

 

https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/userFiles/3773052466552311808/postdetail/1618319687941/d37162e0e4ccf026478c9e0bc8922c0d.png

3.3 LVGL移植接口

Lvgl移植代码位于app/src/lvgl_porting文件夹内,其包含oled.c和oled.h。

https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/userFiles/3773052466552311808/postdetail/1618319816837/6d6238144585c75a448026c84429b540.png

  • 以下功能接口位于app/src/lvgl_porting/oled.c, 实现SPI管脚的初始化,主要针对CS, DATA, CLOCK, DATAIN管脚,同时实现了对不同管脚的读写操作。
static void oled_gpio_init()
{//csi_gpio_pin_init(&pin_clk, PA28);csi_gpio_pin_dir(&pin_clk, GPIO_DIRECTION_OUTPUT);csi_gpio_pin_init(&pin_mosi, PA29);csi_gpio_pin_dir(&pin_mosi, GPIO_DIRECTION_OUTPUT);csi_gpio_pin_init(&pin_cs, PA27);csi_gpio_pin_dir(&pin_cs, GPIO_DIRECTION_OUTPUT);csi_gpio_pin_init(&pin_miso, PA30); //dccsi_gpio_pin_dir(&pin_miso, GPIO_DIRECTION_OUTPUT);
}static void lcd_cs(uint8_t d)
{if (d == 1) {csi_gpio_pin_write(&pin_cs, GPIO_PIN_HIGH);} else {csi_gpio_pin_write(&pin_cs, GPIO_PIN_LOW);}
}static void lcd_dc(uint8_t d)
{if (d == 1) {csi_gpio_pin_write(&pin_miso, GPIO_PIN_HIGH);} else {csi_gpio_pin_write(&pin_miso, GPIO_PIN_LOW);}
}static void lcd_sclk(uint8_t d)
{if (d == 1) {csi_gpio_pin_write(&pin_clk, GPIO_PIN_HIGH);} else {csi_gpio_pin_write(&pin_clk, GPIO_PIN_LOW);}
}static void lcd_sdin(uint8_t d)
{if (d == 1) {csi_gpio_pin_write(&pin_mosi, GPIO_PIN_HIGH);} else {csi_gpio_pin_write(&pin_mosi, GPIO_PIN_LOW);}
}

  • 以下功能函数位于app/src/lvgl_porting/oled.c,通过SPI实现对屏幕的命令和数据写操作。
void Write_Command(unsigned char Data)
{unsigned char i;lcd_cs(0);lcd_dc(0);for (i = 0; i < 8; i++) {lcd_sclk(0);lcd_sdin((Data & 0x80) >> 7);Data = Data << 1;lcd_sclk(1);}lcd_dc(1);lcd_cs(1);
}void Write_Data(unsigned char Data)
{unsigned char i;lcd_cs(0);lcd_dc(1);for (i = 0; i < 8; i++) {lcd_sclk(0);lcd_sdin((Data & 0x80) >> 7);Data = Data << 1;lcd_sclk(1);}lcd_dc(1);lcd_cs(1);
}

  • 以下功能函数位于app/src/lvgl_porting/oled.c文件中,实现对屏幕的基本命令操作,例如设置屏幕行列地址,屏幕的亮度控制等。
void Set_Start_Column(unsigned char d)
{Write_Command(0x00 + d % 16); // Set Lower Column Start Address for Page Addressing Mode//   Default => 0x00Write_Command(0x10 + d / 16); // Set Higher Column Start Address for Page Addressing Mode//   Default => 0x10
}void Set_Addressing_Mode(unsigned char d)
{Write_Command(0x20); // Set Memory Addressing ModeWrite_Command(d);    //   Default => 0x02//     0x00 => Horizontal Addressing Mode//     0x01 => Vertical Addressing Mode//     0x02 => Page Addressing Mode
}void Set_Column_Address(unsigned char a, unsigned char b)
{Write_Command(0x21); // Set Column AddressWrite_Command(a);    //   Default => 0x00 (Column Start Address)Write_Command(b);    //   Default => 0x7F (Column End Address)
}void Set_Page_Address(unsigned char a, unsigned char b)
{Write_Command(0x22); // Set Page AddressWrite_Command(a);    //   Default => 0x00 (Page Start Address)Write_Command(b);    //   Default => 0x07 (Page End Address)
}void Set_Start_Line(unsigned char d)
{Write_Command(0x40 | d); // Set Display Start Line//   Default => 0x40 (0x00)
}void Set_Contrast_Control(unsigned char d)
{Write_Command(0x81); // Set Contrast Control for Bank 0Write_Command(d);    //   Default => 0x7F
}void Set_Segment_Remap(unsigned char d)
{Write_Command(d); // Set Segment Re-Map//   Default => 0xA0//     0xA0 => Column Address 0 Mapped to SEG0//     0xA1 => Column Address 0 Mapped to SEG127
}void Set_Entire_Display(unsigned char d)
{Write_Command(d); // Set Entire Display On / Off//   Default => 0xA4//     0xA4 => Normal Display//     0xA5 => Entire Display On
}void Set_Inverse_Display(unsigned char d)
{Write_Command(d); // Set Inverse Display On/Off//   Default => 0xA6//     0xA6 => Normal Display//     0xA7 => Inverse Display On
}void Set_Multiplex_Ratio(unsigned char d)
{Write_Command(0xA8); // Set Multiplex RatioWrite_Command(d);    //   Default => 0x3F (1/64 Duty)
}void Set_Display_On_Off(unsigned char d)
{Write_Command(d); // Set Display On/Off//   Default => 0xAE//     0xAE => Display Off//     0xAF => Display On
}void Set_Start_Page(unsigned char d)
{Write_Command(0xB0 | d); // Set Page Start Address for Page Addressing Mode//   Default => 0xB0 (0x00)
}void Set_Common_Remap(unsigned char d)
{Write_Command(d); // Set COM Output Scan Direction//   Default => 0xC0//     0xC0 => Scan from COM0 to 63//     0xC8 => Scan from COM63 to 0
}void Set_Display_Offset(unsigned char d)
{Write_Command(0xD3); // Set Display OffsetWrite_Command(d);    //   Default => 0x00
}void Set_Display_Clock(unsigned char d)
{Write_Command(0xD5); // Set Display Clock Divide Ratio / Oscillator FrequencyWrite_Command(d);    //   Default => 0x70//     D[3:0] => Display Clock Divider//     D[7:4] => Oscillator Frequency
}void Set_Low_Power(unsigned char d)
{Write_Command(0xD8); // Set Low Power Display ModeWrite_Command(d);    //   Default => 0x04 (Normal Power Mode)
}void Set_Precharge_Period(unsigned char d)
{Write_Command(0xD9); // Set Pre-Charge PeriodWrite_Command(d); //   Default => 0x22 (2 Display Clocks [Phase 2] / 2 Display Clocks [Phase 1])//     D[3:0] => Phase 1 Period in 1~15 Display Clocks//     D[7:4] => Phase 2 Period in 1~15 Display Clocks
}void Set_Common_Config(unsigned char d)
{Write_Command(0xDA); // Set COM Pins Hardware ConfigurationWrite_Command(d);    //   Default => 0x12//     Alternative COM Pin Configuration//     Disable COM Left/Right Re-Map
}void Set_NOP()
{Write_Command(0xE3); // Command for No Operation
}void Set_Command_Lock(unsigned char d)
{Write_Command(0xFD); // Set Command LockWrite_Command(d);    //   Default => 0x12//     0x12 => Driver IC interface is unlocked from entering command.//     0x16 => All Commands are locked except 0xFD.
}

  • 该功能函数位于app/src/lvgl_porting/oled.c文件中,实现对屏幕的初始化。
static void oled_initialize()
{Set_Command_Lock(0x12);           // Unlock Driver IC (0x12/0x16)Set_Display_On_Off(0xAE);         // Display Off (0xAE/0xAF)Set_Display_Clock(0xA0);          // Set Clock as 116 Frames/SecSet_Multiplex_Ratio(0x3F);        // 1/64 Duty (0x0F~0x3F)Set_Display_Offset(0x00);         // Shift Mapping RAM Counter (0x00~0x3F)Set_Start_Line(0x00);             // Set Mapping RAM Display Start Line (0x00~0x3F)Set_Low_Power(0x04);              // Set Normal Power Mode (0x04/0x05)Set_Addressing_Mode(0x02);        // Set Page Addressing Mode (0x00/0x01/0x02)Set_Segment_Remap(0xA1);          // Set SEG/Column Mapping (0xA0/0xA1)Set_Common_Remap(0xC8);           // Set COM/Row Scan Direction (0xC0/0xC8)Set_Common_Config(0x12);          // Set Alternative Configuration (0x02/0x12)Set_Contrast_Control(Brightness); // Set SEG Output CurrentSet_Precharge_Period(0x82);       // Set Pre-Charge as 8 Clocks & Discharge as 2 ClocksSet_VCOMH(0x34);                  // Set VCOM Deselect LevelSet_Entire_Display(0xA4);         // Disable Entire Display On (0xA4/0xA5)Set_Inverse_Display(0xA6);        // Disable Inverse Display On (0xA6/0xA7)Fill_RAM(0x00); // Clear ScreenSet_Display_On_Off(0xAF); // Display On (0xAE/0xAF)
}

  • 该功能函数位于app/src/main.c文件中,实现在屏幕固定处画一个label, 显示一串字符串。
static void gui_label_create(void)
{lv_obj_t *p = lv_label_create(lv_scr_act(), NULL);lv_label_set_long_mode(p, LV_LABEL_LONG_BREAK);lv_label_set_align(p, LV_LABEL_ALIGN_CENTER);lv_obj_set_pos(p, 0, 4);lv_obj_set_size(p, 128, 60);lv_label_set_text(p, "THEAD RISC-V\nGUI\nDEMO");
}

3.4. 编译运行

编译通过后,点击下载,下载成功后复位运行。可看屏上显示"THEAD RISC-V\nGUI\nDEMO" 字符串。

https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/userFiles/3773052466552311808/postdetail/1618319856321/6be3dc23ae5bca22762411ddab9dba19.png

4. 总结

本例程介绍了如何通过SPI接口来实现对OLED屏幕的图形显示。后续还有更多的开发例程,敬请期待!

本文转自平头哥芯片开放社区(occ),更多详情请点击【这里】。


http://www.ppmy.cn/news/777170.html

相关文章

深入对比分析SWT、Swing 和 AWT

AWT 概述 Abstract Windows Toolkit&#xff08;AWT&#xff09;是最原始的 Java GUI 工具包。AWT 的主要优点是&#xff0c;它在 Java 技术的每个版本上都成为了一种标准配置&#xff0c;包括早期的 Web 浏览器中的 Java 实现&#xff1b;另外它也非常稳定。这意味着我们不需要…

深入对比分析AWT、Swing和SWT

AWT 概述 Abstract Windows Toolkit&#xff08;AWT&#xff09;是最原始的 Java GUI 工具包。AWT 的主要优点是&#xff0c;它在 Java 技术的每个版本上都成为了一种标准配置&#xff0c;包括早期的 Web 浏览器中的 Java 实现&#xff1b;另外它也非常稳定。这意味着我们不需要…

基于SPI/IIC接口的OLED数据显示和字符滚动

目录 一.OLED和SPI二.OLED数据显示实验要求及准备三.OLED数据显示成果展示四.字符滚动显示五.字符滚动显示成果展示 一.OLED和SPI 1.SPI简介 SPI是串行外设接口(Serial Peripheral Interface)的缩写。是 Motorola公司推出的一种同步串行接口技术&#xff0c;是一种高速的&…

基于单片机八位智能抢答器设计系统-基于单片机LM35温度采集控制-基于单片机HX711电子秤称重-基于单片机16位智能抢答器设计-基于STM32自动售货机控制系统设计-STM32自动售货机控制系统

1642基于单片机八位智能抢答器设计系统报告、仿真、C程序 随着经济和文化事业发展的需要&#xff0c;在很多公开竞争的场合要求有公共的竞争裁决&#xff0c;诸如证券、股票交易及各种竞赛抢答&#xff0c;因此抢答器应运而生。抢答器一般是由很多电路组成的&#xff0c;线路…

【无标题】基于51单片机和DHT11的温湿度检测系统

基于51单片机的温湿度检测系统 摘 要&#xff1a;设计一款能够实时检测当前空气温度和湿度的装置。主控芯片采用STC12C5A60S2芯片&#xff0c;温湿度传感器采用DHT11数字温湿度传感器&#xff0c;显示屏幕采用OLED屏幕。整个设计采用模块化设计&#xff0c;分别为三大模块。分…

SWT、Swing 和 AWT 介绍

简介 developerWorks 上另外一些作者已经展示了如何在 Swing 和 SWT 之间很好地进行迁移&#xff08;参见 参考资料&#xff09;。本文的目标是帮助您在开始开发项目之前确定选择使用哪个 GUI 工具包。 但是首先我们要弄清一个问题&#xff1a;为什么会有多个 Java™ GUI 工…

4线SPI驱动OLED常规操作

拿到一块点阵屏幕&#xff0c;首先找卖家拿驱动例程 步骤 目录 1.void LCD_IO_Cfg(void) 2.void wr_cmd(u8 wrcmd) 3.void wr_data(u8 wrdata) 4.void init_lcd(void) 5.void disp_all(void) 6.void Fresh(void) 注&#xff1a;根据商家的时序图可以知道数据在上升沿/下降…

视频显示系统

引言&#xff1a; 作为消费者&#xff0c;我们对于各种形式的视频系统都已经非常熟悉了。但是从嵌入式开发人员的角度来看&#xff0c;视频就好像是一张纷繁复杂的网络&#xff0c;里面充满了各种不同的分辨率、格式、标准与显示等。 视频显示&#xff1a; 模拟视频显示 视频…