|
[b]相关帖子[/b]
[list]
[*][url=https://www.stcaimcu.com/thread-1474-1-1.html]【开源】GUI-OLED12864: U8g2/OLED12864 for STC32G12K128[/url]
[/list][list]
[*][url=https://www.stcaimcu.com/thread-12152-1-1.html]GUI-U8g2 移植到Ai805U实验箱 | 已给说明[/url]
[/list]在这里感谢上述帖子的版主开疆拓土,在我还没明白如何驱动的情况下率先提供了应用例。
[hr]稍微修改了一下源码,实现了STC8051U(AI8051U)驱动SH1108(中景园128×160)液晶屏的效果。以下为预览视频:
(若无法直接预览,可点击原视频链接在新窗口打开: [url=https://v.stcai.com/sv/61c06001-19ba93d3ae8/61c06001-19ba93d3ae8.mp4]https://v.stcai.com/sv/61c06001-19ba93d3ae8/61c06001-19ba93d3ae8.mp4[/url])
[apoyl_aliyunvideo]1003[/apoyl_aliyunvideo]
[hr][b]简述[/b]
由于研究时间相隔太久,1年前还在琢磨的U8G2现在开始使用的时候发现移植方法已经被忘得一干二净,真正用于独自使用的速查手册还不合格,再加上我这次有整活任务要动真格,所以加快了自己的开发速度。
先前凭借着自己的网络偶发能正常访问GitHub的特性,取得了原作者olikraus的新版本U8G2(发帖时原作更新到2025年11月10日版),这为我复制新函数打下基础,手里恰好存在三个模块,分别是SSD1322(Intel 8080接口)、SH1108(SPI接口带D/C)、GP1247AI(VFD,SPI接口不含D/C),都是这次重点攻坚的目标,恰好这三个显示屏模块都在新版本对应的库文件中,所以直接复制文件,再根据报错找办法就行。
二编:电脑浏览器炸了,提交之后的版本居然是凌晨3点开Markdown编辑器之后的版本,已通过浏览器缓存恢复原始数据。
[hr][b]移植办法[/b]
1.先根据自己的OLED固件信息,在新版本库文件中找到对应型号的OLED驱动函数。以本人成功驱动的SH1108为例,寻找情况如下:
*在论坛版库函数找到了"u8g2_Setup_sh1108_160x160_f",但经过编程,存在部分内容被裁切的问题。
*在新版库函数找到了"u8g2_Setup_sh1108_128x160_f",中景园的SH1108就是仅显示128×160的版本。
[quote]/* issue #1998, 128x160 OLED */[/quote]
2.根据关键词,在工程将驱动文件放置在μVision工程中。
我把“u8x8_d_sh1108.c”放进去了。
3.在u8g2_d_setup.c中寻找有没有对应的初始化函数,比如“void u8g2_Setup_sh1108_128x160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)”,如果找到了,将后缀为1/2/f三个关键字的函数(可按需只拿一个)解除上下文的“#if 0",使其解除忽略。如果没有对应的初始化函数,从新文件复制。
[code]/* "u8g2_d_setup.c" */
//上面有一个#if 0
void u8g2_Setup_sh1107_i2c_seeed_128x128_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
{……}
#endif //将 if 0 导致的屏蔽从此处截断
/* sh1108 160x160 Generic*/
/* sh1108 1 */
void u8g2_Setup_sh1108_160x160_1(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
{……}
/* sh1108 128x160 Generic*/
/* sh1108 f */
/* sh1108 128x160 I2C_Exclude_DorC*/
/* sh1108 f */void u8g2_Setup_sh1108_i2c_128x160_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
{
uint8_t tile_buf_height;
uint8_t *buf;
u8g2_SetupDisplay(u8g2, u8x8_d_sh1108_128x160, u8x8_cad_ssd13xx_i2c, byte_cb, gpio_and_delay_cb);
buf = u8g2_m_16_20_f(&tile_buf_height);
u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
}
#if 0 //补上被截断的if 0使得下面部分恢复屏蔽[/code]4.找到函数定义中名为“buf=”的关键词,检查等式后面的参数是否能在文件中找到,比如“u8g2_d_memory.c”中的“u8g2_m_16_20_1(&tile_buf_height)”,如果找到了,同样解除上下文的“ #if 0 ”,否则直接导入,导入后的函数原型可能是“uint8_t *u8g2_m_16_20_f(uint8_t *page_cnt);”
[quote]/* "u8g2_d_setup.c" */
buf = u8g2_m_16_20_f(&tile_buf_height);[/quote]
[code]/* "u8g2_d_memory.c" */
/* issue #1998, 128x160 OLED */
uint8_t *u8g2_m_16_20_1(uint8_t *page_cnt)
{……}
uint8_t *u8g2_m_16_20_2(uint8_t *page_cnt)
{……}
uint8_t *u8g2_m_16_20_f(uint8_t *page_cnt)
{
#ifdef U8G2_USE_DYNAMIC_ALLOC
*page_cnt = 20;
return 0;
#else
static uint8_t buf[2560];
*page_cnt = 20;
return buf;
#endif
}[/code]5.提交修改后的工程文件进行全编译(Rebuild All Targets),如果存在L107错误(L107 Address Space Overflow),选择内存模型为Large或者换成后缀为“1/2”的分页模式。
[quote]Program Size: data=8.1 edata+hdata=256 xdata=8303 const=1003 code=25044[/quote]
U8G2的GitHub页面写了将GRAM分配到外部指定空间的办法,可参考:“[url=https://github.com/olikraus/u8g2/wiki/u8g2setupc#using-dynamically-allocated-page-buffers]Using dynamically allocated page buffers[/url]”
以下为做好那时候的工程:
[attach]128670[/attach] |