注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
我爱下载的个人空间 https://home.eeworld.com.cn/space-uid-101026.html [收藏] [复制] [分享] [RSS]
日志

【得捷电子Follow me第4期】扩展U8G2移植支持LCD显示

已有 454 次阅读2024-2-22 18:25 |个人分类:产品评测

【得捷电子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);//绘制缓冲区的内容    

 

模块运行状态

 

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章