STM32的使用:u8g2

U8g2

  • U8g2 是一个用于控制 OLED 和 LCD 显示器的开源库,特别适用于各种微控制器和嵌入式系统。它支持 I2C、SPI 等通信方式
  • 使用的OLED上使用的是IIC协议
  • 使用步骤
  • 开启I2C1的模式为I2C,配置其SPeed Mode模式为Fast Mode
  • 开启RCC为Crystal,配置时钟电路为64Mhz
  • USART1为异步通信(串口连接在这里,故要使用)
  • 在Core下放置u8g2_port文件夹,并在project-》properties中添加其路径,文件夹都要添加途径,子文件夹也一样,如下图
  • 在这里插入图片描述
  • 使用方法
1. u8g2_t u8g2;//在main函数外定义好u8g2的结构体,存储u8g2的东西
2.  u8g2_Init(&u8g2, &hi2c1, 0x78);//初始化 U8g2 库,使其能够通过 I2C 接口与 OLED 显示屏进行通信。
//0x78是I2C设备的地址0x3C左移一位得到
可以通过调用该函数查看I2C设备上挂载的地址
void I2C_Scan(void)
{
    HAL_StatusTypeDef result;
    uint8_t i;
    printf("Scanning I2C bus...\r\n");

    for (i = 1; i < 128; i++) // I2C 地址范围为 7 位,所以是 1 到 127
    {
        result = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i << 1), 1, 10);
        if (result == HAL_OK) // 如果设备准备好,则地址有效
        {
            printf("I2C device found at address 0x%02X\r\n", i);
        }
    }
    printf("Scan complete.\r\n");
}
3. u8g2_ClearBuffer(&u8g2);//每次绘制之前清除屏幕
4. 绘制完成后,调用 u8g2_SendBuffer() 将缓冲区中的数据发送到 OLED 显示屏
5. u8g2_SetFont(&u8g2, u8g2_font_ncenB08_tr);//设置字体
6. u8g2_DrawStr(&u8g2, 0, 24, "Hello, STM32!");//绘制字符串
7. u8g2_DrawHLine(&u8g2, 10, 30, 50);// 从坐标 (10, 30) 开始绘制一条长度为 50 像素的水平线
8. u8g2_DrawBox(&u8g2, 10, 10, 50, 20);// 在 (10, 10) 位置绘制一个宽 50、高 20 的填充矩形
9. 玩花的还可以在一张图片显示后,再延迟显示另一个。
10. 等等
 


示例代码
#include "main.h"                // 包含主头文件
#include "u8g2.h"                // 包含U8g2库头文件

u8g2_t u8g2;                     // 定义一个u8g2结构体,用于存储OLED显示相关的信息

I2C_HandleTypeDef hi2c1;         // 定义一个I2C句柄结构体,用于配置I2C1接口
UART_HandleTypeDef huart1;       // 定义一个UART句柄结构体,用于配置UART1接口

void SystemClock_Config(void);   // 系统时钟配置函数声明
static void MX_GPIO_Init(void);  // GPIO初始化函数声明
static void MX_I2C1_Init(void);  // I2C1初始化函数声明
static void MX_USART1_UART_Init(void);  // USART1 UART初始化函数声明
#include "stdio.h"               // 包含标准输入输出库,用于打印信息

void I2C_Scan(void)              // 定义I2C总线扫描函数
{
    HAL_StatusTypeDef result;    // 定义一个变量,用于存储I2C设备状态
    uint8_t i;                   // 定义一个8位变量用于存储I2C地址
    printf("Scanning I2C bus...\r\n");  // 打印扫描信息

    for (i = 1; i < 128; i++)    // 循环遍历I2C的所有可能地址范围(1-127)
    {
        result = HAL_I2C_IsDeviceReady(&hi2c1, (uint16_t)(i << 1), 1, 10);  // 检查当前地址的设备是否准备好
        if (result == HAL_OK)    // 如果设备存在
        {
            printf("I2C device found at address 0x%02X\r\n", i);  // 打印找到的设备地址
        }
    }
    printf("Scan complete.\r\n");  // 打印扫描完成信息
}

int __io_putchar(int ch)         // 重定向标准输出到UART
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);  // 通过UART发送字符
    return ch;                  // 返回字符
}

