1331|3

337

帖子

2

TA的资源

纯净的硅(初级)

楼主
 

【得捷电子Follow me第4期】扩展U8G2移植支持LCD显示 [复制链接]

  本帖最后由 我爱下载 于 2024-2-22 18:26 编辑
【得捷电子Follow me4期】扩展U8G2移植支持LCD显示

硬件环境

和入门任务的硬件基本环境相同。
 
图1 硬件连接关系图

软件实现

以pico-sdk为基础,利用官方提供的w5500-evb-pico程序框架,添加u8g2的支持。

U8g2源码下载

源码下载地址:
链接已隐藏,如需查看请登录或者注册

 

图2 源码目录结构
其中红色框的部分为u8g2的c语言实现版本,这个就是我们下面需要移植的源码。

U8g2源码移植过程

通过浏览源码可以发现,Adafruit sharp memory display显示模块在支持的行列,这样就比较简单了。
其驱动文件的名称为:u8x8_d_ls013b7dh03.c
复制源码目录下csrc目录到我们的工程目录library下,并修改为u8g2 。
同时修改CmakeLists.txt中的相关配置项,增加对u8g2的支持。
需要分别修改两处CMakeLists.txt文件:

   1.  工程目录下CmakeLists.txt的修改

        增加了两个配置项目,一个为LCD_GUI_DIR目录的定义,另一个为我们测试工程。

