【得捷电子Follow me第4期】扩展U8G2移植支持LCD显示
[复制链接]
本帖最后由 我爱下载 于 2024-2-22 18:26 编辑
【得捷电子Follow me第4期】扩展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);//绘制缓冲区的内容
模块运行状态
|