int main(void)                   // 主函数
{
    HAL_Init();                  // 初始化硬件抽象层库
    SystemClock_Config();         // 配置系统时钟
    MX_GPIO_Init();               // 初始化GPIO
    MX_I2C1_Init();               // 初始化I2C1
    MX_USART1_UART_Init();        // 初始化USART1 UART

    u8g2_Init(&u8g2, &hi2c1, 0x78);  // 初始化u8g2库,指定使用I2C1和0x78的OLED地址
    u8g2_SetFont(&u8g2, u8g2_font_9x15_tr);  // 设置字体为9x15像素
    u8g2_DrawBox(&u8g2, 0, 18, 30, 20);  // 在OLED屏幕上绘制一个起始点(0, 18),宽30高20的矩形
    u8g2_SetFontPosTop(&u8g2);  // 设置字体位置为顶部对齐

    u8g2_DrawStr(&u8g2, 0, 0, "hello world!!!");  // 在OLED屏幕上绘制字符串 "hello world!!!"
    u8g2_DrawPixel(&u8g2, 0, 16);  // 在OLED屏幕上的(0, 16)位置绘制一个像素点
    u8g2_SendBuffer(&u8g2);  // 将缓冲区中的内容发送到OLED屏幕

    I2C_Scan();               // 扫描I2C总线

    while (1)                 // 无限循环
    {
    }
}

void SystemClock_Config(void)   // 系统时钟配置函数
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};  // 初始化时钟结构体
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};  // 初始化时钟配置结构体

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  // 配置HSE作为外部晶振
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;   // 启用HSE外部晶振
    RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;  // 设置HSE预分频为1
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;   // 启用内部高速时钟HSI
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;  // 启用锁相环PLL
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;  // 配置PLL时钟源为HSE
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;  // 设置PLL倍频因子为8
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)  // 检查配置是否成功
    {
        Error_Handler();  // 如果失败则进入错误处理
    }

    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;  // 配置HCLK, SYSCLK, PCLK1, PCLK2的时钟类型
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;  // 设置系统时钟源为PLL
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;  // 设置AHB时钟分频为1
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;  // 设置APB1时钟分频为2
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  // 设置APB2时钟分频为1

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)  // 应用时钟配置
    {
        Error_Handler();  // 如果失败则进入错误处理
    }
}

static void MX_I2C1_Init(void)  // I2C1初始化函数
{
    hi2c1.Instance = I2C1;  // 设置I2C1实例
    hi2c1.Init.ClockSpeed = 400000;  // 设置I2C时钟速度为400kHz
    hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;  // 设置占空比为2
    hi2c1.Init.OwnAddress1 = 0;  // 不设置自身地址
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;  // 设置7位地址模式
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;  // 禁用双地址模式
    hi2c1.Init.OwnAddress2 = 0;  // 不设置第二地址
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;  // 禁用I2C总线的全局呼叫
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;  // 禁用时钟拉伸
    if (HAL_I2C_Init(&hi2c1) != HAL_OK)  // 检查I2C初始化是否成功
    {
        Error_Handler();  // 如果失败则进入错误处理
    }
}

static void MX_USART1_UART_Init(void)  // USART1 UART初始化函数
{
    huart1.Instance = USART1;  // 设置USART1实例
    huart1.Init.BaudRate = 115200;  // 设置波特率为115200
    huart1.Init.WordLength = UART_WORDLENGTH_8B;  // 设置数据位长度为8位
    huart1.Init.StopBits = UART_STOPBITS_1;  // 设置停止位为1位
    huart1.Init.Parity = UART_PARITY_NONE;  // 禁用奇偶校验
    huart1.Init.Mode = UART_MODE_TX_RX;  // 设置UART模式为收发
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;  // 禁用硬件流控
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;  // 设置16倍过采样
    if (HAL_UART_Init(&huart1) != HAL_OK)  // 检查UART初始化是否成功
    {
        Error_Handler();  // 如果失败则进入错误处理
    }
}

static void MX_GPIO_Init(void)  // GPIO初始化函数
{
    __HAL_RCC_GPIOD_CLK_ENABLE();  // 启用GPIOD时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();  // 启用GPIOA时钟
    __HAL_RCC_GPIOB_CLK_ENABLE();  // 启用GPIOB时钟
}

void Error_Handler(void)  // 错误处理函数
{
    __disable_irq();  // 禁用中断
    while (1)         // 无限循环,系统卡在这里
    {
    }
}

#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)  // 断言失败时的处理函数
{
}
#endif

  • 对于绘制图片可以有更简便的方法
1.将图片保存为bmp格式
2.https://shequ.stmicroelectronics.cn/thread-616886-1-1.html这个取模工具
3.2的软件给出取模
4.u8g2_DrawXBMP();//用该函数绘制图片
5.代码示例

