修改了基础的device生成

This commit is contained in:
Robofish 2025-08-07 19:14:32 +08:00
parent 3159d3ae1a
commit c8ca5e1031
15 changed files with 724 additions and 451 deletions

View File

@ -154,27 +154,42 @@ class CodeGenerateInterface(QWidget):
) )
def generate_code(self): def generate_code(self):
"""生成代码逻辑 - 修复导入问题""" """生成代码逻辑 - 修复导入问题并添加配置重载"""
try: try:
# 收集所有已加载的页面对象 # 收集所有已加载的页面对象,并按类型分类
pages = [] bsp_pages = []
component_pages = []
device_pages = []
for i in range(self.stack.count()): for i in range(self.stack.count()):
widget = self.stack.widget(i) widget = self.stack.widget(i)
pages.append(widget) # 根据页面类型分类
if hasattr(widget, '_generate_bsp_code_internal'):
bsp_pages.append(widget)
elif hasattr(widget, '_generate_component_code_internal'):
component_pages.append(widget)
elif hasattr(widget, '_generate_device_code_internal'):
device_pages.append(widget)
# 确保导入成功 # 确保导入成功
from app.code_page.bsp_interface import bsp from app.code_page.bsp_interface import bsp
from app.code_page.component_interface import component from app.code_page.component_interface import component
from app.code_page.device_interface import device
# 生成 BSP 代码 # 生成 BSP 代码
bsp_result = bsp.generate_bsp(self.project_path, pages) bsp_result = bsp.generate_bsp(self.project_path, bsp_pages)
# 生成 Component 代码 # 生成 Component 代码
component_result = component.generate_component(self.project_path, pages) component_result = component.generate_component(self.project_path, component_pages)
# 生成 Device 代码
device_result = device.generate_device(self.project_path, device_pages)
# 合并结果信息 # 合并结果信息
combined_result = f"BSP代码生成:\n{bsp_result}\n\nComponent代码生成:\n{component_result}" combined_result = f"BSP代码生成:\n{bsp_result}\n\nComponent代码生成:\n{component_result}\n\nDevice代码生成:\n{device_result}"
# 用 InfoBar 在主界面弹出 # 用 InfoBar 在主界面弹出
InfoBar.success( InfoBar.success(
@ -199,6 +214,9 @@ class CodeGenerateInterface(QWidget):
duration=3000 duration=3000
) )
def _get_freertos_status(self): def _get_freertos_status(self):
"""获取FreeRTOS状态""" """获取FreeRTOS状态"""
ioc_files = [f for f in os.listdir(self.project_path) if f.endswith('.ioc')] ioc_files = [f for f in os.listdir(self.project_path) if f.endswith('.ioc')]
@ -261,6 +279,11 @@ class CodeGenerateInterface(QWidget):
comp_name = class_name[len('component_'):] # 移除 .replace("_", " ") comp_name = class_name[len('component_'):] # 移除 .replace("_", " ")
page = get_component_page(comp_name, self.project_path, self.component_manager) page = get_component_page(comp_name, self.project_path, self.component_manager)
self.component_manager.register_component(page.component_name, page) self.component_manager.register_component(page.component_name, page)
elif class_name.startswith('device_'):
# Device页面
from app.code_page.device_interface import get_device_page
device_name = class_name[len('device_'):] # 移除 device_ 前缀
page = get_device_page(device_name, self.project_path)
else: else:
print(f"未知的页面类型: {class_name}") print(f"未知的页面类型: {class_name}")
return None return None
@ -270,5 +293,4 @@ class CodeGenerateInterface(QWidget):
return page return page
except Exception as e: except Exception as e:
print(f"创建页面 {class_name} 失败: {e}") print(f"创建页面 {class_name} 失败: {e}")
return None return None

View File

