U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)

这篇具有很好参考价值的文章主要介绍了U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

U8g2库的STM32硬件SPI移植教程(HAL、OLED显示、四线SPI)

前言

  • 本文教你把U8g2图形库移植到STM32上,基于STM32的硬件SPI、CubeMX
  • U8g2库Github网址:https://github.com/olikraus/u8g2
  • U8g2库CSDN镜像网址:https://gitcode.net/mirrors/olikraus/u8g2?utm_source=csdn_github_accelerator
  • 硬件准备:STM32C8T6(STM32系列芯片)、0.96寸OLED(128×64)、J-Link(或其他)
  • 引脚连接:
//----------------------------------------------------------------
本次用的是SPI1、DMA、全双工(当然半双工也没什么问题、CS、DC、RS是普通GPIO,自行切换)
GND -----------> 电源地
VCC ----------->5V或3.3v电源
D0 -----------> 接PA5(SCL)
D1 -----------> 接PA7(SDA)
RES -----------> 接PB0
DC -----------> 接PB1
CS -----------> 接PA4              
//----------------------------------------------------------------

U8g2简介

出自此篇基于STM32移植U8g2图形库——OLED显示

U8g2是什么

   U8g2是GitHub上一款十分优秀的开源图形库(GUI库),其本质是嵌入式设备的单色图形库。在 Github 上超过3.2K Star,2.6K Commit。其开发语言90%为C语言,且代码简洁干练便于移植与后期修改。

U8g2支持的显示控制器

   U8g2支持单色OLED和LCD,包括以下控制器:

SSD1305 SSD1306 SSD1309 SSD1312 SSD1316 SSD1320
SSD1322 SSD1325 SSD1327 SSD1329 SSD1606 SSD1607
SH1106 SH1107 SH1108 SH1122 T6963 RA8835
LC7981 PCD8544 PCF8812 HX1230 UC1601 UC1604
UC1608 UC1610 UC1611 UC1617 UC1638 UC1701
ST7511 ST7528 ST7565 ST7567 ST7571 ST7586
ST7588 ST75256 ST75320 NT7534 ST7920 IST3020
IST7920 LD7032 KS0108 KS0713 HD44102 T7932
SED1520 SBN1661 IL3820 MAX7219

   可以说,基本上主流的显示控制器都支持,比如我们常见的SSD1306等,读者在使用该库之前请查阅自己的OLED显示控制器是否处于支持列表中。

U8g2的优势

  • U8g2库平台支持性好,基本上支持绝大部分Arduino与STM32开发板,也包含物联网比较常用的esp8266;
  • U8g2库显示控制器支持性好,基本上市面上的OLED都完美支持;
  • U8g2库 API函数众多,特别支持了中文,支持了不同字体,这是一个对于开发者俩说不小的福利;
  • U8g2 库移植简单,容易使用(这一点也是笔者比较钟意的);

  其实,我们可以把U8g2当作一个工具箱,需要使用的时候就去打开工具箱,使用里面的已经写好的API函数去实现我们需要达到的显示效果。(当然,前提是需要熟悉U8g2的使用,这一点网上有很多用法博客写得都很详细,感兴趣的读者朋友可以去看看这篇:深入学习Arduino u8g2 OLED库,一篇就够)

CubexMX的配置

RCC配置外部高速晶振(精度更高)——HSE:

U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)

SYS配置:Debug设置成Serial Wire(否则可能导致芯片自锁):

U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)

时钟树配置:

U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)

SPI1配置半双工(全双工):作为OLED的通讯方式:(注意这里的配置)

  半双工:
U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)
  全双工:
U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)

DMA配置:

U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)

工程配置:

U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)
  这里我们不用的库不加,减小代码体积
U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)
然后生成

U8g2移植

准备U8g2库文件

  • 准备U8g2库文件---------->U8g2下载地址: https://github.com/olikraus/u8g2 下载压缩包
  • Git用---------->git clone https://ghproxy.com/https://github.com/olikraus/u8g2.git

精简U8g2库文件

  • U8g2支持多种显示驱动的屏幕,因为源码中也包含了各个驱动对应的文件(因此不需要自己去写屏幕底层驱动了),为了减小整个工程的代码体积和芯片资源占用,在移植U8g2时,可以删除一些无用的文件。
  • 这里我们主要关注的是U8g2库文件中的csrc文件夹 U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)