cmake_minimum_required(VERSION 3.12)
#set(PICO_SDK_PATH G:\\desktop-backup\\board\\rp2040\\pico-sdk)
#set(PICO_TOOLCHAIN_PATH D:\\arm-gcc\\gcc-arm-none-eabi-10.3-2021.10\\bin)
# Pull in SDK (must be before project)
include(pico_sdk_import.cmake)
project(pico_examples C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
# Initialize the SDK
pico_sdk_init()
set(WIZNET_DIR ${CMAKE_SOURCE_DIR}/library/ioLibrary_Driver)
set(LCD_GUI_DIR ${CMAKE_SOURCE_DIR}/library)
set(PORT_DIR ${CMAKE_SOURCE_DIR}/port)
#add_subdirectory(examples)
add_subdirectory(myprog)
add_subdirectory(library)
add_subdirectory(port)

 

      2. Library目录下CmakeLists.txt的修改

         添加u8g2库文件,由于u8g2支持非常多的lcd显示驱动芯片,所以目录下的C文件只需要添加需要的就可以。

add_library(GUI_U8G2_FILES STATIC)
target_sources(GUI_U8G2_FILES PUBLIC
${LCD_GUI_DIR}/u8g2/mui.c
${LCD_GUI_DIR}/u8g2/mui_u8g2.c
${LCD_GUI_DIR}/u8g2/u8g2_arc.c
${LCD_GUI_DIR}/u8g2/u8g2_bitmap.c
${LCD_GUI_DIR}/u8g2/u8g2_box.c
${LCD_GUI_DIR}/u8g2/u8g2_buffer.c
${LCD_GUI_DIR}/u8g2/u8g2_button.c
${LCD_GUI_DIR}/u8g2/u8g2_circle.c
${LCD_GUI_DIR}/u8g2/u8g2_cleardisplay.c
${LCD_GUI_DIR}/u8g2/u8g2_d_memory.c
${LCD_GUI_DIR}/u8g2/u8g2_d_setup.c
${LCD_GUI_DIR}/u8g2/u8g2_font.c
${LCD_GUI_DIR}/u8g2/u8g2_fonts.c
${LCD_GUI_DIR}/u8g2/u8g2_hvline.c
${LCD_GUI_DIR}/u8g2/u8g2_input_value.c
${LCD_GUI_DIR}/u8g2/u8g2_intersection.c
${LCD_GUI_DIR}/u8g2/u8g2_kerning.c
${LCD_GUI_DIR}/u8g2/u8g2_line.c
${LCD_GUI_DIR}/u8g2/u8g2_ll_hvline.c
${LCD_GUI_DIR}/u8g2/u8g2_message.c
${LCD_GUI_DIR}/u8g2/u8g2_polygon.c
${LCD_GUI_DIR}/u8g2/u8g2_selection_list.c
${LCD_GUI_DIR}/u8g2/u8g2_setup.c
${LCD_GUI_DIR}/u8g2/u8log.c
${LCD_GUI_DIR}/u8g2/u8log_u8g2.c
${LCD_GUI_DIR}/u8g2/u8log_u8x8.c
${LCD_GUI_DIR}/u8g2/u8log_u8x8.c
${LCD_GUI_DIR}/u8g2/u8x8_8x8.c
${LCD_GUI_DIR}/u8g2/u8x8_byte.c
${LCD_GUI_DIR}/u8g2/u8x8_cad.c
${LCD_GUI_DIR}/u8g2/u8x8_capture.c
${LCD_GUI_DIR}/u8g2/u8x8_d_ls013b7dh03.c
${LCD_GUI_DIR}/u8g2/u8x8_debounce.c
${LCD_GUI_DIR}/u8g2/u8x8_display.c
${LCD_GUI_DIR}/u8g2/u8x8_fonts.c
${LCD_GUI_DIR}/u8g2/u8x8_gpio.c
${LCD_GUI_DIR}/u8g2/u8x8_input_value.c
${LCD_GUI_DIR}/u8g2/u8x8_message.c
${LCD_GUI_DIR}/u8g2/u8x8_selection_list.c
${LCD_GUI_DIR}/u8g2/u8x8_setup.c
${LCD_GUI_DIR}/u8g2/u8x8_string.c
${LCD_GUI_DIR}/u8g2/u8x8_u8toa.c
${LCD_GUI_DIR}/u8g2/u8x8_u16toa.c
)
target_include_directories(GUI_U8G2_FILES INTERFACE
${LCD_GUI_DIR}/u8g2
)

硬件接口函数移植实现

接口函数移植主要有:硬件SPI初始化和相关GPIO硬件接口初始化,lcd写函数的实现和gpio操作函数实现。
spi及gpio口初始化函数
Spi硬件写操作实现:
void lcd_SharpMem_io_init(void)
{
     printf("init lcd spi1\n\r");
    // this example will use SPI1 at 5MHz
    spi_init(SHARPMEM_SPI_PORT, 2 * 1000 * 1000);
    gpio_set_function(SHARPMEM_PIN_SCK, GPIO_FUNC_SPI);
    gpio_set_function(SHARPMEM_PIN_MOSI, GPIO_FUNC_SPI);
    // make the SPI pins available to picotool
    bi_decl(bi_2pins_with_func(SHARPMEM_PIN_MOSI, SHARPMEM_PIN_SCK, GPIO_FUNC_SPI));
    // chip select is active-low, so we'll initialise it to a driven-high state
    gpio_init(SHARPMEM_PIN_CS);
    gpio_set_dir(SHARPMEM_PIN_CS, GPIO_OUT);
    gpio_put(SHARPMEM_PIN_CS, 0);
    // make the SPI pins available to picotool
    bi_decl(bi_1pin_with_name(SHARPMEM_PIN_CS, "Sharp Memory Display CHIP SELECT"));
}

u8g2操作写入LCD数据接口函数

// sharp memory display 3wire spi cb
uint8_t sharpmem_byte_3wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
  uint8_t i;
  uint8_t *data;
  uint16_t b;
  static uint8_t last_dc;
  switch(msg)
  {
    case U8X8_MSG_BYTE_SEND:
      data = (uint8_t *)arg_ptr;
      if(arg_int > 0)
        spi_write_blocking(SHARPMEM_SPI_PORT, data, arg_int);
      break;
    case U8X8_MSG_BYTE_INIT:
      break;
    case U8X8_MSG_BYTE_SET_DC:
      break;
    case U8X8_MSG_BYTE_START_TRANSFER:
      gpio_put(SHARPMEM_PIN_CS, 1);
      break;
    case U8X8_MSG_BYTE_END_TRANSFER:
      gpio_put(SHARPMEM_PIN_CS, 0);
      break;
    default:
      return 0;
  }
  return 1;
}

库中需要的gpio操作函数实现,实际上并不需要实现什么。