@ -0,0 +1,394 @@
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout
from qfluentwidgets import BodyLabel, CheckBox, ComboBox, SubtitleLabel
from PyQt5.QtCore import Qt
from app.tools.code_generator import CodeGenerator
import os
import shutil
import yaml
import re
def load_device_config(config_path):
"""加载设备配置"""
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
return yaml.safe_load(f)
return {}
def get_available_bsp_devices(project_path, bsp_type):
"""获取可用的BSP设备"""
bsp_config_path = os.path.join(project_path, "User/bsp/bsp_config.yaml")
if not os.path.exists(bsp_config_path):
return []
try:
with open(bsp_config_path, 'r', encoding='utf-8') as f:
bsp_config = yaml.safe_load(f)
if bsp_type in bsp_config and bsp_config[bsp_type].get('enabled', False):
devices = bsp_config[bsp_type].get('devices', [])
return [f"BSP_{bsp_type.upper()}_{device['name']}" for device in devices]
except Exception as e:
print(f"读取BSP配置失败: {e}")
return []
def generate_device_header(project_path, enabled_devices):
"""生成device.h文件"""
device_dir = os.path.join(os.path.dirname(__file__), "../../assets/User_code/device")
template_path = os.path.join(device_dir, "device.h")
# 读取模板文件
with open(template_path, 'r', encoding='utf-8') as f:
content = f.read()
# 收集所有需要的信号定义
signals = []
current_bit = 0
# 加载设备配置来获取信号信息
config_path = os.path.join(device_dir, "config.yaml")
device_configs = load_device_config(config_path)
for device_name in enabled_devices:
device_key = device_name.lower()
if device_key in device_configs.get('devices', {}):
device_config = device_configs['devices'][device_key]
thread_signals = device_config.get('thread_signals', [])
for signal in thread_signals:
signal_name = signal['name']
signals.append(f"#define {signal_name} (1u << {current_bit})")
current_bit += 1
# 生成信号定义文本
signals_text = '\n'.join(signals) if signals else '/* No signals defined */'
# 替换AUTO GENERATED SIGNALS部分
pattern = r'/\* AUTO GENERATED SIGNALS BEGIN \*/(.*?)/\* AUTO GENERATED SIGNALS END \*/'
replacement = f'/* AUTO GENERATED SIGNALS BEGIN */\n{signals_text}\n/* AUTO GENERATED SIGNALS END */'
content = re.sub(pattern, replacement, content, flags=re.DOTALL)
# 保存文件
dst_path = os.path.join(project_path, "User/device/device.h")
os.makedirs(os.path.dirname(dst_path), exist_ok=True)
with open(dst_path, 'w', encoding='utf-8') as f:
f.write(content)
class DeviceSimple(QWidget):
"""简单设备界面"""
def __init__(self, project_path, device_name, device_config):
super().__init__()
self.project_path = project_path
self.device_name = device_name
self.device_config = device_config
# 添加必要的属性,确保兼容性
self.component_name = device_name # 添加这个属性以兼容现有代码
self._init_ui()
self._load_config()
def _init_ui(self):
layout = QVBoxLayout(self)
# 顶部横向布局:左侧复选框,居中标题
top_layout = QHBoxLayout()
top_layout.setAlignment(Qt.AlignVCenter)
self.generate_checkbox = CheckBox(f"启用 {self.device_name}")
self.generate_checkbox.stateChanged.connect(self._on_checkbox_changed)
top_layout.addWidget(self.generate_checkbox, alignment=Qt.AlignLeft)
# 弹性空间
top_layout.addStretch()
title = SubtitleLabel(f"{self.device_name} 配置 ")
title.setAlignment(Qt.AlignHCenter)
top_layout.addWidget(title, alignment=Qt.AlignHCenter)
# 再加一个弹性空间,保证标题居中
top_layout.addStretch()
layout.addLayout(top_layout)
# 功能说明
desc = self.device_config.get('description', '')
if desc:
desc_label = BodyLabel(f"功能说明:{desc}")
desc_label.setWordWrap(True)
layout.addWidget(desc_label)
# 依赖信息
self._add_dependency_info(layout)
# BSP配置区域
self.content_widget = QWidget()
content_layout = QVBoxLayout(self.content_widget)
self._add_bsp_config(content_layout)
layout.addWidget(self.content_widget)
self.content_widget.setEnabled(False)
layout.addStretch()
def _add_dependency_info(self, layout):
"""添加依赖信息显示"""
bsp_deps = self.device_config.get('dependencies', {}).get('bsp', [])
comp_deps = self.device_config.get('dependencies', {}).get('component', [])
if bsp_deps or comp_deps:
deps_text = "依赖: "
if bsp_deps:
deps_text += f"BSP({', '.join(bsp_deps)})"
if comp_deps:
if bsp_deps:
deps_text += ", "
deps_text += f"Component({', '.join(comp_deps)})"
deps_label = BodyLabel(deps_text)
deps_label.setWordWrap(True)
deps_label.setStyleSheet("color: #888888;")
layout.addWidget(deps_label)
def _add_bsp_config(self, layout):
"""添加BSP配置区域"""
bsp_requirements = self.device_config.get('bsp_requirements', [])
self.bsp_combos = {}
if bsp_requirements:
layout.addWidget(BodyLabel("BSP设备配置:"))
for req in bsp_requirements:
bsp_type = req['type']
var_name = req['var_name']
description = req.get('description', '')
# 创建选择组合框
req_layout = QHBoxLayout()
label = BodyLabel(f"{bsp_type.upper()}:")
label.setMinimumWidth(80)
req_layout.addWidget(label)
combo = ComboBox()
self._update_bsp_combo(combo, bsp_type)
req_layout.addWidget(combo)
if description:
desc_label = BodyLabel(f"({description})")
desc_label.setStyleSheet("color: #666666; font-size: 12px;")
req_layout.addWidget(desc_label)
req_layout.addStretch()
layout.addLayout(req_layout)
self.bsp_combos[var_name] = combo
def _update_bsp_combo(self, combo, bsp_type):
"""更新BSP组合框选项"""
combo.clear()
available_devices = get_available_bsp_devices(self.project_path, bsp_type)
if available_devices:
combo.addItems(available_devices)
else:
combo.addItem(f"未找到可用的{bsp_type.upper()}设备")
combo.setEnabled(False)
def refresh_bsp_combos(self):
"""刷新所有BSP组合框"""
bsp_requirements = self.device_config.get('bsp_requirements', [])
for req in bsp_requirements:
bsp_type = req['type']
var_name = req['var_name']
if var_name in self.bsp_combos:
current_text = self.bsp_combos[var_name].currentText()
self._update_bsp_combo(self.bsp_combos[var_name], bsp_type)
# 尝试恢复之前的选择
index = self.bsp_combos[var_name].findText(current_text)
if index >= 0:
self.bsp_combos[var_name].setCurrentIndex(index)
def _on_checkbox_changed(self, state):
"""处理复选框状态变化"""
self.content_widget.setEnabled(state == 2)
def is_need_generate(self):
"""检查是否需要生成代码"""
return self.generate_checkbox.isChecked()
def get_bsp_config(self):
"""获取BSP配置"""
config = {}
for var_name, combo in self.bsp_combos.items():
if combo.isEnabled():
config[var_name] = combo.currentText()
return config
def _generate_device_code_internal(self):
"""生成设备代码"""
if not self.is_need_generate():
return False
# 获取BSP配置
bsp_config = self.get_bsp_config()
# 复制并修改文件
template_dir = self._get_device_template_dir()
files = self.device_config.get('files', {})
for file_type, filename in files.items():
src_path = os.path.join(template_dir, filename)
dst_path = os.path.join(self.project_path, f"User/device/{filename}")
if os.path.exists(src_path):
if file_type == 'header':
# 头文件直接复制,不做修改
os.makedirs(os.path.dirname(dst_path), exist_ok=True)
shutil.copy2(src_path, dst_path)
elif file_type == 'source':
# 源文件需要替换BSP设备名称
with open(src_path, 'r', encoding='utf-8') as f:
content = f.read()
# 替换BSP设备名称
for var_name, device_name in bsp_config.items():
content = content.replace(var_name, device_name)
# 保存文件
os.makedirs(os.path.dirname(dst_path), exist_ok=True)
with open(dst_path, 'w', encoding='utf-8') as f:
f.write(content)
self._save_config()
return True
def _get_device_template_dir(self):
"""获取设备模板目录"""
current_dir = os.path.dirname(os.path.abspath(__file__))
# 向上找到 MRobot 根目录
while os.path.basename(current_dir) != 'MRobot' and current_dir != '/':
current_dir = os.path.dirname(current_dir)
if os.path.basename(current_dir) == 'MRobot':
return os.path.join(current_dir, "assets/User_code/device")
else:
# 如果找不到,使用相对路径作为备选
return os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "assets/User_code/device")
def _save_config(self):
"""保存配置"""
config_path = os.path.join(self.project_path, "User/device/device_config.yaml")
config_data = CodeGenerator.load_config(config_path)
config_data[self.device_name.lower()] = {
'enabled': self.is_need_generate(),
'bsp_config': self.get_bsp_config()
}
CodeGenerator.save_config(config_data, config_path)
def _load_config(self):
"""加载配置"""
config_path = os.path.join(self.project_path, "User/device/device_config.yaml")
config_data = CodeGenerator.load_config(config_path)
conf = config_data.get(self.device_name.lower(), {})
if conf.get('enabled', False):
self.generate_checkbox.setChecked(True)
# 恢复BSP配置
bsp_config = conf.get('bsp_config', {})
for var_name, device_name in bsp_config.items():
if var_name in self.bsp_combos:
combo = self.bsp_combos[var_name]
index = combo.findText(device_name)
if index >= 0:
combo.setCurrentIndex(index)
def get_device_page(device_name, project_path):
"""根据设备名返回对应的页面类"""
# 加载设备配置
device_dir = os.path.join(os.path.dirname(__file__), "../../assets/User_code/device")
config_path = os.path.join(device_dir, "config.yaml")
device_configs = load_device_config(config_path)
devices = device_configs.get('devices', {})
device_key = device_name.lower()
if device_key in devices:
device_config = devices[device_key]
page = DeviceSimple(project_path, device_name, device_config)
else:
# 如果配置中没有找到,返回一个基本的设备页面
basic_config = {
'name': device_name,
'description': f'{device_name}设备',
'files': {'header': f'{device_name.lower()}.h', 'source': f'{device_name.lower()}.c'},
'bsp_requirements': [],
'dependencies': {'bsp': [], 'component': []}
}
page = DeviceSimple(project_path, device_name, basic_config)
# 确保页面有必要的属性
page.device_name = device_name
return page
class device(QWidget):
"""设备管理器"""
def __init__(self, project_path):
super().__init__()
self.project_path = project_path
@staticmethod
def generate_device(project_path, pages):
"""生成所有设备代码"""
success_count = 0
fail_count = 0
fail_list = []
enabled_devices = []
# 生成设备代码
for page in pages:
if hasattr(page, "device_name") and hasattr(page, "is_need_generate"):
if page.is_need_generate():
enabled_devices.append(page.device_name)
try:
result = page._generate_device_code_internal()
if result:
success_count += 1
else:
fail_count += 1
fail_list.append(page.device_name)
except Exception as e:
fail_count += 1
fail_list.append(f"{page.device_name} (异常: {e})")
# 生成device.h文件
try:
generate_device_header(project_path, enabled_devices)
success_count += 1
except Exception as e:
fail_count += 1
fail_list.append(f"device.h (异常: {e})")
# 刷新所有页面的BSP组合框选项
for page in pages:
if hasattr(page, 'refresh_bsp_combos'):
try:
page.refresh_bsp_combos()
except Exception as e:
print(f"刷新页面 {getattr(page, 'device_name', 'Unknown')} 的BSP选项失败: {e}")
total_items = success_count + fail_count
msg = f"设备代码生成完成:总共尝试生成 {total_items} 项,成功 {success_count} 项,失败 {fail_count} 项。"
if fail_list:
msg += "\n失败项:\n" + "\n".join(fail_list)
return msg

