mirror of
https://github.com/goldenfishs/MRobot.git
synced 2025-04-28 23:39:55 +08:00
添加了些新模块
This commit is contained in:
parent
b27fc87089
commit
3f477172f2
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BSP_OK (0)
|
||||
#define BSP_ERR (-1)
|
||||
#define BSP_ERR_NULL (-2)
|
||||
#define BSP_ERR_INITED (-3)
|
||||
#define BSP_ERR_NO_DEV (-4)
|
||||
|
||||
#define SIGNAL_BSP_USB_BUF_RECV (1u << 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
104
User/bsp/i2c.c
Normal file
104
User/bsp/i2c.c
Normal file
@ -0,0 +1,104 @@
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include "bsp\i2c.h"
|
||||
|
||||
/* Private define ----------------------------------------------------------- */
|
||||
/* Private macro ------------------------------------------------------------ */
|
||||
/* Private typedef ---------------------------------------------------------- */
|
||||
/* Private variables -------------------------------------------------------- */
|
||||
static void (*I2C_Callback[BSP_I2C_NUM][BSP_I2C_CB_NUM])(void);
|
||||
|
||||
/* Private function -------------------------------------------------------- */
|
||||
static BSP_I2C_t I2C_Get(I2C_HandleTypeDef *hi2c) {
|
||||
if (hi2c->Instance == I2C1) return BSP_I2C_OLED;
|
||||
else
|
||||
return BSP_I2C_ERR;
|
||||
}
|
||||
|
||||
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) {
|
||||
BSP_I2C_t bsp_i2c = I2C_Get(hi2c);
|
||||
if (bsp_i2c != BSP_I2C_ERR) {
|
||||
if (I2C_Callback[bsp_i2c][HAL_I2C_MASTER_TX_CPLT_CB])
|
||||
I2C_Callback[bsp_i2c][HAL_I2C_MASTER_TX_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) {
|
||||
BSP_I2C_t bsp_i2c = I2C_Get(hi2c);
|
||||
if (bsp_i2c != BSP_I2C_ERR) {
|
||||
if (I2C_Callback[bsp_i2c][HAL_I2C_MASTER_RX_CPLT_CB])
|
||||
I2C_Callback[bsp_i2c][HAL_I2C_MASTER_RX_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) {
|
||||
BSP_I2C_t bsp_i2c = I2C_Get(hi2c);
|
||||
if (bsp_i2c != BSP_I2C_ERR) {
|
||||
if (I2C_Callback[bsp_i2c][HAL_I2C_SLAVE_TX_CPLT_CB])
|
||||
I2C_Callback[bsp_i2c][HAL_I2C_SLAVE_TX_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) {
|
||||
BSP_I2C_t bsp_i2c = I2C_Get(hi2c);
|
||||
if (bsp_i2c != BSP_I2C_ERR) {
|
||||
if (I2C_Callback[bsp_i2c][HAL_I2C_SLAVE_RX_CPLT_CB])
|
||||
I2C_Callback[bsp_i2c][HAL_I2C_SLAVE_RX_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) {
|
||||
BSP_I2C_t bsp_i2c = I2C_Get(hi2c);
|
||||
if (bsp_i2c != BSP_I2C_ERR) {
|
||||
if (I2C_Callback[bsp_i2c][HAL_I2C_LISTEN_CPLT_CB])
|
||||
I2C_Callback[bsp_i2c][HAL_I2C_LISTEN_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c) {
|
||||
BSP_I2C_t bsp_i2c = I2C_Get(hi2c);
|
||||
if (bsp_i2c != BSP_I2C_ERR) {
|
||||
if (I2C_Callback[bsp_i2c][HAL_I2C_MEM_TX_CPLT_CB])
|
||||
I2C_Callback[bsp_i2c][HAL_I2C_MEM_TX_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) {
|
||||
BSP_I2C_t bsp_i2c = I2C_Get(hi2c);
|
||||
if (bsp_i2c != BSP_I2C_ERR) {
|
||||
if (I2C_Callback[bsp_i2c][HAL_I2C_MEM_RX_CPLT_CB])
|
||||
I2C_Callback[bsp_i2c][HAL_I2C_MEM_RX_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) {
|
||||
BSP_I2C_t bsp_i2c = I2C_Get(hi2c);
|
||||
if (bsp_i2c != BSP_I2C_ERR) {
|
||||
if (I2C_Callback[bsp_i2c][HAL_I2C_ERROR_CB])
|
||||
I2C_Callback[bsp_i2c][HAL_I2C_ERROR_CB]();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c) {
|
||||
BSP_I2C_t bsp_i2c = I2C_Get(hi2c);
|
||||
if (bsp_i2c != BSP_I2C_ERR) {
|
||||
if (I2C_Callback[bsp_i2c][HAL_I2C_ABORT_CPLT_CB])
|
||||
I2C_Callback[bsp_i2c][HAL_I2C_ABORT_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
I2C_HandleTypeDef *BSP_I2C_GetHandle(BSP_I2C_t i2c) {
|
||||
switch (i2c) {
|
||||
case BSP_I2C_OLED:
|
||||
return &hi2c1;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int8_t BSP_I2C_RegisterCallback(BSP_I2C_t i2c, BSP_I2C_Callback_t type,
|
||||
void (*callback)(void)) {
|
||||
if (callback == NULL) return BSP_ERR_NULL;
|
||||
I2C_Callback[i2c][type] = callback;
|
||||
return BSP_OK;
|
||||
}
|
43
User/bsp/i2c.h
Normal file
43
User/bsp/i2c.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include <i2c.h>
|
||||
|
||||
#include "bsp/bsp.h"
|
||||
|
||||
/* Exported constants ------------------------------------------------------- */
|
||||
/* Exported macro ----------------------------------------------------------- */
|
||||
/* Exported types ----------------------------------------------------------- */
|
||||
/* I2C实体枚举,与设备对应 */
|
||||
typedef enum {
|
||||
BSP_I2C_OLED,
|
||||
BSP_I2C_NUM,
|
||||
BSP_I2C_ERR,
|
||||
} BSP_I2C_t;
|
||||
|
||||
/* I2C支持的中断回调函数类型,具体参考HAL中定义 */
|
||||
typedef enum {
|
||||
HAL_I2C_MASTER_TX_CPLT_CB,
|
||||
HAL_I2C_MASTER_RX_CPLT_CB,
|
||||
HAL_I2C_SLAVE_TX_CPLT_CB,
|
||||
HAL_I2C_SLAVE_RX_CPLT_CB,
|
||||
HAL_I2C_LISTEN_CPLT_CB,
|
||||
HAL_I2C_MEM_TX_CPLT_CB,
|
||||
HAL_I2C_MEM_RX_CPLT_CB,
|
||||
HAL_I2C_ERROR_CB,
|
||||
HAL_I2C_ABORT_CPLT_CB,
|
||||
BSP_I2C_CB_NUM,
|
||||
} BSP_I2C_Callback_t;
|
||||
|
||||
/* Exported functions prototypes -------------------------------------------- */
|
||||
I2C_HandleTypeDef *BSP_I2C_GetHandle(BSP_I2C_t i2c);
|
||||
int8_t BSP_I2C_RegisterCallback(BSP_I2C_t i2c, BSP_I2C_Callback_t type,
|
||||
void (*callback)(void));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
61
User/bsp/led.c
Normal file
61
User/bsp/led.c
Normal file
@ -0,0 +1,61 @@
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include "bsp\led.h"
|
||||
|
||||
#include <tim.h>
|
||||
|
||||
/* Private define ----------------------------------------------------------- */
|
||||
/* Private macro ------------------------------------------------------------ */
|
||||
/* Private typedef ---------------------------------------------------------- */
|
||||
/* Private variables -------------------------------------------------------- */
|
||||
static uint32_t led_stats;
|
||||
|
||||
/* Private function -------------------------------------------------------- */
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
int8_t BSP_LED_Set(BSP_LED_Channel_t ch, BSP_LED_Status_t s, float duty_cycle) {
|
||||
if (duty_cycle > 1.0f) return BSP_ERR;
|
||||
|
||||
uint32_t tim_ch;
|
||||
uint16_t pulse = (uint16_t)(duty_cycle * (float)UINT16_MAX);
|
||||
|
||||
switch (ch) {
|
||||
case BSP_LED_1:
|
||||
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, pulse);
|
||||
tim_ch = TIM_CHANNEL_2;
|
||||
break;
|
||||
|
||||
case BSP_LED_2:
|
||||
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, pulse);
|
||||
tim_ch = TIM_CHANNEL_3;
|
||||
break;
|
||||
|
||||
case BSP_LED_3:
|
||||
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_4, pulse);
|
||||
tim_ch = TIM_CHANNEL_1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (s) {
|
||||
case BSP_LED_ON:
|
||||
HAL_TIM_PWM_Start(&htim2, tim_ch);
|
||||
led_stats |= tim_ch;
|
||||
break;
|
||||
|
||||
case BSP_LED_OFF:
|
||||
HAL_TIM_PWM_Stop(&htim2, tim_ch);
|
||||
led_stats &= ~tim_ch;
|
||||
break;
|
||||
|
||||
case BSP_LED_TAGGLE:
|
||||
if (led_stats & tim_ch) {
|
||||
HAL_TIM_PWM_Stop(&htim2, tim_ch);
|
||||
led_stats &= ~tim_ch;
|
||||
} else {
|
||||
HAL_TIM_PWM_Start(&htim2, tim_ch);
|
||||
led_stats |= tim_ch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return BSP_OK;
|
||||
}
|
36
User/bsp/led.h
Normal file
36
User/bsp/led.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include <stdint.h>
|
||||
|
||||
#include "bsp/bsp.h"
|
||||
|
||||
/* Exported constants ------------------------------------------------------- */
|
||||
/* Exported macro ----------------------------------------------------------- */
|
||||
/* Exported types ----------------------------------------------------------- */
|
||||
|
||||
/* LED灯状态,设置用 */
|
||||
typedef enum {
|
||||
BSP_LED_ON,
|
||||
BSP_LED_OFF,
|
||||
BSP_LED_TAGGLE,
|
||||
} BSP_LED_Status_t;
|
||||
|
||||
/* LED通道 */
|
||||
typedef enum {
|
||||
BSP_LED_1,
|
||||
BSP_LED_2,
|
||||
BSP_LED_3,
|
||||
} BSP_LED_Channel_t;
|
||||
|
||||
/* Exported functions prototypes -------------------------------------------- */
|
||||
|
||||
int8_t BSP_LED_Set(BSP_LED_Channel_t ch, BSP_LED_Status_t s, float duty_cycle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
114
User/bsp/uart.c
Normal file
114
User/bsp/uart.c
Normal file
@ -0,0 +1,114 @@
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include "bsp\uart.h"
|
||||
|
||||
/* Private define ----------------------------------------------------------- */
|
||||
/* Private macro ------------------------------------------------------------ */
|
||||
/* Private typedef ---------------------------------------------------------- */
|
||||
/* Private variables -------------------------------------------------------- */
|
||||
static void (*UART_Callback[BSP_UART_NUM][BSP_UART_CB_NUM])(void);
|
||||
|
||||
/* Private function -------------------------------------------------------- */
|
||||
static BSP_UART_t UART_Get(UART_HandleTypeDef *huart) {
|
||||
if (huart->Instance == USART1)
|
||||
return BSP_UART_SINDT;
|
||||
else
|
||||
return BSP_UART_ERR;
|
||||
}
|
||||
|
||||
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
|
||||
BSP_UART_t bsp_uart = UART_Get(huart);
|
||||
if (bsp_uart != BSP_UART_ERR) {
|
||||
if (UART_Callback[bsp_uart][BSP_UART_TX_CPLT_CB]) {
|
||||
UART_Callback[bsp_uart][BSP_UART_TX_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) {
|
||||
BSP_UART_t bsp_uart = UART_Get(huart);
|
||||
if (bsp_uart != BSP_UART_ERR) {
|
||||
if (UART_Callback[bsp_uart][BSP_UART_TX_HALF_CPLT_CB]) {
|
||||
UART_Callback[bsp_uart][BSP_UART_TX_HALF_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
|
||||
BSP_UART_t bsp_uart = UART_Get(huart);
|
||||
if (bsp_uart != BSP_UART_ERR) {
|
||||
if (UART_Callback[bsp_uart][BSP_UART_RX_CPLT_CB]) {
|
||||
UART_Callback[bsp_uart][BSP_UART_RX_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) {
|
||||
BSP_UART_t bsp_uart = UART_Get(huart);
|
||||
if (bsp_uart != BSP_UART_ERR) {
|
||||
if (UART_Callback[bsp_uart][BSP_UART_RX_HALF_CPLT_CB]) {
|
||||
UART_Callback[bsp_uart][BSP_UART_RX_HALF_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
|
||||
BSP_UART_t bsp_uart = UART_Get(huart);
|
||||
if (bsp_uart != BSP_UART_ERR) {
|
||||
if (UART_Callback[bsp_uart][BSP_UART_ERROR_CB]) {
|
||||
UART_Callback[bsp_uart][BSP_UART_ERROR_CB]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart) {
|
||||
BSP_UART_t bsp_uart = UART_Get(huart);
|
||||
if (bsp_uart != BSP_UART_ERR) {
|
||||
if (UART_Callback[bsp_uart][BSP_UART_ABORT_CPLT_CB]) {
|
||||
UART_Callback[bsp_uart][BSP_UART_ABORT_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart) {
|
||||
BSP_UART_t bsp_uart = UART_Get(huart);
|
||||
if (bsp_uart != BSP_UART_ERR) {
|
||||
if (UART_Callback[bsp_uart][BSP_UART_ABORT_TX_CPLT_CB]) {
|
||||
UART_Callback[bsp_uart][BSP_UART_ABORT_TX_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart) {
|
||||
BSP_UART_t bsp_uart = UART_Get(huart);
|
||||
if (bsp_uart != BSP_UART_ERR) {
|
||||
if (UART_Callback[bsp_uart][BSP_UART_ABORT_RX_CPLT_CB]) {
|
||||
UART_Callback[bsp_uart][BSP_UART_ABORT_RX_CPLT_CB]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void BSP_UART_IRQHandler(UART_HandleTypeDef *huart) {
|
||||
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)) {
|
||||
__HAL_UART_CLEAR_IDLEFLAG(huart);
|
||||
if (UART_Callback[UART_Get(huart)][BSP_UART_IDLE_LINE_CB]) {
|
||||
UART_Callback[UART_Get(huart)][BSP_UART_IDLE_LINE_CB]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UART_HandleTypeDef *BSP_UART_GetHandle(BSP_UART_t uart) {
|
||||
switch (uart) {
|
||||
case BSP_UART_SINDT:
|
||||
return &huart1;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int8_t BSP_UART_RegisterCallback(BSP_UART_t uart, BSP_UART_Callback_t type,
|
||||
void (*callback)(void)) {
|
||||
if (callback == NULL) return BSP_ERR_NULL;
|
||||
UART_Callback[uart][type] = callback;
|
||||
return BSP_OK;
|
||||
}
|
47
User/bsp/uart.h
Normal file
47
User/bsp/uart.h
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include <usart.h>
|
||||
|
||||
#include "bsp/bsp.h"
|
||||
|
||||
/* Exported constants ------------------------------------------------------- */
|
||||
/* Exported macro ----------------------------------------------------------- */
|
||||
/* Exported types ----------------------------------------------------------- */
|
||||
|
||||
/* 要添加使用UART的新设备,需要先在此添加对应的枚举值 */
|
||||
|
||||
/* UART实体枚举,与设备对应 */
|
||||
typedef enum {
|
||||
BSP_UART_SINDT,
|
||||
BSP_UART_NUM,
|
||||
BSP_UART_ERR,
|
||||
} BSP_UART_t;
|
||||
|
||||
/* UART支持的中断回调函数类型,具体参考HAL中定义 */
|
||||
typedef enum {
|
||||
BSP_UART_TX_HALF_CPLT_CB,
|
||||
BSP_UART_TX_CPLT_CB,
|
||||
BSP_UART_RX_HALF_CPLT_CB,
|
||||
BSP_UART_RX_CPLT_CB,
|
||||
BSP_UART_ERROR_CB,
|
||||
BSP_UART_ABORT_CPLT_CB,
|
||||
BSP_UART_ABORT_TX_CPLT_CB,
|
||||
BSP_UART_ABORT_RX_CPLT_CB,
|
||||
|
||||
BSP_UART_IDLE_LINE_CB,
|
||||
BSP_UART_CB_NUM,
|
||||
} BSP_UART_Callback_t;
|
||||
|
||||
/* Exported functions prototypes -------------------------------------------- */
|
||||
UART_HandleTypeDef *BSP_UART_GetHandle(BSP_UART_t uart);
|
||||
int8_t BSP_UART_RegisterCallback(BSP_UART_t uart, BSP_UART_Callback_t type,
|
||||
void (*callback)(void));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
268
User/device/oled.c
Normal file
268
User/device/oled.c
Normal file
@ -0,0 +1,268 @@
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include "device/oled.h"
|
||||
#include "bsp/i2c.h"
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
/* Private define ----------------------------------------------------------- */
|
||||
#define OLED_I2C_ADDR 0x78 // OLED I2C 地址
|
||||
#define OLED_WIDTH 128
|
||||
#define OLED_HEIGHT 64
|
||||
|
||||
/* Private variables -------------------------------------------------------- */
|
||||
static uint8_t oled_buffer[OLED_WIDTH * OLED_HEIGHT / 8];
|
||||
static struct {
|
||||
uint8_t x_min;
|
||||
uint8_t x_max;
|
||||
uint8_t y_min;
|
||||
uint8_t y_max;
|
||||
uint8_t dirty; // 标志是否有脏区域
|
||||
} dirty_rect = {0, 0, 0, 0, 0};
|
||||
|
||||
/* Private function prototypes ---------------------------------------------- */
|
||||
static void OLED_WriteCommand(uint8_t cmd);
|
||||
static void OLED_WriteData(uint8_t *data, uint16_t size);
|
||||
static void OLED_MarkDirty(uint8_t x, uint8_t y);
|
||||
static void OLED_UpdateDirtyScreen(void);
|
||||
|
||||
static const uint8_t oled_font[95][8] = {
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}, /* " ", 0 */
|
||||
{0x00,0x00,0x00,0xcf,0xcf,0x00,0x00,0x00,}, /* "!", 1 */
|
||||
{0x00,0x0c,0x06,0x00,0x0c,0x06,0x00,0x00,}, /* """, 2 */
|
||||
{0x24,0xe4,0x3c,0x27,0xe4,0x3c,0x27,0x24,}, /* "#", 3 */
|
||||
{0x00,0x20,0x46,0xf9,0x9f,0x62,0x04,0x00,}, /* "$", 4 */
|
||||
{0x06,0x09,0xc6,0x30,0x0c,0x63,0x90,0x60,}, /* "%", 5 */
|
||||
{0x00,0x00,0x6e,0x91,0xa9,0x46,0xa0,0x00,}, /* "&", 6 */
|
||||
{0x00,0x00,0x00,0x1c,0x0e,0x00,0x00,0x00,}, /* "'", 7 */
|
||||
{0x00,0x00,0x3c,0x42,0x81,0x00,0x00,0x00,}, /* "(", 8 */
|
||||
{0x00,0x00,0x00,0x81,0x42,0x3c,0x00,0x00,}, /* ")", 9 */
|
||||
{0x00,0x10,0x54,0x38,0x38,0x54,0x10,0x00,}, /* "*", 10 */
|
||||
{0x00,0x10,0x10,0xfc,0x10,0x10,0x00,0x00,}, /* "+", 11 */
|
||||
{0x00,0x00,0x00,0xc0,0x60,0x00,0x00,0x00,}, /* ",", 12 */
|
||||
{0x00,0x00,0x10,0x10,0x10,0x10,0x00,0x00,}, /* "-", 13 */
|
||||
{0x00,0x00,0x00,0x00,0xc0,0xc0,0x00,0x00,}, /* ".", 14 */
|
||||
{0x00,0x00,0x00,0xc0,0x38,0x07,0x00,0x00,}, /* "/", 15 */
|
||||
{0x00,0x00,0x7c,0x92,0x8a,0x7c,0x00,0x00,}, /* "0", 16 */
|
||||
{0x00,0x00,0x00,0x84,0xfe,0x80,0x00,0x00,}, /* "1", 17 */
|
||||
{0x00,0x00,0x8c,0xc2,0xa2,0x9c,0x00,0x00,}, /* "2", 18 */
|
||||
{0x00,0x00,0x44,0x92,0x92,0x6c,0x00,0x00,}, /* "3", 19 */
|
||||
{0x00,0x20,0x38,0x24,0xfe,0x20,0x00,0x00,}, /* "4", 20 */
|
||||
{0x00,0x00,0x5e,0x92,0x92,0x62,0x00,0x00,}, /* "5", 21 */
|
||||
{0x00,0x00,0x78,0x94,0x92,0x62,0x00,0x00,}, /* "6", 22 */
|
||||
{0x00,0x00,0x82,0x62,0x1a,0x06,0x00,0x00,}, /* "7", 23 */
|
||||
{0x00,0x00,0x6c,0x92,0x92,0x6c,0x00,0x00,}, /* "8", 24 */
|
||||
{0x00,0x00,0x8c,0x52,0x32,0x1c,0x00,0x00,}, /* "9", 25 */
|
||||
{0x00,0x00,0x00,0x6c,0x6c,0x00,0x00,0x00,}, /* ":", 26 */
|
||||
{0x00,0x00,0x80,0xec,0x6c,0x00,0x00,0x00,}, /* ";", 27 */
|
||||
{0x00,0x00,0x10,0x28,0x44,0x00,0x00,0x00,}, /* "<", 28 */
|
||||
{0x00,0x00,0x24,0x24,0x24,0x24,0x00,0x00,}, /* "=", 29 */
|
||||
{0x00,0x00,0x00,0x44,0x28,0x10,0x00,0x00,}, /* ">", 30 */
|
||||
{0x00,0x00,0x0c,0xa2,0x92,0x1c,0x00,0x00,}, /* "?", 31 */
|
||||
{0x00,0x3c,0x42,0x99,0xa5,0xa2,0x3c,0x00,}, /* "@", 32 */
|
||||
{0x00,0xe0,0x1c,0x12,0x12,0x1c,0xe0,0x00,}, /* "A", 33 */
|
||||
{0x00,0xfe,0x92,0x92,0x9c,0x90,0x60,0x00,}, /* "B", 34 */
|
||||
{0x00,0x38,0x44,0x82,0x82,0x82,0x44,0x00,}, /* "C", 35 */
|
||||
{0x00,0xfe,0x82,0x82,0x82,0x82,0x7c,0x00,}, /* "D", 36 */
|
||||
{0x00,0xfe,0x92,0x92,0x92,0x92,0x92,0x00,}, /* "E", 37 */
|
||||
{0x00,0xfe,0x12,0x12,0x12,0x12,0x02,0x00,}, /* "F", 38 */
|
||||
{0x00,0x7c,0x82,0x92,0x92,0x72,0x00,0x00,}, /* "G", 39 */
|
||||
{0x00,0xfe,0x10,0x10,0x10,0x10,0xfe,0x00,}, /* "H", 40 */
|
||||
{0x00,0x82,0x82,0xfe,0x82,0x82,0x00,0x00,}, /* "I", 41 */
|
||||
{0x00,0x82,0x82,0x7e,0x02,0x02,0x00,0x00,}, /* "J", 42 */
|
||||
{0x00,0xfe,0x10,0x28,0x44,0x82,0x00,0x00,}, /* "K", 43 */
|
||||
{0x00,0xfe,0x80,0x80,0x80,0x80,0x00,0x00,}, /* "L", 44 */
|
||||
{0xfc,0x02,0x04,0xf8,0x04,0x02,0xfc,0x00,}, /* "M", 45 */
|
||||
{0x00,0xfe,0x04,0x18,0x30,0x40,0xfe,0x00,}, /* "N", 46 */
|
||||
{0x00,0x7c,0x82,0x82,0x82,0x82,0x7c,0x00,}, /* "O", 47 */
|
||||
{0x00,0x00,0xfe,0x12,0x12,0x0c,0x00,0x00,}, /* "P", 48 */
|
||||
{0x00,0x00,0x3c,0x42,0xc2,0xbc,0x00,0x00,}, /* "Q", 49 */
|
||||
{0x00,0x00,0xfe,0x32,0x52,0x8c,0x00,0x00,}, /* "R", 50 */
|
||||
{0x00,0x00,0x4c,0x92,0x92,0x64,0x00,0x00,}, /* "S", 51 */
|
||||
{0x00,0x02,0x02,0xfe,0x02,0x02,0x00,0x00,}, /* "T", 52 */
|
||||
{0x00,0x7e,0x80,0x80,0x80,0x80,0x7e,0x00,}, /* "U", 53 */
|
||||
{0x00,0x0c,0x30,0xc0,0x30,0x0c,0x00,0x00,}, /* "V", 54 */
|
||||
{0x7c,0x80,0x80,0x78,0x80,0x80,0x7c,0x00,}, /* "W", 55 */
|
||||
{0x00,0x84,0x48,0x30,0x30,0x48,0x84,0x00,}, /* "X", 56 */
|
||||
{0x00,0x06,0x08,0xf0,0x08,0x06,0x00,0x00,}, /* "Y", 57 */
|
||||
{0x00,0x00,0xc2,0xa2,0x92,0x8e,0x00,0x00,}, /* "Z", 58 */
|
||||
{0x00,0x00,0xfe,0x82,0x82,0x82,0x00,0x00,}, /* "[", 59 */
|
||||
{0x00,0x00,0x06,0x18,0x60,0x80,0x00,0x00,}, /* "\", 60 */
|
||||
{0x00,0x00,0x82,0x82,0x82,0xfe,0x00,0x00,}, /* "]", 61 */
|
||||
{0x00,0x30,0x0c,0x02,0x0c,0x30,0x00,0x00,}, /* "^", 62 */
|
||||
{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,}, /* "_", 63 */
|
||||
{0x00,0x00,0x04,0x0c,0x18,0x00,0x00,0x00,}, /* "`", 64 */
|
||||
{0x00,0x00,0x60,0x90,0x90,0xe0,0x00,0x00,}, /* "a", 65 */
|
||||
{0x00,0x00,0xf8,0xa0,0xe0,0x00,0x00,0x00,}, /* "b", 66 */
|
||||
{0x00,0x00,0x60,0x90,0x90,0x00,0x00,0x00,}, /* "c", 67 */
|
||||
{0x00,0x00,0xe0,0xa0,0xf8,0x00,0x00,0x00,}, /* "d", 68 */
|
||||
{0x00,0x00,0x70,0xa8,0xa8,0x90,0x00,0x00,}, /* "e", 69 */
|
||||
{0x00,0x00,0x10,0xf8,0x14,0x00,0x00,0x00,}, /* "f", 70 */
|
||||
{0x00,0x00,0xd8,0xa4,0x7c,0x00,0x00,0x00,}, /* "g", 71 */
|
||||
{0x00,0x00,0xf8,0x20,0xe0,0x00,0x00,0x00,}, /* "h", 72 */
|
||||
{0x00,0x00,0x00,0xe8,0x00,0x00,0x00,0x00,}, /* "i", 73 */
|
||||
{0x00,0x00,0x40,0x90,0x74,0x00,0x00,0x00,}, /* "j", 74 */
|
||||
{0x00,0x00,0xf8,0x60,0x90,0x00,0x00,0x00,}, /* "k", 75 */
|
||||
{0x00,0x00,0x78,0x80,0x80,0x00,0x00,0x00,}, /* "l", 76 */
|
||||
{0x00,0xe0,0x10,0xe0,0x10,0xe0,0x00,0x00,}, /* "m", 77 */
|
||||
{0x00,0x00,0xf0,0x10,0x10,0xe0,0x00,0x00,}, /* "n", 78 */
|
||||
{0x00,0x00,0x60,0x90,0x90,0x60,0x00,0x00,}, /* "o", 79 */
|
||||
{0x00,0x00,0xf0,0x48,0x48,0x30,0x00,0x00,}, /* "p", 80 */
|
||||
{0x00,0x00,0x30,0x48,0x48,0xf0,0x00,0x00,}, /* "q", 81 */
|
||||
{0x00,0x00,0x00,0xf0,0x20,0x10,0x00,0x00,}, /* "r", 82 */
|
||||
{0x00,0x00,0x90,0xa8,0xa8,0x48,0x00,0x00,}, /* "s", 83 */
|
||||
{0x00,0x10,0x10,0xf8,0x90,0x90,0x00,0x00,}, /* "t", 84 */
|
||||
{0x00,0x00,0x78,0x80,0x80,0xf8,0x00,0x00,}, /* "u", 85 */
|
||||
{0x00,0x18,0x60,0x80,0x60,0x18,0x00,0x00,}, /* "v", 86 */
|
||||
{0x00,0x38,0xc0,0x38,0xc0,0x38,0x00,0x00,}, /* "w", 87 */
|
||||
{0x00,0x88,0x50,0x20,0x50,0x88,0x00,0x00,}, /* "x", 88 */
|
||||
{0x00,0x8c,0x50,0x20,0x10,0x0c,0x00,0x00,}, /* "y", 89 */
|
||||
{0x00,0x88,0xc8,0xa8,0x98,0x88,0x00,0x00,}, /* "z", 90 */
|
||||
{0x00,0x00,0x10,0x7c,0x82,0x00,0x00,0x00,}, /* "{", 91 */
|
||||
{0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,}, /* "|", 92 */
|
||||
{0x00,0x00,0x00,0x82,0x7c,0x10,0x00,0x00,}, /* "}", 93 */
|
||||
{0x00,0x08,0x04,0x04,0x08,0x10,0x10,0x08,}, /* "~", 94 */
|
||||
};
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
void OLED_Init(void) {
|
||||
OLED_WriteCommand(0xAE); // 关闭显示
|
||||
OLED_WriteCommand(0x20); // 设置内存寻址模式
|
||||
OLED_WriteCommand(0x10); // 页寻址模式
|
||||
OLED_WriteCommand(0xB0); // 设置页起始地址
|
||||
OLED_WriteCommand(0xC8); // 设置COM扫描方向
|
||||
OLED_WriteCommand(0x00); // 设置低列地址
|
||||
OLED_WriteCommand(0x10); // 设置高列地址
|
||||
OLED_WriteCommand(0x40); // 设置显示起始行
|
||||
OLED_WriteCommand(0x81); // 设置对比度
|
||||
OLED_WriteCommand(0xFF); // 最大对比度
|
||||
OLED_WriteCommand(0xA1); // 设置段重映射
|
||||
OLED_WriteCommand(0xA6); // 正常显示
|
||||
OLED_WriteCommand(0xA8); // 设置多路复用比率
|
||||
OLED_WriteCommand(0x3F); // 1/64
|
||||
OLED_WriteCommand(0xA4); // 输出跟随 RAM 内容
|
||||
OLED_WriteCommand(0xD3); // 设置显示偏移
|
||||
OLED_WriteCommand(0x00); // 无偏移
|
||||
OLED_WriteCommand(0xD5); // 设置显示时钟分频比/振荡频率
|
||||
OLED_WriteCommand(0xF0); // 高频
|
||||
OLED_WriteCommand(0xD9); // 设置预充电周期
|
||||
OLED_WriteCommand(0x22); // 修复缺少分号
|
||||
OLED_WriteCommand(0xDA); // 设置COM引脚硬件配置
|
||||
OLED_WriteCommand(0x12); // 修复缺少分号
|
||||
OLED_WriteCommand(0xDB); // 设置VCOMH电压
|
||||
OLED_WriteCommand(0x20); // 修复缺少分号
|
||||
OLED_WriteCommand(0x8D); // 设置充电泵
|
||||
OLED_WriteCommand(0x14); // 修复缺少分号
|
||||
OLED_WriteCommand(0xAF); // 打开显示
|
||||
}
|
||||
|
||||
void OLED_Clear(void) {
|
||||
memset(oled_buffer, 0, sizeof(oled_buffer));
|
||||
dirty_rect.x_min = 0;
|
||||
dirty_rect.x_max = OLED_WIDTH - 1;
|
||||
dirty_rect.y_min = 0;
|
||||
dirty_rect.y_max = OLED_HEIGHT - 1;
|
||||
dirty_rect.dirty = 1;
|
||||
OLED_UpdateScreen();
|
||||
}
|
||||
|
||||
void OLED_UpdateScreen(void) {
|
||||
OLED_UpdateDirtyScreen();
|
||||
}
|
||||
|
||||
void OLED_DrawPixel(uint8_t x, uint8_t y, uint8_t color) {
|
||||
if (x >= OLED_WIDTH || y >= OLED_HEIGHT) return;
|
||||
|
||||
if (color) {
|
||||
if (!(oled_buffer[x + (y / 8) * OLED_WIDTH] & (1 << (y % 8)))) {
|
||||
oled_buffer[x + (y / 8) * OLED_WIDTH] |= (1 << (y % 8));
|
||||
OLED_MarkDirty(x, y);
|
||||
}
|
||||
} else {
|
||||
if (oled_buffer[x + (y / 8) * OLED_WIDTH] & (1 << (y % 8))) {
|
||||
oled_buffer[x + (y / 8) * OLED_WIDTH] &= ~(1 << (y % 8));
|
||||
OLED_MarkDirty(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OLED_DrawChar(uint8_t x, uint8_t y, char ch, uint8_t color) {
|
||||
if (ch < ' ' || ch > '~') return;
|
||||
|
||||
if (x >= OLED_WIDTH || y >= OLED_HEIGHT || x + 8 > OLED_WIDTH || y + 8 > OLED_HEIGHT) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t *font_data = oled_font[ch - ' '];
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
uint8_t column_data = font_data[i];
|
||||
for (uint8_t j = 0; j < 8; j++) {
|
||||
if (column_data & (1 << j)) {
|
||||
OLED_DrawPixel(x + i, y + j, color);
|
||||
} else {
|
||||
OLED_DrawPixel(x + i, y + j, !color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OLED_DrawString(uint8_t x, uint8_t y, const char *str, uint8_t color) {
|
||||
while (*str) {
|
||||
OLED_DrawChar(x, y, *str, color);
|
||||
x += 8;
|
||||
if (x + 8 > OLED_WIDTH) {
|
||||
x = 0;
|
||||
y += 8;
|
||||
}
|
||||
if (y + 8 > OLED_HEIGHT) {
|
||||
break;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Private functions -------------------------------------------------------- */
|
||||
|
||||
static void OLED_MarkDirty(uint8_t x, uint8_t y) {
|
||||
if (!dirty_rect.dirty) {
|
||||
dirty_rect.x_min = x;
|
||||
dirty_rect.x_max = x;
|
||||
dirty_rect.y_min = y;
|
||||
dirty_rect.y_max = y;
|
||||
dirty_rect.dirty = 1;
|
||||
} else {
|
||||
if (x < dirty_rect.x_min) dirty_rect.x_min = x;
|
||||
if (x > dirty_rect.x_max) dirty_rect.x_max = x;
|
||||
if (y < dirty_rect.y_min) dirty_rect.y_min = y;
|
||||
if (y > dirty_rect.y_max) dirty_rect.y_max = y;
|
||||
}
|
||||
}
|
||||
|
||||
static void OLED_UpdateDirtyScreen(void) {
|
||||
if (!dirty_rect.dirty) return;
|
||||
|
||||
uint8_t y_start = dirty_rect.y_min / 8;
|
||||
uint8_t y_end = dirty_rect.y_max / 8;
|
||||
|
||||
for (uint8_t i = y_start; i <= y_end; i++) {
|
||||
OLED_WriteCommand(0xB0 + i);
|
||||
OLED_WriteCommand(dirty_rect.x_min & 0x0F);
|
||||
OLED_WriteCommand(0x10 | (dirty_rect.x_min >> 4));
|
||||
uint8_t width = dirty_rect.x_max - dirty_rect.x_min + 1;
|
||||
OLED_WriteData(&oled_buffer[dirty_rect.x_min + i * OLED_WIDTH], width);
|
||||
}
|
||||
|
||||
dirty_rect.dirty = 0;
|
||||
}
|
||||
|
||||
static void OLED_WriteCommand(uint8_t cmd) {
|
||||
uint8_t data[2] = {0x00, cmd};
|
||||
HAL_I2C_Master_Transmit(BSP_I2C_GetHandle(BSP_I2C_OLED), OLED_I2C_ADDR, data, 2, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
static void OLED_WriteData(uint8_t *data, uint16_t size) {
|
||||
uint8_t buffer[size + 1];
|
||||
buffer[0] = 0x40;
|
||||
memcpy(&buffer[1], data, size);
|
||||
HAL_I2C_Master_Transmit(BSP_I2C_GetHandle(BSP_I2C_OLED), OLED_I2C_ADDR, buffer, size + 1, HAL_MAX_DELAY);
|
||||
}
|
26
User/device/oled.h
Normal file
26
User/device/oled.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ----------------------------------------------------------------- */
|
||||
#include <stdint.h>
|
||||
|
||||
/* Exported constants ------------------------------------------------------- */
|
||||
#define OLED_COLOR_BLACK 0
|
||||
#define OLED_COLOR_WHITE 1
|
||||
|
||||
/* Exported functions prototypes -------------------------------------------- */
|
||||
void OLED_Init(void);
|
||||
void OLED_Clear(void);
|
||||
void OLED_UpdateScreen(void);
|
||||
void OLED_DrawPixel(uint8_t x, uint8_t y, uint8_t color);
|
||||
void OLED_DrawString(uint8_t x, uint8_t y, const char *str, uint8_t color);
|
||||
void OLED_DrawChar(uint8_t x, uint8_t y, char ch, uint8_t color);
|
||||
void OLED_ShowChinese(uint8_t x, uint8_t y, uint8_t index);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user