uint8_t sharpmem_gpio_and_delay_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
  switch (msg)
  {
  case U8X8_MSG_GPIO_AND_DELAY_INIT: // called once during init phase of u8g2/u8x8
    break;                           // can be used to setup pins
  case U8X8_MSG_DELAY_NANO:          // delay arg_int * 1 nano second
    break;
  case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
    break;
  case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
    break;
  case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
    break;
  case U8X8_MSG_GPIO_D0:   // D0 or SPI clock pin: Output level in arg_int
    // case U8X8_MSG_GPIO_SPI_CLOCK:
    break;
  case U8X8_MSG_GPIO_D1: // D1 or SPI data pin: Output level in arg_int
    // case U8X8_MSG_GPIO_SPI_DATA:
    break;
  case U8X8_MSG_GPIO_D2: // D2 pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_D3: // D3 pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_D4: // D4 pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_D5: // D5 pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_D6: // D6 pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_D7: // D7 pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_E: // E/WR pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_CS: // CS (chip select) pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_DC: // DC (data/cmd, A0, register select) pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_RESET: // Reset pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_CS1: // CS1 (chip select) pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_CS2: // CS2 (chip select) pin: Output level in arg_int
    break;
  case U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pin
    break;                      // arg_int=1: Input dir with pullup high for I2C clock pin
  case U8X8_MSG_GPIO_I2C_DATA:  // arg_int=0: Output low at I2C data pin
    break;                      // arg_int=1: Input dir with pullup high for I2C data pin
  case U8X8_MSG_GPIO_MENU_SELECT:
    break;
  case U8X8_MSG_GPIO_MENU_NEXT:
    break;
  case U8X8_MSG_GPIO_MENU_PREV:
    break;
  case U8X8_MSG_GPIO_MENU_HOME:
    break;
  default:
    break;
  }
  return 1;
}

 

运行输出

测试代码

    u8g2_Setup_ls013b7dh05_144x168_f(&u8g2, U8G2_R0, sharpmem_byte_3wire_hw_spi, sharpmem_gpio_and_delay_cb);
    u8g2_InitDisplay(&u8g2);        // 根据所选的芯片进行初始化工作,初始化完成后,显示器处于关闭状态
    u8g2_SetPowerSave(&u8g2, 0);    // 打开显示器
    u8g2_SetDrawColor(&u8g2, 0);  //设置绘制颜色(反色)
    u8g2_ClearDisplay(&u8g2); // 清除显示数据及屏幕
    u8g2_ClearBuffer(&u8g2);//清空缓冲区的内容
    u8g2_SetFont(&u8g2,u8g2_font_10x20_mr);//设置英文字体
    u8g2_DrawStr(&u8g2,20,15,"PING TEST");//输出固定不变的字符串
    u8g2_SetFont(&u8g2,u8g2_font_7x14_mr);//设置英文字体
    u8g2_DrawStr(&u8g2,0,40,"DNS:218.203.59.116");//输出固定不变的字符串
    u8g2_DrawStr(&u8g2,0,60,"Ping Domain Name:");//输出固定不变的字符串
    u8g2_DrawStr(&u8g2,20,80,"www.baidu.com");//输出固定不变的字符串
    u8g2_DrawStr(&u8g2,0,100,"DNS GetIP:");//输出固定不变的字符串
    sprintf(cstr_buf,"%d.%d.%d.%d",destip[0],destip[1],destip[2],destip[3]);
    u8g2_DrawStr(&u8g2,20,120,cstr_buf);//输出固定不变的字符串
    u8g2_DrawStr(&u8g2,0,140,"PING SUCCESS!");//输出固定不变的字符串
    u8g2_SendBuffer(&u8g2);//绘制缓冲区的内容    

 

模块运行状态

 

 

最新回复

厉害厉害,学习了     详情 回复 发表于 2024-2-25 16:12
点赞 关注
 
 

回复
举报

6807

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

库中需要的gpio操作函数实现,实际上并不需要实现什么,这是为什么

点评

我感觉这个函数主要要是提供延时功能和GPIO的操作的一些功能的,我看有些大神在模拟I2C和模拟SPI中把一些操作放在这里,还有一些初始化会放在这里,我这个移植的时候把硬件SPI和CS引脚初始化直接放到外面初始化函数  详情 回复 发表于 2024-2-25 08:20
 
 
 

回复

337

帖子

2

TA的资源

纯净的硅(初级)

板凳
 
本帖最后由 我爱下载 于 2024-2-25 08:21 编辑
Jacktang 发表于 2024-2-24 08:05 库中需要的gpio操作函数实现,实际上并不需要实现什么,这是为什么

我感觉这个函数主要要是提供延时功能和GPIO的操作的一些功能的,我看有些大神在模拟I2C和模拟SPI中把一些操作放在这里,还有一些初始化会放在这里,我这个移植的时候把硬件SPI和CS引脚初始化直接放到外面初始化函数里了,而且这款LCD没有命令数据切换引脚,所以GPIO函数对这个lcd的移植没有什么用了

 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(中级)

4
 

厉害厉害,学习了

 

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表