基于你的需求,我来分析一下逻辑顺序和中断选择:
推荐方案:使用定时器中断
理由:
1.精度要求高 - 正倒计时、PWM调光都需要精确时间
2.多任务并发 - 需要同时处理按键、显示、超声波、计时等
3.避免阻塞 - delay()会导致其他功能无法及时响应
程序逻辑结构建议:
1. 系统初始化
void System_Init(void) {
Timer0_Init(); // 用于系统时基(1ms)
Timer1_Init(); // 用于PWM调光
OLED_Init();
Key_Init();
Ultrasonic_Init();
Buzzer_Init();
LED_Init();
}
2. 主程序框架
void main(void) {
System_Init();
while(1) {
Key_Scan(); // 按键扫描
Menu_Process(); // 菜单处理
Mode_Process(); // 模式处理
Display_Process(); // 显示更新
}
}
3. 定时器中断设计
// Timer0 中断服务函数 (1ms)
void Timer0_ISR(void) interrupt 1 {
static uint16_t ms_count = 0;
Key_Debounce(); // 按键消抖
Timer_Count(); // 计时计数
Ultrasonic_Process(); // 超声波处理
Buzzer_Process(); // 蜂鸣器处理
LED_Blink_Process(); // LED闪烁处理
ms_count++;
if(ms_count >= 1000) { // 1秒更新
ms_count = 0;
System_1s_Update(); // 系统1秒更新
}
}
4. 按键分配建议
#define KEY_MODE P1_0 // 按键1:模式切换
#define KEY_UP P1_1 // 按键2:增加/确认
#define KEY_DOWN P1_2 // 按键3:减少/返回
#define KEY_SET P1_3 // 按键4:设置/功能
5. 菜单状态机设计
enum Menu_State {
MAIN_MENU = 0, // 主菜单
MANUAL_MODE, // 手动调光模式
STUDY_MODE, // 学习模式
COUNT_UP_MODE, // 正计时
COUNT_DOWN_MODE, // 倒计时
SET_TIME_MODE, // 设置时间
ULTRASONIC_MODE // 超声波模式
};
6. 关键功能实现要点
PWM调光(使用Timer1)
void PWM_Set_Duty(uint8_t duty) {
// 设置PWM占空比实现亮度调节
// 三档亮度:30%, 60%, 100%
}
学习模式计时
void Study_Timer_Process(void) {
if(study_mode == COUNT_UP) {
// 正计时逻辑
if(seconds % 60 == 0) buzzer_beep(); // 每分钟响
} else {
// 倒计时逻辑
if(timer_remaining == 0) buzzer_beep(); // 结束响
}
}
超声波坐姿检测
void Posture_Check(uint16_t distance) {
if(distance < 10) {
LED_Blink_Fast(); // 快速闪烁
} else if(distance <= 20) {
Buzzer_Fast(); // 快速报警
} else if(distance <= 30) {
Buzzer_Slow(); // 慢速报警
}
}
开发建议:
1.模块化编程 - 每个功能独立成模块
2.状态机设计 - 使用枚举管理各种状态
3.分阶段实现 - 先完成基础功能,再添加高级特性
4.调试输出 - 通过串口或OLED显示调试信息
这样设计可以确保系统响应及时,各功能协调工作,代码结构清晰易于维护。
|