View File

@ -1,7 +1,7 @@
/* /*
UI相关命令 UI相关命令
*/ */
#include "component\ui.h" #include "component/ui.h"
#include <stdio.h> #include <stdio.h>

View File

@ -11,7 +11,7 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "component\user_math.h" #include "component/user_math.h"
#define UI_DEL_OPERATION_NOTHING (0) #define UI_DEL_OPERATION_NOTHING (0)
#define UI_DEL_OPERATION_DEL (1) #define UI_DEL_OPERATION_DEL (1)
@ -45,12 +45,12 @@ typedef enum {
WHITE WHITE
} UI_Color_t; } UI_Color_t;
typedef __Packed struct { typedef struct __packed {
uint8_t op; uint8_t op;
uint8_t num_layer; uint8_t num_layer;
} UI_InterStudent_UIDel_t; } UI_InterStudent_UIDel_t;
typedef __Packed struct { typedef struct __packed {
uint8_t name[3]; uint8_t name[3];
uint8_t type_op : 3; uint8_t type_op : 3;
uint8_t type_ele : 3; uint8_t type_ele : 3;
@ -66,28 +66,28 @@ typedef __Packed struct {
uint16_t y_end : 11; uint16_t y_end : 11;
} UI_Ele_t; } UI_Ele_t;
typedef __Packed struct { typedef struct __packed {
UI_Ele_t grapic; UI_Ele_t grapic;
} UI_Drawgrapic_1_t; } UI_Drawgrapic_1_t;
typedef __Packed struct { typedef struct __packed {
UI_Ele_t grapic[2]; UI_Ele_t grapic[2];
} UI_Drawgrapic_2_t; } UI_Drawgrapic_2_t;
typedef __Packed struct { typedef struct __packed {
UI_Ele_t grapic[5]; UI_Ele_t grapic[5];
} UI_Drawgrapic_5_t; } UI_Drawgrapic_5_t;
typedef __Packed struct { typedef struct __packed {
UI_Ele_t grapic[7]; UI_Ele_t grapic[7];
} UI_Drawgrapic_7_t; } UI_Drawgrapic_7_t;
typedef __Packed struct { typedef struct __packed {
UI_Ele_t grapic; UI_Ele_t grapic;
uint8_t character[30]; uint8_t character[30];
} UI_Drawcharacter_t; } UI_Drawcharacter_t;
typedef __Packed struct { typedef struct __packed {
uint8_t del_operation; uint8_t del_operation;
uint8_t layer; uint8_t layer;
} UI_Del_t; } UI_Del_t;

View File

@ -25,6 +25,10 @@ extern "C" {
#define M_2PI 6.28318530717958647692f #define M_2PI 6.28318530717958647692f
#endif #endif
#ifndef __packed
#define __packed __attribute__((__packed__))
#endif /* __packed */
#define max(a, b) \ #define max(a, b) \
({ \ ({ \
__typeof__(a) _a = (a); \ __typeof__(a) _a = (a); \

Binary file not shown.

View File

@ -0,0 +1,16 @@
devices:
dr16:
name: "DR16"
description: "大疆遥控器接收机"
dependencies:
bsp: ["uart"]
component: ["user_math"]
bsp_requirements:
- type: "uart"
var_name: "BSP_UART_DR16" # 需要替换的变量名
description: "用于接收遥控器数据"
thread_signals:
- name: "SIGNAL_DR16_RAW_REDY"
files:
header: "dr16.h"
source: "dr16.c"

View File

@ -1,5 +0,0 @@
oled_i2c,bsp/i2c
bmp280_i2c,bsp/i2c
pc_uart,bsp/uart
key_gpio,bsp/gpio_exti
servo,bsp/servo_pwm
1 oled_i2c bsp/i2c
2 bmp280_i2c bsp/i2c
3 pc_uart bsp/uart
4 key_gpio bsp/gpio_exti
5 servo bsp/servo_pwm

View File

@ -1 +0,0 @@
servo,测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息
1 servo 测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息测试消息

View File

@ -10,6 +10,19 @@ extern "C" {
#define DEVICE_ERR_INITED (-3) #define DEVICE_ERR_INITED (-3)
#define DEVICE_ERR_NO_DEV (-4) #define DEVICE_ERR_NO_DEV (-4)
/* AUTO GENERATED SIGNALS BEGIN */
/* AUTO GENERATED SIGNALS END */
/* USER SIGNALS BEGIN */
/* USER SIGNALS END */
/*设备层通用Header*/
typedef struct {
bool online;
uint64_t last_online_time;
} DEVICE_Header_t;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -0,0 +1,85 @@
/*
DR16接收机
*/
/* Includes ----------------------------------------------------------------- */
#include "dr16.h"
#include <string.h>
#include "bsp/uart.h"
/* Private define ----------------------------------------------------------- */
#define DR16_CH_VALUE_MIN (364u)
#define DR16_CH_VALUE_MID (1024u)
#define DR16_CH_VALUE_MAX (1684u)
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
static osThreadId_t thread_alert;
static bool inited = false;
/* Private function -------------------------------------------------------- */
static void DR16_RxCpltCallback(void) {
osThreadFlagsSet(thread_alert, SIGNAL_DR16_RAW_REDY);
}
static bool DR16_DataCorrupted(const DR16_t *dr16) {
if (dr16 == NULL) return DEVICE_ERR_NULL;
if ((dr16->data.ch_r_x < DR16_CH_VALUE_MIN) ||
(dr16->data.ch_r_x > DR16_CH_VALUE_MAX))
return true;
if ((dr16->data.ch_r_y < DR16_CH_VALUE_MIN) ||
(dr16->data.ch_r_y > DR16_CH_VALUE_MAX))
return true;
if ((dr16->data.ch_l_x < DR16_CH_VALUE_MIN) ||
(dr16->data.ch_l_x > DR16_CH_VALUE_MAX))
return true;
if ((dr16->data.ch_l_y < DR16_CH_VALUE_MIN) ||
(dr16->data.ch_l_y > DR16_CH_VALUE_MAX))
return true;
if (dr16->data.sw_l == 0) return true;
if (dr16->data.sw_r == 0) return true;
return false;
}
/* Exported functions ------------------------------------------------------- */
int8_t DR16_Init(DR16_t *dr16) {
if (dr16 == NULL) return DEVICE_ERR_NULL;
if (inited) return DEVICE_ERR_INITED;
if ((thread_alert = osThreadGetId()) == NULL) return DEVICE_ERR_NULL;
BSP_UART_RegisterCallback(BSP_UART_DR16, BSP_UART_RX_CPLT_CB,
DR16_RxCpltCallback);
inited = true;
return DEVICE_OK;
}
int8_t DR16_Restart(void) {
__HAL_UART_DISABLE(BSP_UART_GetHandle(BSP_UART_DR16));
__HAL_UART_ENABLE(BSP_UART_GetHandle(BSP_UART_DR16));
return DEVICE_OK;
}
int8_t DR16_StartDmaRecv(DR16_t *dr16) {
if (HAL_UART_Receive_DMA(BSP_UART_GetHandle(BSP_UART_DR16),
(uint8_t *)&(dr16->data),
sizeof(dr16->data)) == HAL_OK)
return DEVICE_OK;
return DEVICE_ERR;
}
bool DR16_WaitDmaCplt(uint32_t timeout) {
return (osThreadFlagsWait(SIGNAL_DR16_RAW_REDY, osFlagsWaitAll, timeout) ==
SIGNAL_DR16_RAW_REDY);
}

View File

@ -0,0 +1,45 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <cmsis_os2.h>
#include "component/user_math.h"
#include "device/device.h"
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
typedef struct __packed {
uint16_t ch_r_x : 11;
uint16_t ch_r_y : 11;
uint16_t ch_l_x : 11;
uint16_t ch_l_y : 11;
uint8_t sw_r : 2;
uint8_t sw_l : 2;
int16_t x;
int16_t y;
int16_t z;
uint8_t press_l;
uint8_t press_r;
uint16_t key;
uint16_t res;
} DR16_Data_t;
typedef struct {
DR16_Data_t data;
} DR16_t;
/* Exported functions prototypes -------------------------------------------- */
int8_t DR16_Init(DR16_t *dr16);
int8_t DR16_Restart(void);
int8_t DR16_StartDmaRecv(DR16_t *dr16);
bool DR16_WaitDmaCplt(uint32_t timeout);
#ifdef __cplusplus
}
#endif

View File

@ -1,381 +0,0 @@
/*
OLED显示模块
使SPI通信时#define OLED_USE_SPI
使I2C通信时#define OLED_USE_I2C
*/
/* Includes ----------------------------------------------------------------- */
/* Include 自身的头文件。*/
#include "oled.h"
/* Include 标准库。*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
/* Include HAL相关的头文件。*/
#include "bsp_delay.h"
#include "bsp_spi.h"
#include <gpio.h>
#ifdef OLED_USE_SPI
#include "spi.h"
#
#elif defined OLED_USE_I2C
#include "i2c.h"
#endif
/* Include Component相关的头文件 */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
#ifdef OLED_USE_SPI
#define OLED_CMD_Set() HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, GPIO_PIN_SET)
#define OLED_CMD_Clr() HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, GPIO_PIN_RESET)
#define OLED_RST_Set() HAL_GPIO_WritePin(OLED_RST_GPIO_Port, OLED_RST_Pin, GPIO_PIN_SET)
#define OLED_RST_Clr() HAL_GPIO_WritePin(OLED_RST_GPIO_Port, OLED_RST_Pin, GPIO_PIN_RESET)
#elif defined OLED_USE_I2C
#define OLED_I2C_HANDLE hi2c1
#endif
/* Private typedef ---------------------------------------------------------- */
typedef enum {
OLED_WriteCMD = 0,
OLED_WriteData = 1,
}OLED_Write_t;
/* Private variables -------------------------------------------------------- */
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 */
};
static const uint8_t gram_logo[8][128] = {
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,0x02,0x06,0x0E,0X1E,0X3E,0X7E,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFE,0XFC,0XFC,0XF8,0XF8,0XF0,0XE0,0XC0,0X80,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0F,0X1F,0X3F,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF7,0XE7,0XC7,0X87,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x0F,0X1F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFE,0XF0,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0XC0,0XFC,0XFC,0XFC,0XFC,0XFC,0XFD,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFE,0XFC,0XFC,0XFC,0XFC,0XFC,0XFC,0XFC,0XFC,0XFC,0XFC,0XFE,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X7F,0X3F,0x0F,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0X80,0XF0,0XFE,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X1F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0X1F,0X3F,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XEF,0XCF,0X87,0x07,0x03,0x03,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0XE0,0XFC,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X3F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0X40,0X40,0X40,0XC0,0XC0,0XC0,0XC0,0XC1,0XC3,0XC7,0XCF,0XDF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFE,0XFC,0XF8,0XF0,0XE0,0XC0,0X80,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x0C,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x03,0x03,0x07,0x07,0x0F,0x0F,0X1F,0X1F,0X3F,0X3F,0X7F,0X7F,0XFF,0XF3,0XE3,0XC3,0X83,0x03,0x03,0x03,0x03,0x03,0x02,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,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,0x01,0x01,0x03,0x03,0x06,0x04,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,0x60,0x78,0x7B,0x1B,0x1B,0x1B,0x7B,0x7F,0x6F,0x4E,0x00,0x3E,0x7F,0x63,0x63,0x63,0x7F,0x3E,0x00,0x78,0x7B,0x6B,0x6B,0x6B,0x6B,0x7B,0x7F,0x36,0x00,0x3E,0x7F,0x63,0x63,0x63,0x7F,0x3E,0x40,0x60,0x78,0x3D,0x07,0x1F,0x7C,0x70,0x1D,0x07,0x7F,0x78,0x40,0x00,0x60,0x70,0x38,0x5D,0x6F,0x67,0x6F,0x7C,0x70,0x40,0x00,0x40,0x66,0x6F,0x6B,0x6B,0x6B,0x6B,0x7B,0x31,0x02,0x03,0x03,0x7F,0x7F,0x03,0x03,0x61,0x68,0x6B,0x6B,0x6B,0x6B,0x6B,0x0B,0x03,0x60,0x78,0x7B,0x1B,0x1B,0x1B,0x7B,0x7B,0x6F,0x4E,0x00,0x46,0x6F,0x6F,0x6B,0x6B,0x6B,0x7B,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
static OLED_t *goled;
static bool inited = false;
/* Private function ---------------------------------------------- */
static void OLED_WriteByte(uint8_t data, OLED_Write_t type) {
#ifdef OLED_USE_SPI
switch(type) {
case OLED_WriteCMD:
OLED_CMD_Clr();
break;
case OLED_WriteData:
OLED_CMD_Set();
break;
}
BSP_SPI_Transmit(BSP_SPI_OLED, &data, 1);
#elif defined OLED_USE_I2C
uint8_t cmd_data[2];
switch(type) {
case OLED_WriteCMD:
cmd_data[0] = 0x00;
break;
case OLED_WriteData:
cmd_data[0] = 0x40;
break;
}
cmd_data[1] = data;
HAL_I2C_Master_Transmit_DMA(OLED_I2C, OLED_I2C_ADDRESS, cmd_data, 2);
#endif
BSP_Delay(1);
}
static void OLED_WriteSequenceData(uint8_t *data, uint16_t len) {
#ifdef OLED_USE_SPI
OLED_CMD_Set();
HAL_SPI_Transmit_DMA(&hspi1, data, len);
#elif defined OLED_USE_I2C
/* TODO */
uint8_t cmd_data[2];
cmd_data[0] = 0x40;
cmd_data[1] = data;
HAL_I2C_Master_Transmit_DMA(OLED_I2C, OLED_I2C_ADDRESS, cmd_data, 2);
#endif
}
/* Exported functions ------------------------------------------------------- */
int8_t OLED_Init(OLED_t *oled) {
if (oled == NULL)
return -1;
if (inited)
return -1;
oled->cursor.column = 0;
oled->cursor.page = 0;
oled->modified = true;
goled = oled;
OLED_RST_Clr();
BSP_Delay(1);
OLED_RST_Set();
BSP_Delay(5);
OLED_WriteByte(0xae, OLED_WriteCMD); /* Dot martix display off. */
OLED_WriteByte(0x00, OLED_WriteCMD); /* Set lower column address:(00H~0FH). */
OLED_WriteByte(0x10, OLED_WriteCMD); /* Set higher column address:(10H~1FH). */
OLED_WriteByte(0x20, OLED_WriteCMD); /* Set Memory Addressing Mode */
OLED_WriteByte(0x10, OLED_WriteCMD); /* 00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid */
OLED_WriteByte(0x32, OLED_WriteCMD); /* Set pump voltage 8v. */
OLED_WriteByte(0x40, OLED_WriteCMD); /* Set display start line:(40H~7FH). */
OLED_WriteByte(0x81, OLED_WriteCMD); /* Contarst control. */
OLED_WriteByte(0x6f, OLED_WriteCMD); /* Contarst: 0x00~0xff. */
OLED_WriteByte(0xa1, OLED_WriteCMD); /* Set segment re-map. 0xa0 or 0xa1. */
OLED_WriteByte(0xa4, OLED_WriteCMD); /* Entire display off. */
OLED_WriteByte(0xa6, OLED_WriteCMD); /* Set normal display. */
OLED_WriteByte(0xa8, OLED_WriteCMD); /* Set multiplex ratio. */
OLED_WriteByte(0x3f, OLED_WriteCMD);
OLED_WriteByte(0xad, OLED_WriteCMD); /* Set DC/DC booster. */
OLED_WriteByte(0x8b, OLED_WriteCMD);
OLED_WriteByte(0xb0, OLED_WriteCMD); /* Set page address. */
OLED_WriteByte(0xc8, OLED_WriteCMD); /* Com scan COM0->COM63. */
OLED_WriteByte(0xd3, OLED_WriteCMD); /* Set display offset. */
OLED_WriteByte(0x00, OLED_WriteCMD);
OLED_WriteByte(0xd5, OLED_WriteCMD); /* Set frame frequency. */
OLED_WriteByte(0xf0, OLED_WriteCMD);
OLED_WriteByte(0xd9, OLED_WriteCMD); /* Set pre_charge period. */
OLED_WriteByte(0x22, OLED_WriteCMD);
OLED_WriteByte(0xda, OLED_WriteCMD); /* Com pin configuration. */
OLED_WriteByte(0x12, OLED_WriteCMD);
OLED_WriteByte(0xdb, OLED_WriteCMD); /* Set vcom deselect level. */
OLED_WriteByte(0x20, OLED_WriteCMD);
OLED_WriteByte(0x8d, OLED_WriteCMD); /* Set DC-DC enable */
OLED_WriteByte(0x14, OLED_WriteCMD);
OLED_WriteByte(0xaf, OLED_WriteCMD); /* Display on. */
memcmp(oled->gram, gram_logo, sizeof(oled->gram));
OLED_SetAllRam(oled, OLED_PEN_WRITE); /* Clear memory. */
OLED_Refresh(oled); /* Display initial picture. */
return 0;
}
OLED_t *OLED_GetDevice(void) {
if (inited) {
return goled;
}
return NULL;
}
int8_t OLED_PrintRam(OLED_t *oled, const char* str) {
if (str == NULL)
return -1;
oled->modified = true;
for (uint16_t i = 0; str[i] != '\0'; i++) {
uint8_t c = str[i];
if (c < 32) {
switch (c) {
case '\n':
oled->cursor.page ++;
oled->cursor.column = 0;
break;
case '\t':
oled->cursor.column += 16;
break;
}
} else if (c < 126) {
if (oled->cursor.column == 128) {
oled->cursor.page ++;
oled->cursor.column = 0;
}
if (oled->cursor.page == 8) {
OLED_SetAllRam(oled, OLED_PEN_CLEAR);
oled->cursor.page = 0;
}
memcpy(&oled->gram[oled->cursor.page][oled->cursor.column], oled_font[c- 32], sizeof(oled_font[0]));
oled->cursor.column += 8;
}
}
return 0;
}
uint8_t OLED_RewindRam(OLED_t *oled) {
oled->modified = true;
OLED_SetAllRam(oled, OLED_PEN_CLEAR);
oled->cursor.page = 0;
oled->cursor.column = 0;
return 0;
}
uint8_t OLED_SetAllRam(OLED_t *oled, OLED_Pen_t pen) {
switch(pen) {
case OLED_PEN_WRITE:
memset(oled->gram, -1, sizeof(oled->gram));
break;
case OLED_PEN_CLEAR:
memset(oled->gram, 0, sizeof(oled->gram));
break;
case OLED_PEN_INVERSION:
for (uint8_t i = 0; i < 8; i++) {
for (uint8_t n = 0; n < 128; n++) {
oled->gram[i][n] = ~oled->gram[i][n];
}
}
break;
}
return 0;
}
uint8_t OLED_DisplayOn(OLED_t *oled) {
OLED_WriteByte(0x8d, OLED_WriteCMD);
OLED_WriteByte(0x14, OLED_WriteCMD);
OLED_WriteByte(0xaf, OLED_WriteCMD);
return 0;
}
uint8_t OLED_DisplayOff(OLED_t *oled) {
OLED_WriteByte(0x8d, OLED_WriteCMD);
OLED_WriteByte(0x10, OLED_WriteCMD);
OLED_WriteByte(0xae, OLED_WriteCMD);
return 0;
}
void OLED_SetCursor(uint8_t x, uint8_t y)
{
OLED_WriteByte((0xb0 + y), OLED_WriteCMD); /*set page address y */
OLED_WriteByte(((x&0xf0)>>4)|0x10, OLED_WriteCMD); /*set column high address */
OLED_WriteByte((x&0x0f), OLED_WriteCMD); /*set column low address */
}
uint8_t OLED_Refresh(OLED_t *oled) {
for (uint8_t i = 0; i < 8; i++) {
OLED_SetCursor(0, i);
for (uint8_t n = 0; n < 8; n++) {
OLED_WriteByte(oled->gram[i][n], OLED_WriteData);
}
}
oled->modified = false;
return 0;
}

View File

@ -1,45 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <stdbool.h>
#include <stdint.h>
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
typedef enum {
OLED_PEN_CLEAR = 0,
OLED_PEN_WRITE = 1,
OLED_PEN_INVERSION = 2,
} OLED_Pen_t;
typedef struct {
uint8_t column;
s uint8_t page;
} OLED_Cursor_t;
typedef struct {
OLED_Cursor_t cursor;
uint8_t gram[8][128];
bool modified;
} OLED_t;
/* Exported functions prototypes -------------------------------------------- */
uint8_t OLED_Init(OLED_t *oled);
OLED_t *OLED_GetDevice(void);
uint8_t OLED_PrintRam(OLED_t *oled, const char *str);
uint8_t OLED_RewindRam(OLED_t *oled);
uint8_t OLED_SetAllRam(OLED_t *oled, OLED_Pen_t pen);
uint8_t OLED_DisplayOn(OLED_t *oled);
uint8_t OLED_DisplayOff(OLED_t *oled);
uint8_t OLED_Refresh(OLED_t *oled);
#ifdef __cplusplus
}
#endif

126
bsp_config.yaml Normal file
View File

@ -0,0 +1,126 @@
can:
devices:
- instance: CAN1
name: CAN1
- instance: CAN2
name: CAN2
enabled: true
dwt:
enabled: true
gpio:
configs:
- custom_name: USER_KEY
has_exti: true
ioc_label: USER_KEY
pin: PA0-WKUP
- custom_name: ACCL_CS
has_exti: false
ioc_label: ACCL_CS
pin: PA4
- custom_name: GYRO_CS
has_exti: false
ioc_label: GYRO_CS
pin: PB0
- custom_name: SPI2_CS
has_exti: false
ioc_label: SPI2_CS
pin: PB12
- custom_name: HW0
has_exti: false
ioc_label: HW0
pin: PC0
- custom_name: HW1
has_exti: false
ioc_label: HW1
pin: PC1
- custom_name: HH
has_exti: false
ioc_label: hh
pin: PC2
- custom_name: ACCL_INT
has_exti: true
ioc_label: ACCL_INT
pin: PC4
- custom_name: GYRO_INT
has_exti: true
ioc_label: GYRO_INT
pin: PC5
- custom_name: CMPS_INT
has_exti: true
ioc_label: CMPS_INT
pin: PG3
- custom_name: CMPS_RST
has_exti: false
ioc_label: CMPS_RST
pin: PG6
enabled: true
i2c:
devices:
- instance: I2C1
name: OLED
enabled: true
mm:
enabled: true
pwm:
configs:
- channel: TIM_CHANNEL_1
custom_name: TIM8_CH1
label: TIM8_CH1
timer: TIM8
- channel: TIM_CHANNEL_3
custom_name: LASER
label: LASER
timer: TIM3
- channel: TIM_CHANNEL_3
custom_name: BUZZER
label: BUZZER
timer: TIM4
- channel: TIM_CHANNEL_2
custom_name: TIM1_CH2
label: TIM1_CH2
timer: TIM1
- channel: TIM_CHANNEL_3
custom_name: TIM1_CH3
label: TIM1_CH3
timer: TIM1
- channel: TIM_CHANNEL_4
custom_name: TIM1_CH4
label: TIM1_CH4
timer: TIM1
- channel: TIM_CHANNEL_1
custom_name: TIM1_CH1
label: TIM1_CH1
timer: TIM1
- channel: TIM_CHANNEL_1
custom_name: IMU_HEAT_PWM
label: IMU_HEAT_PWM
timer: TIM10
- channel: TIM_CHANNEL_1
custom_name: LED_B
label: LED_B
timer: TIM5
- channel: TIM_CHANNEL_2
custom_name: LED_G
label: LED_G
timer: TIM5
- channel: TIM_CHANNEL_3
custom_name: LED_R
label: LED_R
timer: TIM5
- channel: TIM_CHANNEL_2
custom_name: TIM8_CH2
label: TIM8_CH2
timer: TIM8
enabled: true
spi:
devices:
- instance: SPI1
name: BMI088
enabled: true
time:
enabled: true
uart:
devices:
- instance: USART3
name: DR16
enabled: true