共计 1910 个字符,预计需要花费 5 分钟才能阅读完成。
硬件电路设计
按键抖动是嵌入式系统中最常见的问题之一。机械按键在按下和释放时会产生 5 -10ms 的抖动,这会导致单片机误判多次按键动作。解决这个问题的第一步是在硬件层面进行滤波。

- RC 滤波电路设计 :
- 典型值:R=10kΩ,C=0.1μF
- 时间常数 τ =RC=1ms
- 计算公式:Vc = V0*(1-e^(-t/RC))
-
建议在按键输入端并联一个 0.1μF 电容到地
-
ESD 防护设计 :
- 在 IO 口串联 100Ω 电阻
- 并联 TVS 二极管到地
- 避免直接连接外部接口
软件消抖算法
硬件滤波只能减轻抖动,要完全消除抖动还需要软件配合。最常用的方法是定时器扫描法。
- 初始化定时器,设置 10ms 中断
- 在中断服务程序中扫描按键状态
- 采用状态机思想处理按键
关键代码片段:
typedef enum {
KEY_IDLE,
KEY_DOWN,
KEY_DEBOUNCE,
KEY_CONFIRM
} KeyState;
void Timer0_ISR() interrupt 1 {
static KeyState keyState = KEY_IDLE;
static uint8_t debounceCnt = 0;
switch(keyState) {
case KEY_IDLE:
if(KEY_PIN == 0) {keyState = KEY_DOWN;}
break;
case KEY_DOWN:
if(KEY_PIN == 0) {
keyState = KEY_DEBOUNCE;
debounceCnt = 0;
}
break;
case KEY_DEBOUNCE:
if(++debounceCnt >= 5) { // 50ms 消抖
if(KEY_PIN == 0) {
keyState = KEY_CONFIRM;
keyPressCallback();} else {keyState = KEY_IDLE;}
}
break;
case KEY_CONFIRM:
if(KEY_PIN == 1) {
keyState = KEY_IDLE;
keyReleaseCallback();}
break;
}
}
状态机设计
对于复杂的人机交互系统,状态机是最佳选择。下面是菜单系统的状态机实现:
stateDiagram-v2
[*] --> MainMenu
MainMenu --> SettingMenu: 按下设置键
SettingMenu --> TimeSetting: 选择时间设置
SettingMenu --> [*]: 长按返回键
TimeSetting --> HourSetting: 选择小时
TimeSetting --> MinuteSetting: 选择分钟
TimeSetting --> SettingMenu: 按下返回键
核心状态机结构体:
typedef void (*StateHandler)(void);
typedef struct {
StateHandler currentState;
uint8_t menuLevel;
void* pContext;
} StateMachine;
void RunStateMachine(StateMachine* pSM) {if(pSM->currentState != NULL) {pSM->currentState();
}
}
显示优化
LCD 刷新是另一个性能瓶颈。采用双缓冲技术可以显著提升体验:
- 创建两个显示缓冲区
- 后台线程更新缓冲区 B
- 垂直消隐期间切换缓冲区
- 使用 DMA 传输数据
关键实现:
uint8_t dispBuffer[2][128*64/8];
volatile uint8_t activeBuffer = 0;
void LCD_Refresh() {uint8_t* pData = dispBuffer[activeBuffer^1];
// 通过 SPI 发送数据到 LCD
// ...
activeBuffer ^= 1; // 切换缓冲区
}
避坑指南
在实际开发中,有几个常见问题需要注意:
- 中断服务程序 :
- 执行时间控制在 10μs 以内
- 避免在中断中调用复杂函数
-
使用标志位 + 主循环处理模式
-
状态机测试 :
- 为每个状态设计测试用例
- 模拟异常输入(快速连续按键)
-
检查内存泄漏(特别是上下文指针)
-
系统稳定性 :
- 添加看门狗定时器
- 关键变量使用 volatile 修饰
- 对指针进行有效性检查
性能优化
与 RTOS 方案相比,状态机有这些优势:
- 内存占用小(不需要任务栈)
- 响应速度快(无任务切换开销)
- 代码可预测性高
- 适合资源受限的 8 位单片机
移植到 STM8 的注意事项:
- 修改中断向量表
- 调整定时器配置
- 优化状态机内存占用
- 注意 IO 口驱动能力差异
总结
通过合理的硬件设计 + 软件状态机,可以在 C51 上实现稳定可靠的人机交互系统。关键是要做好:
- 彻底的按键消抖(硬件 + 软件)
- 清晰的状态划分
- 非阻塞的显示刷新
- 严谨的异常处理
这套方案已经在我们多个量产项目中验证,平均无故障时间超过 5 万小时。希望对大家的嵌入式开发有所帮助!
正文完
