基于RVB2601的GUI程序是利用Lvgl开源组件实现在OLED屏幕上的字符和图形显示。开发者可以利用Lvgl组件在OLED屏幕上实现Label控件显示功能。
建议在看本文之前 先详细看下RVB2601资源。本例程名为ch2601_gui_demo 可以通过CDK直接从OCC拉取。
2. 硬件配置2.1 显示屏RVB2601开发板采用的是OLED显示屏 位于开发板正面。
2.2 屏幕物理接口CH2601开发板采用单彩色图形显示面板 屏幕分辨率128x64 pixel 屏幕背景颜色可选 该程序中采用的是一块黄色背景的屏幕。屏幕控制器采用SSD1309 通过4 wire SPI接口与主芯片连接, 原理图如下所示, 对应的pin引脚分别为PA27、PA28、PA29、PA30。 原理图如下
软件通过对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 协议支持MicroPython3.2 例程下载打开CDK 点击HOME图标 查找ch2601_gui_demo后 打开工程可以看到以下目录
3.3 LVGL移植接口Lvgl移植代码位于app/src/lvgl_porting文件夹内 其包含oled.c和oled.h。
以下功能接口位于app/src/lvgl_porting/oled.c 实现SPI管脚的初始化 主要针对CS, DATA, CLOCK, DATAIN管脚 同时实现了对不同管脚的读写操作。1. static void oled_gpio_init() 3. // 4. csi_gpio_pin_init( pin_clk, PA28); 5. csi_gpio_pin_dir( pin_clk, GPIO_DIRECTION_OUTPUT); 6. csi_gpio_pin_init( pin_mosi, PA29); 7. csi_gpio_pin_dir( pin_mosi, GPIO_DIRECTION_OUTPUT); 8. csi_gpio_pin_init( pin_cs, PA27); 9. csi_gpio_pin_dir( pin_cs, GPIO_DIRECTION_OUTPUT); 10. csi_gpio_pin_init( pin_miso, PA30); //dc 11. csi_gpio_pin_dir( pin_miso, GPIO_DIRECTION_OUTPUT); 12. } 14. static void lcd_cs(uint8_t d) 15. { 16. if (d 1) { 17. csi_gpio_pin_write( pin_cs, GPIO_PIN_HIGH); 18. } else { 19. csi_gpio_pin_write( pin_cs, GPIO_PIN_LOW); 20. } 21. } 23. static void lcd_dc(uint8_t d) 24. { 25. if (d 1) { 26. csi_gpio_pin_write( pin_miso, GPIO_PIN_HIGH); 27. } else { 28. csi_gpio_pin_write( pin_miso, GPIO_PIN_LOW); 29. } 30. } 32. static void lcd_sclk(uint8_t d) 33. { 34. if (d 1) { 35. csi_gpio_pin_write( pin_clk, GPIO_PIN_HIGH); 36. } else { 37. csi_gpio_pin_write( pin_clk, GPIO_PIN_LOW); 38. } 39. } 41. static void lcd_sdin(uint8_t d) 42. { 43. if (d 1) { 44. csi_gpio_pin_write( pin_mosi, GPIO_PIN_HIGH); 45. } else { 46. csi_gpio_pin_write( pin_mosi, GPIO_PIN_LOW); 47. } 48. } c以下功能函数位于app/src/lvgl_porting/oled.c 通过SPI实现对屏幕的命令和数据写操作。
1. void Write_Command(unsigned char Data) 3. unsigned char i; 5. lcd_cs(0); 6. lcd_dc(0); 7. for (i i i ) { 8. lcd_sclk(0); 9. lcd_sdin((Data 0x80) 7); 10. Data Data 1; 11. lcd_sclk(1); 12. } 13. lcd_dc(1); 14. lcd_cs(1); 15. } 17. void Write_Data(unsigned char Data) 18. { 19. unsigned char i; 21. lcd_cs(0); 22. lcd_dc(1); 23. for (i i i ) { 24. lcd_sclk(0); 25. lcd_sdin((Data 0x80) 7); 26. Data Data 1; 27. lcd_sclk(1); 28. } 29. lcd_dc(1); 30. lcd_cs(1); 31. } c以下功能函数位于app/src/lvgl_porting/oled.c文件中 实现对屏幕的基本命令操作 例如设置屏幕行列地址 屏幕的亮度控制等。
1. void Set_Start_Column(unsigned char d) 3. Write_Command(0x00 d % 16); // Set Lower Column Start Address for Page Addressing Mode 4. // Default 0x00 5. Write_Command(0x10 d / 16); // Set Higher Column Start Address for Page Addressing Mode 6. // Default 0x10 9. void Set_Addressing_Mode(unsigned char d) 10. { 11. Write_Command(0x20); // Set Memory Addressing Mode 12. Write_Command(d); // Default 0x02 13. // 0x00 Horizontal Addressing Mode 14. // 0x01 Vertical Addressing Mode 15. // 0x02 Page Addressing Mode 16. } 18. void Set_Column_Address(unsigned char a, unsigned char b) 19. { 20. Write_Command(0x21); // Set Column Address 21. Write_Command(a); // Default 0x00 (Column Start Address) 22. Write_Command(b); // Default 0x7F (Column End Address) 23. } 25. void Set_Page_Address(unsigned char a, unsigned char b) 26. { 27. Write_Command(0x22); // Set Page Address 28. Write_Command(a); // Default 0x00 (Page Start Address) 29. Write_Command(b); // Default 0x07 (Page End Address) 30. } 32. void Set_Start_Line(unsigned char d) 33. { 34. Write_Command(0x40 | d); // Set Display Start Line 35. // Default 0x40 (0x00) 36. } 38. void Set_Contrast_Control(unsigned char d) 39. { 40. Write_Command(0x81); // Set Contrast Control for Bank 0 41. Write_Command(d); // Default 0x7F 42. } 44. void Set_Segment_Remap(unsigned char d) 45. { 46. Write_Command(d); // Set Segment Re-Map 47. // Default 0xA0 48. // 0xA0 Column Address 0 Mapped to SEG0 49. // 0xA1 Column Address 0 Mapped to SEG127 50. } 52. void Set_Entire_Display(unsigned char d) 53. { 54. Write_Command(d); // Set Entire Display On / Off 55. // Default 0xA4 56. // 0xA4 Normal Display 57. // 0xA5 Entire Display On 58. } 60. void Set_Inverse_Display(unsigned char d) 61. { 62. Write_Command(d); // Set Inverse Display On/Off 63. // Default 0xA6 64. // 0xA6 Normal Display 65. // 0xA7 Inverse Display On 66. } 68. void Set_Multiplex_Ratio(unsigned char d) 69. { 70. Write_Command(0xA8); // Set Multiplex Ratio 71. Write_Command(d); // Default 0x3F (1/64 Duty) 72. } 74. void Set_Display_On_Off(unsigned char d) 75. { 76. Write_Command(d); // Set Display On/Off 77. // Default 0xAE 78. // 0xAE Display Off 79. // 0xAF Display On 80. } 82. void Set_Start_Page(unsigned char d) 83. { 84. Write_Command(0xB0 | d); // Set Page Start Address for Page Addressing Mode 85. // Default 0xB0 (0x00) 86. } 88. void Set_Common_Remap(unsigned char d) 89. { 90. Write_Command(d); // Set COM Output Scan Direction 91. // Default 0xC0 92. // 0xC0 Scan from COM0 to 63 93. // 0xC8 Scan from COM63 to 0 94. } 96. void Set_Display_Offset(unsigned char d) 97. { 98. Write_Command(0xD3); // Set Display Offset 99. Write_Command(d); // Default 0x00 100. } 101. 102. void Set_Display_Clock(unsigned char d) 103. { 104. Write_Command(0xD5); // Set Display Clock Divide Ratio / Oscillator Frequency 105. Write_Command(d); // Default 0x70 106. // D[3:0] Display Clock Divider 107. // D[7:4] Oscillator Frequency 108. } 109. 110. void Set_Low_Power(unsigned char d) 111. { 112. Write_Command(0xD8); // Set Low Power Display Mode 113. Write_Command(d); // Default 0x04 (Normal Power Mode) 114. } 115. 116. void Set_Precharge_Period(unsigned char d) 117. { 118. Write_Command(0xD9); // Set Pre-Charge Period 119. Write_Command(d); // Default 0x22 (2 Display Clocks [Phase 2] / 2 Display Clocks [Phase 1]) 120. // D[3:0] Phase 1 Period in 1~15 Display Clocks 121. // D[7:4] Phase 2 Period in 1~15 Display Clocks 122. } 123. 124. void Set_Common_Config(unsigned char d) 125. { 126. Write_Command(0xDA); // Set COM Pins Hardware Configuration 127. Write_Command(d); // Default 0x12 128. // Alternative COM Pin Configuration 129. // Disable COM Left/Right Re-Map 130. } 131. 132. void Set_NOP() 133. { 134. Write_Command(0xE3); // Command for No Operation 135. } 136. 137. void Set_Command_Lock(unsigned char d) 138. { 139. Write_Command(0xFD); // Set Command Lock 140. Write_Command(d); // Default 0x12 141. // 0x12 Driver IC interface is unlocked from entering command. 142. // 0x16 All Commands are locked except 0xFD. 143. } c该功能函数位于app/src/lvgl_porting/oled.c文件中 实现对屏幕的初始化。
1. static void oled_initialize() 3. Set_Command_Lock(0x12); // Unlock Driver IC (0x12/0x16) 4. Set_Display_On_Off(0xAE); // Display Off (0xAE/0xAF) 5. Set_Display_Clock(0xA0); // Set Clock as 116 Frames/Sec 6. Set_Multiplex_Ratio(0x3F); // 1/64 Duty (0x0F~0x3F) 7. Set_Display_Offset(0x00); // Shift Mapping RAM Counter (0x00~0x3F) 8. Set_Start_Line(0x00); // Set Mapping RAM Display Start Line (0x00~0x3F) 9. Set_Low_Power(0x04); // Set Normal Power Mode (0x04/0x05) 10. Set_Addressing_Mode(0x02); // Set Page Addressing Mode (0x00/0x01/0x02) 11. Set_Segment_Remap(0xA1); // Set SEG/Column Mapping (0xA0/0xA1) 12. Set_Common_Remap(0xC8); // Set COM/Row Scan Direction (0xC0/0xC8) 13. Set_Common_Config(0x12); // Set Alternative Configuration (0x02/0x12) 14. Set_Contrast_Control(Brightness); // Set SEG Output Current 15. Set_Precharge_Period(0x82); // Set Pre-Charge as 8 Clocks Discharge as 2 Clocks 16. Set_VCOMH(0x34); // Set VCOM Deselect Level 17. Set_Entire_Display(0xA4); // Disable Entire Display On (0xA4/0xA5) 18. Set_Inverse_Display(0xA6); // Disable Inverse Display On (0xA6/0xA7) 20. Fill_RAM(0x00); // Clear Screen 22. Set_Display_On_Off(0xAF); // Display On (0xAE/0xAF) 23. } c该功能函数位于app/src/main.c文件中 实现在屏幕固定处画一个label, 显示一串字符串。
1. static void gui_label_create(void) 3. lv_obj_t *p lv_label_create(lv_scr_act(), NULL); 4. lv_label_set_long_mode(p, LV_LABEL_LONG_BREAK); 5. lv_label_set_align(p, LV_LABEL_ALIGN_CENTER); 6. lv_obj_set_pos(p, 0, 4); 7. lv_obj_set_size(p, 128, 60); 8. lv_label_set_text(p, THEAD RISC-V\nGUI\nDEMO c3.4. 编译运行
编译通过后 点击下载 下载成功后复位运行。可看屏上显示 THEAD RISC-V\nGUI\nDEMO 字符串。
4. 总结本例程介绍了如何通过SPI接口来实现对OLED屏幕的图形显示。后续还有更多的开发例程 敬请期待
云虚拟主机 可以干什么?云 虚拟主机 可以是搭 建网站 的重要产品,可用来存放网...
API风格说明 当前ECS服务对外开放两类风格的API: ECS服务自定义规范的API(以下...
客户简介 全民直播是一家涵盖游戏、娱乐、户外等多领域泛娱乐的直播平台。2015年...
??提到慕尼黑,大家第一个想到总是啤酒节,其实慕尼黑的文化同样闻名世界。慕尼...
排查思路 无法通过远程桌面连接裸金属服务器时,我们推荐您按照以下思路排查问题...
公司介绍 我们公司是全球法律服务整合平台,已有的4万多名律师遍布全国359个城市...
案例背景 高校健康打卡项目发起于北京大学软件与微电子学院,是该学院张齐勋老师...
客户简介 趣医网(quyiyuan.com)创立于2014年,为京颐集团重要成员企业之一,是...
注册了 域名 不备案可以吗?可以的。 注册域名 并不是一定要备案的,只有搭 建网...
3月24日,腾讯发布2020年Q4及全年财报,其中金融科技及企业服务第四季收入385亿...