去掉csrc文件夹中无用的驱动文件

  这些驱动文件通常是u8x8_d_xxx.cxxx包括驱动的型号屏幕分辨率ssd1306驱动芯片的OLED,使用u8x8_ssd1306_128x64_noname.c这个文件,其它的屏幕驱动和分辨率的文件可以删掉。
U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)
u8x8_d_xxx.c文件中留下u8x8_ssd1306_128x64_noname.c即可

精简u8g2_d_setup.c(注意不是u8x8_setup.c)

  由于本文使用的OLED是SPI接口,只留一个本次要用到u8g2_Setup_ssd1306_128x64_noname_f就好(如果是IIC接口,需要使用u8g2_Setup_ssd1306_i2c_128x64_noname_f这个函数,多了i2c注意区分),其它的可以删掉或注释掉。
U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)

注意,与这个函数看起来十分相似的函数的有:

  • u8g2_Setup_ssd1306_128x64_noname_1
  • u8g2_Setup_ssd1306_128x64_noname_2
  • u8g2_Setup_ssd1306_128x64_noname_f
  • u8g2_Setup_ssd1306_i2c_128x64_noname_1
  • u8g2_Setup_ssd1306_i2c_128x64_noname_2
  • u8g2_Setup_ssd1306_i2c_128x64_noname_f

其中,前面3个,是给SPI接口的OLED用的,后面3个,是给I2C用的函数最后的数字或字母,代表显示时的buf大小:

  • 1:128字节
  • 2:256字节
  • f:1024字节
精简u8g2_d_memory.c

  u8g2_d_memory.c文件中,由于用到的u8g2_Setup_ssd1306_128x64_noname_f函数中,只调用了u8g2_m_16_8_f这个函数,所以只用留下这个函数,如果你用的其他函数,在u8g2_d_memory.c留下它相对应调用到的函数即可,其它的函数要删掉或注释,否则编译时很可能会导致内存不足
U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)
U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)

将精简后的U8g2库添加至Keil

  Keil工程目录添加精简后U8g2库文件中的csrc文件夹,然后再添加U8g2的头文件搜寻目录(U8g2_lib里都是csrc文件里面的文件,可以根据自己的需要删减),如下:
U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)
U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)

代码

Oled回调函数

oled_driver.c:

#include "oled_driver.h"
#include "stdlib.h"
#include "spi.h"
#include "dma.h"
#include "u8g2.h"

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个字节数据*/
//           HAL_SPI_Transmit_DMA(&hspi1, (uint8_t *)arg_ptr, arg_int);while(hspi1.TxXferCount);
			/*配置了DMA取消上一行注释即可*/
			HAL_SPI_Transmit(&hspi1,(uint8_t *)arg_ptr,arg_int,200);
			/*这是CubeMX生成的初始化*/
            break;
        case U8X8_MSG_BYTE_INIT: /*初始化函数*/
            break;
        case U8X8_MSG_BYTE_SET_DC: /*设置DC引脚,表明发送的是数据还是命令*/
			HAL_GPIO_WritePin(OLED_DC_GPIO_Port,OLED_DC_Pin,arg_int);
            break;
        case U8X8_MSG_BYTE_START_TRANSFER: 
            u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
            u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
            break;
        case U8X8_MSG_BYTE_END_TRANSFER: 
            u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
            u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
            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: /*delay和GPIO的初始化,在main中已经初始化完成了*/
            break;
        case U8X8_MSG_DELAY_MILLI: /*延时函数*/
            HAL_Delay(arg_int);     //调用谁stm32系统延时函数
            break;
        case U8X8_MSG_GPIO_CS: /*片选信号*/ //由于只有一个SPI设备,所以片选信号在初始化时已经设置为常有效
            HAL_GPIO_WritePin(OLED_CS_GPIO_Port, OLED_CS_Pin, arg_int);
            break;
        case U8X8_MSG_GPIO_DC: /*设置DC引脚,表明发送的是数据还是命令*/
            HAL_GPIO_WritePin(OLED_DC_GPIO_Port,OLED_DC_Pin,arg_int);
            break;
        case U8X8_MSG_GPIO_RESET:
            break;
    }
    return 1;
}

