stm32cubemx生成的HAL移植硬件SPI的u8g2(保姆级教学)

一、前言

        想要你的OLED显示丝滑,试试移植u8g2吧。我分享了两种u8g2的移植过程,一个是标准库移植,一个是cubemx移植,此文章介绍cubemx配置u8g2,需要标准库配置的可在我的上篇文章有介绍。

二、cubemx配置文件

        在cubemx下创建工程并配置相关属性。这里我使用的是stm32f103c8t6,使用7针SPI的OLED。

        配置外部时钟。

OLED引脚接线:

SCK-----PA5     

SDA-----PA7

RES-----PA4

DC-------PB0

CS-------PB1

配置GPIO

硬件SPI1的配置

时钟树配置

工程文件配置(栈空间给大点,不然后续容易卡死)

三、u8g2移植到,cubemx生成的文件

        对于github得到的u8g2文件的裁剪,网上多有此介绍,这里我直接给出裁剪后的u8g2文件,大家解压即可,方便快速移植。

        u8g2裁剪后的文件:

        链接:https://pan.baidu.com/s/1s2Oqgs7NqtwfXcNySExyWA 
        提取码:8836

        进入keil中:

将文件路径加入C/C++

加上 --no-multibyte-chars  这个标识

        在OLED.c文件中写入这些初始化代码

#include "oled.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可以将上面的注释解除,把下面不带DMA的给注释掉
			HAL_SPI_Transmit(&hspi1,(uint8_t *)arg_ptr,arg_int,200);
            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)
{
	MD_OLED_RST_Set(); //显示器复位拉高
	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); //开启显示
}

        OLED.h中写入:

#ifndef __OLED_H
#define __OLED_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);

#endif  

        不要忘记了在main.h中在用户可写代码段处定义以下宏定义:

#define OLED_CS_Pin GPIO_PIN_1
#define OLED_CS_GPIO_Port GPIOB
#define OLED_SCK_Pin GPIO_PIN_5
#define OLED_SCK_GPIO_Port GPIOA
#define OLED_MOSI_Pin GPIO_PIN_7
#define OLED_MOSI_GPIO_Port GPIOA
#define OLED_RES_Pin GPIO_PIN_4
#define OLED_RES_GPIO_Port GPIOA
#define OLED_DC_Pin GPIO_PIN_0
#define OLED_DC_GPIO_Port GPIOB

        至此移植和配置已经全部完成,接下来我们可以在main.c中测试以下

        这里我删除了一些cubemx生成的不必要的注释,只是为了给大家演示,大家不用删,只需加入相关代码即可。

#include "main.h"
//#include "dma.h"
#include "spi.h"
#include "gpio.h"

#include "u8g2.h"
#include "OLED.h"
#include "menu.h"


void SystemClock_Config(void);

void draw(u8g2_t *u8g2)
{
    u8g2_SetFont(u8g2, u8g2_font_6x12_tf);  //设定字体
    u8g2_DrawStr(u8g2, 80,36,"YYDS");    //显示字符
    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");
}

int main(void)
{
  
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  //MX_DMA_Init();
  MX_SPI1_Init();

  u8g2_t u8g2; // 显示器初始化结构体
  u8g2Init(&u8g2);   //显示器调用初始化函数

  while (1)
  {
       u8g2_FirstPage(&u8g2);
       do
       {
   			draw(&u8g2);
           
       } while (u8g2_NextPage(&u8g2));
  }
}


        最后向大家提供能运行完整的工程文件:

        链接:https://pan.baidu.com/s/1GCtnIc_pLxe0hnLN75ufXg 
        提取码:jklv

四、结语

        自此stm32的硬件SPI移植u8g2Cubemx版也完美结束,谢谢大家。

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
### 回答1: STM32CubeMX软件是一款用于生成STM32微控制器应用程序的图形化设计工具。使用它可以快速配置STM32硬件,并生成符合STM32标准的C/C++代码,以及相关的配置文件。要生成STM32SPI驱动程序,首先需要在STM32CubeMX软件中配置SPI硬件,然后生成C/C++代码并编译,最后将编译好的文件链接到相应的应用程序中即可。 ### 回答2: STM32CubeMX软件是针对ST微电子的STM32系列微控制器的开发工具。它提供了一个图形化的界面,使得开发人员可以轻松地生成C代码的启动文件和初始化配置,以及相关外设驱动程序。 要使用STM32CubeMX软件生成STM32SPI驱动程序,可以按照以下步骤进行操作: 1. 下载和安装STM32CubeMX软件,并启动它。 2. 在工程窗口中选择要使用的STM32微控制器型号,并创建一个新项目。 3. 在配置栏中选择"GPIO"选项卡,启用所需的SPI引脚。 4. 在配置栏中选择"RCC"选项卡,配置系统时钟和外设时钟使能。 5. 在配置栏中选择"SPI"选项卡,并启用SPI外设,并进行相关配置,如主从模式、传输速率、数据位数等。 6. 在NVIC配置中启用SPI外设中断(如果需要)。 7. 点击"生成代码"按钮,STM32CubeMX生成相关的C代码并自动保存。 8. 在生成的代码中,可以找到SPI初始化函数,例如"HAL_SPI_Init()",在主函数中调用此函数进行SPI外设的初始化。 9. 通过适当的SPI发送和接收函数调用,可以在应用程序中使用SPI外设进行通信。 总结来说,使用STM32CubeMX软件生成STM32SPI驱动程序的步骤包括选择目标微控制器型号、配置SPI引脚和参数、生成代码并保存、初始化SPI外设,并在应用程序中使用SPI函数进行通信。这个工具可以大大简化SPI驱动程序的生成过程,提高开发效率。 ### 回答3: 使用STM32CubeMX软件生成STM32SPI驱动程序很简单。下面是具体的步骤: 1. 下载并安装STM32CubeMX软件,并打开软件。 2. 在软件界面的左侧,选择需要使用的STM32系列微控制器。 3. 在"Pinout & Configuration"选项卡中,选择需要使用的SPI接口。如果需要使用多个SPI接口,可以在"Peripherals"列表中选择并启用多个SPI接口。 4. 在"Pinout & Configuration"选项卡中,为SPI接口选择引脚。单击需要选择的引脚,在弹出的菜单中选择对应的引脚功能。确保引脚选择符合硬件连接的需求。 5. 在"Configuration"选项卡中,设置SPI的各种参数。这些参数包括时钟极性、时钟相位、数据位长度、数据传输模式等。如果需要使用硬件NSS信号,也可以在这里设置。 6. 在"Initialization"选项卡中,选择SPI的初始化方法。可以选择使用HAL库还是LL库初始化SPI。 7. 在"Preparation"选项卡中,可以进行其他相关设置,比如中断优先等。 8. 确认所有的设置后,单击界面下方的"GENERATE CODE"按钮,生成工程代码。 9. 打开生成的工程代码,找到SPI驱动程序所在的文件。通常情况下,SPI驱动程序会在"main.c"或者其他自动生成的文件中。 10. 根据生成的代码,调用对应的函数来控制SPI接口进行数据传输。通常情况下,生成的代码已经包含了SPI的初始化和数据传输的相关函数。 总之,使用STM32CubeMX软件生成STM32SPI驱动程序只需要进行简单的配置和参数设置,然后点击生成代码即可。生成的代码中已经包含了SPI的初始化和数据传输函数,可以直接调用和使用。使用这些生成的函数,可以轻松地控制STM32SPI接口进行数据传输。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫色小薇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值