u8g2 stm32移植笔记

下载地址

U8g2下载地址U8g2项目Github

移植步骤

我移植U8g2采用的是stm32硬件SPI,可以提供更高的通讯速率,移植时只需要提供两个回调函数即可。

  1. 从GitHub下载的源码中我们选择csrc文件夹下的代码进行移植
  2. 将csrc下的文件加入到项目目录,其中u8x8_d_器件名.c的文件只需选择自己对应的显示器驱动芯片即可,比如我的是OLED12864显示器,显示器驱动为SSD1306,分辨率为128x64,我选择的文件为u8x8_d_ssd1306_128x64_noname.c
  3. 修改u8g2_d_setup.c文件,只保留自己使用的芯片对应的setup文件。比如我选择的是u8g2_Setup_ssd1306_128x64_noname_1,控制芯片SSD1306,分辨率128x64,128字节页大小。按照自己的芯片进行选择,还有其他类型的函数比如u8g2_Setup_ssd1306_128x64_vcomh0_1u8g2_Setup_ssd1306_128x64_alt0_1,仔细对比后发现只是芯片初始化配置不同,其他操作与noname相同,可以自己选一个进行尝试。
u8g2_Setup_ssd1306_128x64_noname_1 /*芯片SSD1306,分辨率128x64,128字节页大小*/
u8g2_Setup_ssd1306_128x64_noname_2 /*芯片SSD1306,分辨率128x64,256字节页大小*/
u8g2_Setup_ssd1306_128x64_noname_f /*芯片SSD1306,分辨率128x64,1024字节页大小*/
  1. 在自己的工程中编写如下函数
uint8_t u8x8_byte_4wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,void *arg_ptr)
{
    switch (msg)
    {
        case U8X8_MSG_BYTE_SEND: /*通过SPI发送arg_int个字节数据*/
            spiWrNdata(0, arg_ptr, arg_int); /*注意需要自行管理片选信号*/
            break;
        case U8X8_MSG_BYTE_INIT: /*初始化函数,这边我已经初始化SPI了就不填了*/
            break;
        case U8X8_MSG_BYTE_SET_DC: /*设置DC引脚,DC引脚控制发送的是数据还是命令*/
            gpioPinWrite(U8G2_DC_PORT, U8G2_DC_PIN, arg_int);
            break;
        case U8X8_MSG_BYTE_START_TRANSFER: /*开始传输前会进行的操作,如果使用软件片选可以在这里进行控制*/
            break;
        case U8X8_MSG_BYTE_END_TRANSFER: /*传输后进行的操作,如果使用软件片选可以在这里进行控制*/
            break;
        default:
            return 0;
    }
    return 1;
}

uint8_t u8x8_stm32_gpio_and_delay(U8X8_UNUSED u8x8_t *u8x8,
    U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int,
    U8X8_UNUSED void *arg_ptr) 
{
    switch (msg)
    {
        case U8X8_MSG_GPIO_AND_DELAY_INIT: /*dela和GPIO的初始化,我已经初始化过了*/
            break;
        case U8X8_MSG_DELAY_MILLI: /*延时ms函数*/
            delay_ms(arg_int);
            break;
        case U8X8_MSG_GPIO_CS: /*片选信号控制,但是似乎没有啥用*/
            gpioPinWrite(U8G2_CS_PORT, U8G2_CS_PIN, arg_int);
            break;
        case U8X8_MSG_GPIO_DC: /*设置DC引脚,DC引脚控制发送的是数据还是命令*/
            gpioPinWrite(U8G2_DC_PORT, U8G2_DC_PIN, arg_int);
            break;
        case U8X8_MSG_GPIO_RESET: /*GPIO复位*/
            break;
    }
    return 1;
}
void u8g2Init(u8g2_t *u8g2)
{
	/*U8G2_R0 :屏幕旋转/镜像
	U8G2_R0
	U8G2_R1
	U8G2_R2
	U8G2_R3
	U8G2_MIRROR
	*/
	u8g2_Setup_ssd1306_128x64_noname_1(u8g2, U8G2_R0, u8x8_byte_4wire_hw_spi, u8x8_stm32_gpio_and_delay);  // 初始化 u8g2 结构体
	u8g2_InitDisplay(&u8g2); // 根据所选的芯片进行初始化工作,初始化完成后,显示器处于关闭状态
	u8g2_SetPowerSave(&u8g2, 0); // 打开显示器
}
  1. 上一步完成之后,注释掉u8g2_d_memory.c文件里面的所有函数,文件中的函数是给显示器分配显存的,在u8g2_Setup_ssd1306_128x64_noname_1 中有调用此文件中的函数。注释掉后编译,查看哪个函数未定义就去掉相应函数的注释 (如果使用编译器优化的话也可以不删除其他函数)
  2. 编写测试函数
/*官方提供的Log绘制demo*/
void draw(u8g2_t *u8g2)
{
    u8g2_SetFontMode(u8g2, 1); /*字体模式选择*/
    u8g2_SetFontDirection(u8g2, 0); /*字体方向选择*/
    u8g2_SetFont(u8g2, u8g2_font_inb24_mf); /*字库选择*/
    u8g2_DrawStr(u8g2, 0, 20, "U");
    
    u8g2_SetFontDirection(u8g2, 1);
    u8g2_SetFont(u8g2, u8g2_font_inb30_mn);
    u8g2_DrawStr(u8g2, 21,8,"8");
        
    u8g2_SetFontDirection(u8g2, 0);
    u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
    u8g2_DrawStr(u8g2, 51,30,"g");
    u8g2_DrawStr(u8g2, 67,30,"\xb2");
    
    u8g2_DrawHLine(u8g2, 2, 35, 47);
    u8g2_DrawHLine(u8g2, 3, 36, 47);
    u8g2_DrawVLine(u8g2, 45, 32, 12);
    u8g2_DrawVLine(u8g2, 46, 33, 12);
  
    u8g2_SetFont(u8g2, u8g2_font_4x6_tr);
    u8g2_DrawStr(u8g2, 1,54,"github.com/olikraus/u8g2");
}
  1. 编写主函数
u8g2_t u8g2; // 它将包含一个显示器的所有数据
int main(void)
{
	/*外设初始化*/
	...
	/*u8g2初始化*/
	u8g2Init(&u8g2);
	while(1)
	{
       u8g2_FirstPage(&u8g2);
       do
       {
   			draw(&u8g2);
       } while (u8g2_NextPage(&u8g2));
    }
}
  1. 最后编译,可能会提示内存溢出,可以注释掉u8x8_fonts.c文件中不使用的字体,也可以启用编译器优化,将未使用的字体数组自动优化掉。

部分源码简要分析

  1. u8g2_Setup_ssd1306_128x64_noname_1函数分析
void u8g2_Setup_ssd1306_128x64_noname_1(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;
   /*
   u8x8_d_ssd1306_128x64_noname :对应芯片显示相关操作
   u8x8_cad_001:芯片底层数据发送操作
   byte_cb:发送数据回调函数(用户提供)
   gpio_and_delay_cb:io操作与延时操作回调函数(用户提供)
    */
   u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_001, byte_cb, gpio_and_delay_cb); 
   /*获取显存,此函数获取128字节数组*/
   buf = u8g2_m_16_8_1(&tile_buf_height);
   /*设置显示器显存相关参数*/
   u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
}
  1. 页面刷新
    所有的draw操作都是在操作显存,并未将数据写入给显示器,只有,u8g2_NextPage(&u8g2)函数会将显存中的数据发送给显示器
  • 8
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值