#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include "u8g2.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

u8g2_t u8g2;			//定义结构体,存储u8g2库的东西

/* const修饰数组,不可变,惠存如在flash中.*/
const unsigned char hellokitty[]={		/* (48 X 48 )*/
	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C ,
	 0x3C,0x00,0x00,0x7C,0x00,0xFC,0x67,0x00,0x00,0xC6,0xFF,0xFF,0x41,0x00,0x00,0x02,0x3F,0xFF,0x41,0x00,0x00,0x03,0x00,0xFF,0xC3,0x00,0x00,0x03,0x00,0xFF,0xFF,0x00,0x00,0x03,0x00,0xFF,0xFF,0x01,0x00,0x03,0x00,0xFF,0xFF,0x01,0x00,0x06,0x00,0xFF,0xFF,0x01,0x00,0x02,0x00,0xFE,0xFF,0x01,0x00,0x03,0x00,0x80,0xFF,0x01,0x00,0x01 ,
	 0x00,0x00,0xFC,0x00,0x00,0x01,0x00,0x00,0xF8,0x00,0x80,0x01,0x00,0x00,0x90,0x01,0x80,0x00,0x00,0x00,0x80,0x01,0x80,0x00,0x00,0x00,0x80,0x07,0xF0,0x03,0x00,0x00,0xC0,0x01,0x80,0x81,0x01,0x80,0x81,0x01,0x80,0xC1,0x01,0x80,0x81,0x01,0x00,0x81,0x00,0x80,0xC1,0x07,0xC0,0x03,0xC0,0x03,0x80,0x00,0x00,0x03,0xC0,0x03,0xC0,0x00 ,
	 0x00,0x0E,0x00,0x00,0xE0,0x00,0x00,0x0E,0x00,0x00,0xE0,0x01,0x80,0x19,0x00,0x00,0x30,0x02,0x80,0x70,0x00,0x00,0x1C,0x00,0x00,0xC0,0x03,0x80,0x07,0x00,0x00,0x00,0xFE,0xFF,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,
	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};


