一、U8g2
- u8g2_Setup_ssd1306_i2c_128x64_noname_f
- 描述:设置 SSD1306 驱动的 128x64 I2C OLED 显示屏,不使用名称。
- 用法:
u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, rotation, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_arduino);
- u8g2_InitDisplay
- 描述:初始化显示。
- 用法:
u8g2_InitDisplay(&u8g2);
- u8g2_SetFont
- 描述:设置字体。
- 用法:
u8g2_SetFont(&u8g2, u8g2_font_ncenB08_tr);
- u8g2_DrawStr
- 描述:在屏幕上绘制字符串。
- 用法:
u8g2_DrawStr(&u8g2, x, y, "Hello World!");
- u8g2_SendBuffer
- 描述:将缓冲区的内容发送到显示屏。
- 用法:
u8g2_SendBuffer(&u8g2);
- u8g2_ClearBuffer
- 描述:清除缓冲区的内容。
- 用法:
u8g2_ClearBuffer(&u8g2);
- u8g2_DrawFrame
- 描述:在屏幕上绘制矩形框架。
- 用法:
u8g2_DrawFrame(&u8g2, x, y, width, height);
- u8g2_DrawBitmap
- 描述:在屏幕上绘制位图。
- 用法:
u8g2_DrawBitmap(&u8g2, x, y, width, height, bitmap);
- u8g2_SetContrast
- 描述:设置显示屏对比度。
- 用法:
u8g2_SetContrast(&u8g2, contrast_value);
- u8g2_SetPowerSave
- 描述:设置屏幕的电源保存模式。
- 用法:
u8g2_SetPowerSave(&u8g2, is_enable);
- u8g2_FirstPage和u8g2_NextPage
- 描述:在多页屏幕上使用,
u8g2_FirstPage
开始一个新页面,u8g2_NextPage
切换到下一个页面。
二、CubeMX配置
时钟配置
时钟树配置
板子led配置
IIC配置
rtos配置
生成工程
三、移植u8g2
下载源码地址https://github.com/olikraus/u8g2
链接: https://pan.baidu.com/s/1Uu2T2-k3lRe_FgVjWbnl8A?pwd=t3n8 提取码: t3n8
解压后将下载的csrc拷贝到工程中,并新建oled和delay两个文件
在oled文件中添加空的oled.c oled.h文件
并在代码中添加路径
添加oled路径
保存 ,新建组
添加oled和csrc两个组
然后添加函数
全部导进来,看缺什么在添加
找到u8g2_d_setup注释其他函数
void u8g2_Setup_ssd1306_i2c_128x64_noname_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_ssd1306_128x64_noname, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb); buf = u8g2_m_16_8_f(&tile_buf_height); u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation); }
找到u8g2_d_memory注释其他函数
uint8_t *u8g2_m_16_8_f(uint8_t *page_cnt) { #ifdef U8G2_USE_DYNAMIC_ALLOC *page_cnt = 8; return 0; #else static uint8_t buf[1024]; *page_cnt = 8; return buf; #endif }
oled.h
#ifndef __oled_H #define __oled_H #ifdef __cplusplus extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "u8g2.h" /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ #define u8 unsigned char // ?unsigned char ???? #define MAX_LEN 128 // #define OLED_ADDRESS 0x78 // oled?????? #define OLED_CMD 0x00 // ??? #define OLED_DATA 0x40 // ??? /* USER CODE BEGIN Prototypes */ uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); void u8g2Init(u8g2_t *u8g2); #ifdef __cplusplus } #endif #endif /*__ i2c_H */ /* USER CODE END Prototypes */
oled.c
#include "stm32f1xx_hal.h" #include "u8g2.h" #include "oled.h" #include "main.h" #include "oled.h" #include "i2c.h" uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */ static uint8_t buffer[128]; static uint8_t buf_idx; uint8_t *data; switch (msg) { case U8X8_MSG_BYTE_INIT: { /* add your custom code to init i2c subsystem */ MX_I2C1_Init(); //I2C??? } break; case U8X8_MSG_BYTE_START_TRANSFER: { buf_idx = 0; } break; case U8X8_MSG_BYTE_SEND: { data = (uint8_t *)arg_ptr; while (arg_int > 0) { buffer[buf_idx++] = *data; data++; arg_int--; } } break; case U8X8_MSG_BYTE_END_TRANSFER: { if (HAL_I2C_Master_Transmit(&hi2c1, (OLED_ADDRESS), buffer, buf_idx, 1000) != HAL_OK) return 0; } break; case U8X8_MSG_BYTE_SET_DC: break; default: return 0; } return 1; } void delay_us(uint32_t time) { uint32_t i = 8 * time; while (i--) ; } uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { switch (msg) { case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds __NOP(); break; case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds for (uint16_t n = 0; n < 320; n++) { __NOP(); } break; case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second HAL_Delay(1); break; case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz delay_us(5); break; // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us case U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pin break; // arg_int=1: Input dir with pullup high for I2C clock pin case U8X8_MSG_GPIO_I2C_DATA: // arg_int=0: Output low at I2C data pin break; // arg_int=1: Input dir with pullup high for I2C data pin case U8X8_MSG_GPIO_MENU_SELECT: u8x8_SetGPIOResult(u8x8, /* get menu select pin state */ 0); break; case U8X8_MSG_GPIO_MENU_NEXT: u8x8_SetGPIOResult(u8x8, /* get menu next pin state */ 0); break; case U8X8_MSG_GPIO_MENU_PREV: u8x8_SetGPIOResult(u8x8, /* get menu prev pin state */ 0); break; case U8X8_MSG_GPIO_MENU_HOME: u8x8_SetGPIOResult(u8x8, /* get menu home pin state */ 0); break; default: u8x8_SetGPIOResult(u8x8, 1); // default return value break; } return 1; } void u8g2Init(u8g2_t *u8g2) { u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8x8_gpio_and_delay); // ??? u8g2 ??? u8g2_InitDisplay(u8g2); // ??????????????,??????,????????? u8g2_SetPowerSave(u8g2, 0); // ????? u8g2_ClearBuffer(u8g2); }
主函数中freertos.c
/* USER CODE BEGIN Header */ /** ****************************************************************************** * File Name : freertos.c * Description : Code for freertos applications ****************************************************************************** * @attention * * Copyright (c) 2023 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "FreeRTOS.h" #include "task.h" #include "main.h" #include "cmsis_os.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "u8g2.h" #include "oled.h" #include <stdio.h> #include <stdlib.h> #include <string.h> /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ // 当前湿度和设定湿度 int current_humidity = 50; // 当前湿度 int target_humidity = 60; // 设定湿度 // 加湿器工作状态 int humidifier_status = 0; // 0表示关闭,1表示打开 /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN Variables */ /* USER CODE END Variables */ osThreadId defaultTaskHandle; /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN FunctionPrototypes */ /* USER CODE END FunctionPrototypes */ void StartDefaultTask(void const * argument); void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ /* GetIdleTaskMemory prototype (linked to static allocation support) */ void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ); /* USER CODE BEGIN GET_IDLE_TASK_MEMORY */ static StaticTask_t xIdleTaskTCBBuffer; static StackType_t xIdleStack[configMINIMAL_STACK_SIZE]; void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ) { *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer; *ppxIdleTaskStackBuffer = &xIdleStack[0]; *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* place for user code */ } /* USER CODE END GET_IDLE_TASK_MEMORY */ /** * @brief FreeRTOS initialization * @param None * @retval None */ void MX_FREERTOS_Init(void) { /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* USER CODE BEGIN RTOS_MUTEX */ /* add mutexes, ... */ /* USER CODE END RTOS_MUTEX */ /* USER CODE BEGIN RTOS_SEMAPHORES */ /* add semaphores, ... */ /* USER CODE END RTOS_SEMAPHORES */ /* USER CODE BEGIN RTOS_TIMERS */ /* start timers, add new ones, ... */ /* USER CODE END RTOS_TIMERS */ /* USER CODE BEGIN RTOS_QUEUES */ /* add queues, ... */ /* USER CODE END RTOS_QUEUES */ /* Create the thread(s) */ /* definition and creation of defaultTask */ osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128); defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL); /* USER CODE BEGIN RTOS_THREADS */ /* add threads, ... */ /* USER CODE END RTOS_THREADS */ } /* USER CODE BEGIN Header_StartDefaultTask */ /** * @brief Function implementing the defaultTask thread. * @param argument: Not used * @retval None */ /* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void const * argument) { /* USER CODE BEGIN StartDefaultTask */ /* Infinite loop */ u8g2_t u8g2; // a structure which will contain all the data for one display u8g2Init(&u8g2); // 清空缓冲区 //u8g2_ClearBuffer(&u8g2); for(;;) { // 在这里添加你的OLED显示代码 u8g2_ClearBuffer(&u8g2); u8g2_ClearBuffer(&u8g2); // 选择一个字体 u8g2_SetFont(&u8g2, u8g2_font_ncenB08_tr); // 显示当前湿度 char current_humidity_str[20]; sprintf(current_humidity_str, "Humidity: %d%%", current_humidity); u8g2_DrawStr(&u8g2, 10, 20, current_humidity_str); // 显示设定湿度 char target_humidity_str[20]; sprintf(target_humidity_str, "Set Humidity: %d%%", target_humidity); u8g2_DrawStr(&u8g2, 10, 35, target_humidity_str); // 显示加湿器状态 char status_str[20]; if (humidifier_status == 0) { strcpy(status_str, "Status: OFF"); } else { strcpy(status_str, "Status: ON"); } u8g2_DrawStr(&u8g2, 10, 50, status_str); // 发送缓冲区内容到显示屏 u8g2_SendBuffer(&u8g2); osDelay(100); } /* USER CODE END StartDefaultTask */ } /* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ /* USER CODE END Application */
链接:https://pan.baidu.com/s/1TjmONSX5vamA5MHYUQP0Mw 密码:24ml