简介:一个能够高自由度定义的桌面控制键盘,可以编辑图片显示、支持键盘、鼠标、媒体功能以及多种可配置硬件触发方式,由 Electron 制作的上位机使用直观简单,编辑处理迅速。
我将详细阐述针对图片中所示的桌面控制键盘项目,从需求分析、系统架构设计、代码实现到测试验证和维护升级的全过程,并提供一套经过实践验证的C代码架构方案。
关注微信公众号,提前获取相关推文
![]()
项目需求分析
-
功能需求:
- 按键功能: 支持多个自定义按键,每个按键的功能可由上位机配置,包括但不限于:
- 键盘按键模拟: 模拟标准键盘按键,包括组合键(Ctrl+C, Alt+Tab等)。
- 鼠标按键模拟: 模拟鼠标点击、滚动等操作。
- 媒体控制: 控制音乐播放、暂停、音量调节等。
- 宏定义: 执行预设的操作序列。
- 自定义命令: 执行用户定义的特定功能。
- 旋钮功能: 支持多个旋钮,旋钮功能可由上位机配置,如:
- 音量调节: 精确控制系统音量。
- 屏幕缩放: 放大/缩小屏幕内容。
- 页面滚动: 滚动网页或文档。
- 自定义功能: 执行用户定义的特定功能。
- 显示功能:
- LCD显示: 驱动小型LCD屏幕,显示当前按键/旋钮配置、运行状态等信息。
- 图片显示: 显示由上位机传输的图片,实现自定义按键图案显示。
- 触发功能: 支持多种可配置硬件触发方式:
- 按键触发: 按下按键后执行对应的功能。
- 旋钮触发: 旋转旋钮时执行对应的功能。
- 外部信号触发: 通过GPIO接口读取外部信号,触发特定功能。
- 上位机通信: 通过USB接口与上位机(Electron应用)进行双向通信:
- 配置数据接收: 接收上位机发送的按键/旋钮配置、图片数据等。
- 状态数据发送: 将按键/旋钮状态、系统状态等信息发送给上位机。
- 可扩展性: 系统应具有良好的可扩展性,方便添加新的功能模块和硬件支持。
- 按键功能: 支持多个自定义按键,每个按键的功能可由上位机配置,包括但不限于:
-
非功能需求:
- 实时性: 系统响应速度快,操作延迟低。
- 可靠性: 系统运行稳定,不易出错。
- 低功耗: 尽可能降低功耗,延长设备使用时间。
- 易维护性: 代码结构清晰,方便维护和升级。
- 用户友好性: 上位机操作简单直观,方便用户自定义配置。
系统架构设计
根据以上需求,我将采用分层架构来设计嵌入式系统,主要分为以下几个层次:
- 硬件抽象层 (HAL):
- 目的: 屏蔽底层硬件差异,提供统一的硬件访问接口。
- 模块:
- GPIO驱动: 管理按键输入、外部信号输入、LED输出等。
- ADC驱动: 读取旋钮的模拟信号。
- SPI/I2C驱动: 控制LCD显示屏。
- USB驱动: 实现与上位机的USB通信。
- 定时器驱动: 用于定时任务、延时等。
- 驱动层:
- 目的: 提供特定设备的驱动,向上层提供服务。
- 模块:
- 按键驱动: 负责按键扫描、去抖动、按键事件识别。
- 旋钮驱动: 负责旋钮数据读取、滤波、旋转事件识别。
- LCD驱动: 负责LCD屏幕的初始化、显示、图片显示。
- USB通信驱动: 负责USB数据收发、协议解析。
- 核心服务层:
- 目的: 实现系统的核心功能,协调各个模块的工作。
- 模块:
- 按键映射模块: 存储和管理按键与功能的映射关系。
- 旋钮映射模块: 存储和管理旋钮与功能的映射关系。
- 图片管理模块: 管理接收到的图片数据,并提供显示功能。
- 命令执行模块: 根据按键/旋钮映射关系,执行相应的功能。
- 系统状态管理模块: 管理系统运行状态,并向上位机报告。
- 应用层:
- 目的: 实现具体的应用逻辑,包括按键/旋钮功能执行、状态更新、与上位机通信等。
- 模块:
- 主循环: 负责系统任务的调度和执行。
- 配置管理: 负责读取和更新系统配置,与上位机进行数据同步。
- 事件处理: 处理按键事件、旋钮事件、USB事件等。
- 上位机层:
- 目的: 提供友好的用户界面,配置设备、传输数据。
- 模块:
- 配置界面: 用于配置按键功能、旋钮功能、图片显示等。
- 数据传输: 负责向嵌入式设备发送配置数据和图片数据。
- 状态显示: 显示设备的运行状态。
代码实现 (C语言)
以下是基于上述架构的C代码示例,包含核心模块的实现,由于篇幅所限,不能全部展示,但足以体现整体框架和关键技术。
// ------ 1. 头文件定义 ------
#include
#include
#include
#include "hal.h" // 硬件抽象层头文件
#include "config.h" // 配置头文件
#include "usb_comm.h"
#include "lcd_display.h"
// ------ 2. 全局变量定义 ------
// 按键映射表,假设最大按键数量为10
#define MAX_BUTTONS 10
typedef struct {
uint8_t button_id; // 按键ID
uint8_t function_type; // 功能类型: 键盘, 鼠标, 媒体, 宏, 自定义
uint8_t function_param[6]; //功能参数
} ButtonMapping;
ButtonMapping button_map[MAX_BUTTONS];
uint8_t button_count = 0;
// 旋钮映射表,假设最大旋钮数量为2
#define MAX_ENCODERS 2
typedef struct {
uint8_t encoder_id;
uint8_t function_type; // 功能类型: 音量, 滚动, 自定义
uint8_t function_param[6]; // 功能参数
} EncoderMapping;
EncoderMapping encoder_map[MAX_ENCODERS];
uint8_t encoder_count = 0;
// 3.枚举定义
typedef enum {
FUNC_TYPE_NONE,
FUNC_TYPE_KEYBOARD,
FUNC_TYPE_MOUSE,
FUNC_TYPE_MEDIA,
FUNC_TYPE_MACRO,
FUNC_TYPE_CUSTOM
} FunctionType;
typedef enum {
ENCODER_TYPE_NONE,
ENCODER_TYPE_VOLUME,
ENCODER_TYPE_SCROLL,
ENCODER_TYPE_CUSTOM
} EncoderType;
// ----- 3. 函数声明 ------
void system_init(void);
void handle_button_event(uint8_t button_id, bool is_pressed);
void handle_encoder_event(uint8_t encoder_id, int16_t rotation);
void update_lcd_display(void);
void process_usb_data(uint8_t *data, uint16_t len);
void execute_function(uint8_t function_type, uint8_t *params);
void load_config(void);
void save_config(void);- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
评论记录:
回复评论: