一、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