找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 134|回复: 2
打印 上一主题 下一主题
收起左侧

想手搓一个智能台灯

[复制链接]
跳转到指定楼层
楼主
ID:1163085 发表于 2025-11-15 11:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位大佬我来求助一下,本人新手,并非伸手党,想来问问用51单片机(且只有4个按键)想实现下面的功能的话,敲代码的时候什么逻辑顺序比较好,用delay还是用计时器中断比较好?
1.按键手动调节灯亮度(三档),调节亮度的时候有一个渐变过程
2.可以按键控制进入学习模式,可以正计时也可以倒计时,OLED显示时位,分位和秒位,正计时每满1分钟蜂鸣器响一次,倒计时结束蜂鸣器响一次,可以使用按键控制倒计时的时间,按下按键4,时间加,按下按键5,时间减
智能模式:HC-SR04 超声波模块
1.超声波传感器采集坐姿距离,将距离显示在OLED上。
2.坐姿报警:人与超声波之间的距离20≤x≤30cm发出警报,10≤x≤20警报频率变高,小于10cmLED2闪烁。3.检测到30s没有人在桌前,自动关灯。
使用OLED制作一个菜单,通过菜单控制三种模式切换,调节灯光,进入学习模式,正计时,倒计时,设置时间,超声波距离
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:155507 发表于 2025-11-16 11:35 | 只看该作者
基于你的需求,我来分析一下逻辑顺序和中断选择:

推荐方案:使用定时器中断
理由:
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显示调试信息

这样设计可以确保系统响应及时,各功能协调工作,代码结构清晰易于维护。

回复

使用道具 举报

板凳
ID:584814 发表于 2025-11-16 14:46 | 只看该作者
敲代码的时候什么逻辑顺序比较好,用delay还是用计时器中断比较好?
楼主是来招商引资的罢
据说网上有专门做这个生意的,从数百起步直到过万的都有。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表