const unsigned char  hanziku[14][ 32 ] = {
		// 西(0) 游(1) 记(2) 孙(3) 悟(4) 空(5) 猪(6) 八(7) 戒(8) 唐(9) 增(10) 沙(11) 悟(12) 净(13)
		{0x00,0x00,0xFF,0x7F,0x20,0x02,0x20,0x02,0x20,0x02,0xFC,0x1F,0x24,0x12,0x24,0x12,0x24,0x12,0x24,0x12,0x14,0x1C,0x0C,0x10,0x04,0x10,0x04,0x10,0xFC,0x1F,0x04,0x10},/*"西",0*/
		/* (16 X 16 , 宋体 )*/

		{0x40,0x08,0x84,0x08,0x88,0x08,0xE8,0x7D,0x41,0x04,0x42,0x02,0xC2,0x3D,0x48,0x21,0x48,0x11,0x44,0x11,0x47,0x7D,0x44,0x11,0x24,0x11,0x24,0x11,0x94,0x15,0x08,0x08},/*"游",1*/
		/* (16 X 16 , 宋体 )*/

		{0x00,0x00,0x04,0x00,0x88,0x1F,0x08,0x10,0x00,0x10,0x00,0x10,0x0F,0x10,0x88,0x1F,0x88,0x10,0x88,0x00,0x88,0x00,0x88,0x00,0xA8,0x40,0x98,0x40,0x08,0x7F,0x00,0x00},/*"记",2*/
		/* (16 X 16 , 宋体 )*/

		{0x00,0x04,0x7E,0x04,0x40,0x04,0x20,0x04,0x10,0x04,0x10,0x15,0x50,0x25,0x30,0x25,0x9C,0x44,0x93,0x44,0x50,0x44,0x10,0x04,0x10,0x04,0x10,0x04,0x14,0x05,0x08,0x02},/*"孙",3*/
		/* (16 X 16 , 宋体 )*/

		{0x08,0x00,0xC8,0x7F,0x08,0x02,0x08,0x02,0x98,0x3F,0x2A,0x21,0x0A,0x21,0xCA,0x7F,0x09,0x00,0x08,0x00,0x88,0x3F,0x88,0x20,0x88,0x20,0x88,0x20,0x88,0x3F,0x88,0x20},/*"悟",4*/
		/* (16 X 16 , 宋体 )*/

		{0x40,0x00,0x80,0x00,0xFE,0x7F,0x02,0x40,0x11,0x24,0x08,0x08,0x04,0x10,0x00,0x00,0xF8,0x0F,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0xFE,0x3F,0x00,0x00},/*"空",5*/
		/* (16 X 16 , 宋体 )*/

		{0x00,0x02,0x11,0x22,0xCA,0x2F,0x04,0x12,0x0A,0x0A,0xE9,0x7F,0x08,0x02,0x08,0x01,0x8C,0x1F,0xCA,0x10,0xA9,0x10,0x88,0x1F,0x88,0x10,0x88,0x10,0x85,0x1F,0x82,0x10},/*"猪",6*/
		/* (16 X 16 , 宋体 )*/

		{0x00,0x00,0x00,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x04,0x10,0x04,0x10,0x04,0x10,0x08,0x08,0x08,0x08,0x10,0x04,0x10,0x04,0x20,0x02,0x40},/*"八",7*/
		/* (16 X 16 , 宋体 )*/

		{0x00,0x12,0x00,0x22,0x00,0x02,0xFF,0x7F,0x00,0x02,0x48,0x02,0x48,0x22,0x48,0x22,0xFE,0x22,0x48,0x14,0x48,0x14,0x48,0x48,0x44,0x4C,0x44,0x52,0x02,0x61,0xC0,0x40},/*"戒",8*/
		/* (16 X 16 , 宋体 )*/

		{0x80,0x00,0x00,0x01,0xFC,0x7F,0x04,0x01,0xF4,0x1F,0x04,0x11,0xFC,0x7F,0x04,0x11,0xF4,0x1F,0x04,0x01,0xF4,0x1F,0x14,0x10,0x12,0x10,0x12,0x10,0xF1,0x1F,0x10,0x10},/*"唐",9*/
		/* (16 X 16 , 宋体 )*/

		{0x44,0x10,0x84,0x08,0x04,0x00,0xE4,0x3F,0x24,0x22,0xBF,0x2A,0x24,0x27,0x24,0x22,0xE4,0x3F,0x04,0x00,0xC4,0x1F,0x5C,0x10,0xC7,0x1F,0x42,0x10,0xC0,0x1F,0x40,0x10},/*"增",10*/
		/* (16 X 16 , 宋体 )*/

		{0x00,0x02,0x04,0x02,0x08,0x02,0x88,0x12,0x81,0x22,0x42,0x42,0x42,0x42,0x28,0x12,0x08,0x12,0x04,0x12,0x07,0x08,0x04,0x08,0x04,0x04,0x04,0x02,0x84,0x01,0x60,0x00},/*"沙",11*/
		/* (16 X 16 , 宋体 )*/

		{0x08,0x00,0xC8,0x7F,0x08,0x02,0x08,0x02,0x98,0x3F,0x2A,0x21,0x0A,0x21,0xCA,0x7F,0x09,0x00,0x08,0x00,0x88,0x3F,0x88,0x20,0x88,0x20,0x88,0x20,0x88,0x3F,0x88,0x20},/*"悟",12*/
		/* (16 X 16 , 宋体 )*/

		{0x80,0x00,0x82,0x00,0xC4,0x0F,0x24,0x08,0x00,0x04,0xE8,0x3F,0x08,0x22,0x08,0x22,0xF4,0x7F,0x04,0x22,0x07,0x22,0xE4,0x3F,0x04,0x22,0x04,0x02,0x84,0x02,0x00,0x01},/*"净",13*/
		/* (16 X 16 , 宋体 )*/
};


I2C_HandleTypeDef hi2c1;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART1_UART_Init(void);