void u8g2Init(u8g2_t *u8g2)
{
/********************************************     
U8G2_R0     //不旋转,不镜像     
U8G2_R1     //旋转90度
U8G2_R2     //旋转180度   
U8G2_R3     //旋转270度
U8G2_MIRROR   //没有旋转,横向显示左右镜像
U8G2_MIRROR_VERTICAL    //没有旋转,竖向显示镜像
********************************************/
//    u8g2_Setup_sh1106_128x64_noname_2(u8g2, U8G2_R0, u8x8_byte_4wire_hw_spi, u8x8_stm32_gpio_and_delay);  // 初始化1.3寸OLED u8g2 结构体
	u8g2_Setup_ssd1306_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_4wire_hw_spi, u8x8_stm32_gpio_and_delay);  // 初始化0.96寸OLED u8g2 结构体
	u8g2_InitDisplay(u8g2);     //初始化显示
	u8g2_SetPowerSave(u8g2, 0); //开启显示
}
/*官方logo的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");
}
/********************************* end_of_file **********************************/

GPIO定义的时候在CubeMX设置别名能更容易的切换IO口,CS拉高,如下
U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)
oled_driver.h:

#ifndef __MD_OLED_DRIVER_H
#define __MD_OLED_DRIVER_H

#include "stdlib.h"	  
#include "main.h"
#include "gpio.h"
#include "u8g2.h"

//-----------------OLED端口定义----------------  					   
#define MD_OLED_RST_Clr() HAL_GPIO_WritePin(OLED_RES_GPIO_Port,OLED_RES_Pin,GPIO_PIN_RESET) //oled 复位端口操作
#define MD_OLED_RST_Set() HAL_GPIO_WritePin(OLED_RES_GPIO_Port,OLED_RES_Pin,GPIO_PIN_SET)

//OLED控制用函数
uint8_t u8x8_byte_4wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,void *arg_ptr);
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) ;
void u8g2Init(u8g2_t *u8g2);
void draw(u8g2_t *u8g2);

#endif  

  上述编写的移植函数代码属于HAL库下的代码,标准库的代码其实差不多,有个别地方需要注意修改。有一定MCU编程基础的朋友应该很简单就可以做到仿写。移植代码的本质:这些函数代码就是对应的U8g2图形库的接口函数,通过这些函数去启用U8g2图形库。

main函数

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SPI1_Init();

  /* Initialize interrupts */
  MX_NVIC_Init();
  /* USER CODE BEGIN 2 */
  u8g2_t u8g2; // 显示器初始化结构体
  MD_OLED_RST_Set(); //显示器复位拉高
  u8g2Init(&u8g2);   //显示器调用初始化函数
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
       u8g2_FirstPage(&u8g2);
       do
       {
   			draw(&u8g2);
           
       } while (u8g2_NextPage(&u8g2));
  }
  /* USER CODE END 3 */
}

最终效果

U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)

总结

  U8g2图形库可以说目前小尺寸OLED首选的GUI,其可以呈现出的图形远不止上述中的图形,更多的功能还需要读者朋友们自己去好好发掘。优秀GUI的移植是一名合格嵌入式工程师必须掌握的技能之一,其可以达到大大缩短开发周期,优化UI界面等目的。LCD屏幕也存在类似的优秀开源GUI库,后续笔者会进行更新,感兴趣的读者朋友可以点波关注,感谢!!!
————————————————
原文链接:https://blog.csdn.net/black_sneak/article/details/126312657文章来源地址https://www.toymoban.com/news/detail-487032.html

  • 开源代码:https://gitee.com/ljs_ice/STM32_u8g2

到了这里,关于U8g2库的STM32硬件SPI(DMA)移植教程(HAL、OLED显示、四线SPI、DMA)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [低端局][cx32L003] 移植U8G2

    在低端芯片上使用U8G2 U8g2:单色显示库,版本2 U8g2是一个用于嵌入式设备的单色图形库。U8g2支持单色oled和lcd,其中包括以下控制器:Ssd1305、ssd1306、ssd1309、ssd1312、ssd1316、ssd1318、ssd1320、ssd1322、ssd1325、ssd1327、ssd1327、ssd1327、ssd1327、ssd1327、ssd1327、ssd1106、sh1107、sh1108、ssd1607、

    2024年02月13日
    浏览(19)
  • STM32 使用 U8g2 显示自定义图像

    首先移植 U8g2 图形库到 STM32,本文不赘述了。 本问针对 SSD1306 128*64 屏幕 采用 PCtoLCD2002完美版 字模软件对图像取模,具体操作如下: 新建图像: 图像长宽分别为 128 , 64 根据需要绘制图像,例如: 设置字模格式: 需要注意:取模方式 取模走向 C51格式 生成字模,将字模保

    2024年02月04日
    浏览(30)
  • u8g2库的使用及驱动LCD显示中文

    1、准备工作 Env 工具包含了 RT-Thread 源代码开发编译环境和软件包管理系统。 从 RT-Thread 官网下载 Env 工具。https://www.rt-thread.org/download.html。 在电脑上装好 git,软件包管理功能需要 git 的支持。git 的下载地址为https://git-scm.com/downloads,根据向导正确安装 git,并将 git 添加到系

    2024年02月02日
    浏览(24)
  • HAL/LL/STD STM32 U8g2库 +I2C SSD1306/sh1106 WouoUI磁贴案例

    📍基于STM32F103C8T6 LL库驱动版本: https://gitee.com/chcsx/platform-test/tree/master/MDK-ARM 🎬视频演示: WouoUI移植磁贴案例,新增确认弹窗 📍基于标准库驱动,STM32F103RCT6移植u8g2 硬件i2c WouoUI磁贴: https://gitee.com/henrycrh/stm32-f103-rct6_-wouo-ui/tree/master/STM32F10x_FWlib/src 🎬视频演示: 🔖使用LL库

    2024年02月22日
    浏览(20)
  • 【ESP32之旅】U8g2 在线仿真和UI调试

    几乎每个玩屏幕的电子DIYer都知道万能的屏幕驱动中间件u8g2库,这个库提供了强大的驱动适配和ui设计能力。但是官方没有一个好用的ui设计和仿真软件,在设计UI布局的时候对单片机频繁的烧录调试浪费了大量的时间。最近在论坛看到有一个第三方维护的在线u8g2 UI设计软件

    2024年02月09日
    浏览(23)
  • esp32 Arduino(九)u8g2图形库 IIC驱动OLED

    LED驱动芯片:SSD1306 开发平台: vscode+platformIO 开发板:ESP32 Divkit v1 目前Arduino平台上使用最广泛的OLED库: U8G2 github地址: https://github.com/olikraus/u8g2/ 设置和参考手册:https://github.com/olikraus/u8g2/wiki U8g2:单色显示器库,版本2 U8g2是用于嵌入式设备的单色图形库。U8g2支持单色OLED和LCD,包括

    2023年04月09日
    浏览(35)
  • U8G2中文显示问题(u8g2.drawStr()中文不显示)

            在使用u8g2进行中文先显示时,踩到一个坑,其他大佬也没有专门提过这一点,现跟大家分享一下。         起因是在看一些例程时,直接采用u8g2.drawStr()来进行英文输出,在想用该方法进行中文输出时,无法显示中文。 运行代码如下: 显示效果为: 只显示\\\"Hello\\\",

    2024年02月11日
    浏览(24)
  • ESP32 入门笔记04: 0.96寸OLED 显示屏 + u8g2库丝滑显示UI (ESP32 for Arduino IDE)

    先导知识 ESP32 入门笔记01:开发板信息、开发环境搭建以及学资料准备 ESP32 入门笔记02: GPIO参考指南 在本例中,我们使用 I2C 通信协议。ESP32 中最适合 I2C 通信的引脚是通用输入输出接口 22(SCL) 和通用输入输出接口 21(SDA) 。 安装 SSD1306 OLED 库 – ESP32 (也可以用u8g2库,在Ardu

    2024年01月19日
    浏览(25)
  • Adafruit_GFX u8g2库添加中文字体

    u8g2字体生成工具 下载完成后,将文件解压至没有中文字符的路径下。 免费字体下载网站 我这里选择下载优设标题圆这一字体。 打开解压好的字体生成工具,将下载好的ttf字体复制至font文件夹中。 并将字体文件重命名,名称不能包含中文字符,否则会转换失败。 接下来,

    2024年02月13日
    浏览(35)
  • MM32F3273G8P火龙果开发板MindSDK开发教程17 -U8g2库的移植

    手头正好有一块0.96寸的OLED屏,驱动芯片为ssd1306,心想怎么才能显示更为炫彩的图像。无意间,接触到U8g2图形库,遂决定将其移植到自己的工程中。 U8g2 是一个用于嵌入式设备的单色图形库。U8g2支持单色OLED和LCD,并支持如SSD1306等多种类型的OLED驱动。 github下载地址 我这块屏

    2024年02月09日
    浏览(22)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包