int main(void)
{

  HAL_Init();


  SystemClock_Config();


  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  u8g2_Init(&u8g2, &hi2c1, 0x78);
  u8g2_SetFont(&u8g2,  u8g2_font_9x15_tr);	// u8g2_font_unifont_t_chinese3
  u8g2_SetFontPosTop(&u8g2);				// 设备字体参考位置 左下角

  /*绘制英文文字过程*/
  u8g2_ClearBuffer(&u8g2);
  u8g2_DrawStr(&u8g2, 0,0,"hello u8g2!");
  //u8g2_DrawStrX2(&u8g2, 0,0,"hello u8g2!");		//放大一倍,锯齿感
  //u8g2_SendBuffer(&u8g2);

  /*绘制一个点 */
  //u8g2_ClearBuffer(&u8g2);
  u8g2_DrawPixel(&u8g2, 0, 16);
  //绘制一条线
  u8g2_DrawLine(&u8g2, 10, 16, 50, 16);
  //绘制 box--实心矩形
  u8g2_DrawBox(&u8g2, 0,18, 30, 20);
  //绘制frame,虚心 矩形
  u8g2_DrawFrame(&u8g2, 35, 18, 30, 20);

  //圆角矩形-实心的
  u8g2_DrawRBox(&u8g2, 65, 18,  30,20,    8);
  //圆角矩形-虚心
  u8g2_DrawRFrame(&u8g2, 95, 18, 30,20 , 7);

  u8g2_SendBuffer(&u8g2);

  HAL_Delay(1000);

  u8g2_ClearBuffer(&u8g2);
  u8g2_DrawCircle(&u8g2,  32,32,    30,   	U8G2_DRAW_UPPER_RIGHT|U8G2_DRAW_LOWER_LEFT);
  u8g2_DrawDisc(&u8g2,    32,32,    25,   	U8G2_DRAW_UPPER_RIGHT|U8G2_DRAW_LOWER_LEFT);


  //画虚心椭圆
  u8g2_DrawEllipse(&u8g2, 90,30,	30, 20,		U8G2_DRAW_ALL);
  //实心椭圆
  u8g2_DrawFilledEllipse(&u8g2,  90,30,  25,18,   U8G2_DRAW_ALL);

  u8g2_SendBuffer(&u8g2);

  HAL_Delay(1000);


  u8g2_ClearBuffer(&u8g2);
  //画三角形
  u8g2_DrawTriangle(&u8g2, 15,0,  0,30, 30,30);

  //画 汉字
  u8g2_SetFont(&u8g2,  u8g2_font_unifont_t_chinese3);		//中文字库,包含英文
  u8g2_SetFontPosTop(&u8g2);				// 设备字体参考位置 左下角

  u8g2_DrawUTF8(&u8g2, 30, 0, "欢迎界面");
  u8g2_DrawUTF8X2(&u8g2, 0, 30, "菜单确定取消");

  u8g2_SendBuffer(&u8g2);


  u8g2_ClearBuffer(&u8g2);
  //绘制bmp图像
  u8g2_DrawXBMP(&u8g2, 5, 10, 48, 48, hellokitty);

  for(int i=0;i<3;i++){
	  u8g2_DrawXBM(&u8g2,  60+16*i,  10,   16,16,  hanziku[i] );
  }


  u8g2_SendBuffer(&u8g2);



  while (1)
  {
   
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief I2C1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C1_Init(void)
{


  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}


static void MX_USART1_UART_Init(void)
{


  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */


void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)
{

}
#endif /* USE_FULL_ASSERT */


STMicroelectronics(ST)是一家微控制器和半导体解决方案的供应商,其产品STM32是一种功能强大的微控制器系列。U8g2是一款开源的用于驱动显示屏的库,它提供了对许多不同显示屏的支持。在STM32上移植U8g2使用软件模拟SPI的方法如下: 首先,在STM32的开发环境中创建一个新的项目,并包含U8g2库的文件。确保安装了适用于STM32的C编译器和开发工具。 然后,阅读U8g2库的文档,了解如何在STM32使用软件模拟的SPI进行通信。通常,这涉及到定义和配置GPIO引脚,以及模拟SPI时钟、数据线和片选线等。 接下来,使用STM32的GPIO库函数进行引脚的初始化和配置。根据U8g2库的文档,将相关的GPIO引脚配置为软件模拟SPI所需的输入和输出。 然后,根据U8g2库的文档,编写适配代码来实现软件模拟的SPI通信。这涉及到模拟SPI时钟、数据线和片选线的读写操作。可以使用STM32的GPIO库函数来控制引脚的电平。 最后,根据项目的需求,使用U8g2库的函数来初始化和控制显示屏。这些函数通常包括设置显示屏的尺寸、清除屏幕内容、绘制图形和显示文本等。 在完成以上步骤后,可以使用STM32的开发工具编译和烧录代码到目标设备上,然后运行程序。如果一切顺利,显示屏应该能够正常工作,并显示预期的内容。 需要注意的是,软件模拟SPI可能会导致通信的速度较慢,因为它依赖于处理器的计算能力。如果需要更高的通信速度,可以考虑使用硬件SPI接口。 总之,将U8g2库移植到STM32使用软件模拟的SPI进行通信需要对STM32的GPIO库函数和U8g2库的文档有一定的了解。同时,根据具体的项目需求进行适配和调试,以确保显示屏能够正确工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值