找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

51单片机电子闹钟 小白,求助

查看数: 481 | 评论数: 3 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2025-11-20 22:37

正文摘要:

由于本论坛禁止直接求程序,禁止伸手党,所以向大家请教一下大致的实现方法与思路,理清头绪后我自己来写程序去实现,谢谢大家

回复

ID:155507 发表于 2025-11-22 15:11
下面是基于"KR-51开发板"(51单片机)的简化电子闹钟核心C代码框架,实现如下功能需求:  
- 当前时间/闹钟时间设定  
- 光敏控制数码管背光  
- 按键切换/设置/加减  
- 蜂鸣器闹铃&LED闪烁

  1. /*
  2. 51单片机电子闹钟 KR-51开发板
  3. 实现功能:
  4. 1.可自主设定当前时间与闹钟时间,4位共阳数码管
  5. 2.利用光敏传感器实现有光时数码管常亮,无光时,按下按键,数码管亮起,可切换,查看当前时间与闹钟时间
  6. 3.闹钟时间到了,蜂鸣器响起同时,Led灯按 200ms频率闪烁
  7. 1. 主要口线分配

  8. | 功能           | 单片机引脚    |
  9. |----------------|---------------|
  10. | 数码管段选 a-f | P0.0~P0.7     |
  11. | 数码管位选     | P2.0~P2.3     |
  12. | 蜂鸣器         | P2.5          |
  13. | LED            | P1.0          |
  14. | 光敏传感器     | P1.7          |
  15. | 按键功能       | P3.2          |
  16. | 按键切换       | P3.3          |
  17. | 按键加         | P3.4          |
  18. | 按键减         | P3.5          |

  19. 使用说明

  20. - 按KEY_MODE切换显示当前和闹钟时间。
  21. - 三个按键:KEY_ADD/KEY_SUB调节小时,KEY_FUNC调节分钟。
  22. - 光敏自动调节背光,无光时按任一功能键亮屏。
  23. - 闹钟时间到,蜂鸣器响、LED闪;复位或重新设定可清除闹钟。



  24. 代码逻辑清晰,各功能子模块独立,易于修改和维护。


  25. */


  26. #include <reg51.h>
  27. #define uint unsigned int
  28. #define uchar unsigned char

  29. // 段码表
  30. uchar code seg_tab[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //共阳数码管

  31. // 硬件口线映射
  32. sbit BUZZER = P2^5;     //蜂鸣器
  33. sbit LED    = P1^0;
  34. sbit LDR    = P1^7;     // 光敏
  35. sbit KEY_FUNC = P3^2;
  36. sbit KEY_MODE = P3^3;
  37. sbit KEY_ADD  = P3^4;
  38. sbit KEY_SUB  = P3^5;

  39. //主要数据结构
  40. // 任务标志
  41. bit alarm_flag = 0;
  42. bit display_flag = 1;    // 数码管亮/灭
  43. bit key_enable_flag = 0; // 消抖允许
  44. uchar key_state = 0;     // 按键当前状态

  45. // 时钟及闹钟变量
  46. uchar hour=12, minute=0;
  47. uchar alarm_hour=6, alarm_minute=30;
  48. uchar display_mode=0; // 0:当前时间 1:闹钟时间
  49. uint  tcount=0;       // 定时器计数


  50. //时间与闹钟管理模块

  51. void time_update(void) {
  52.     tcount++;
  53.     if(tcount >= 2400) {        //假设定时25ms; 2400*25ms=60s
  54.         tcount = 0;
  55.         minute++;
  56.         if(minute >= 60) {
  57.             minute = 0;
  58.             hour++;
  59.             if(hour >= 24) hour=0;
  60.         }
  61.         if(hour == alarm_hour && minute == alarm_minute) {
  62.             alarm_flag = 1; //闹钟触发
  63.         }
  64.     }
  65. }

  66. void alarm_clear(void) {
  67.     alarm_flag = 0;
  68.     BUZZER = 0;
  69.     LED = 0;
  70. }


  71. //按键扫描与功能切换

  72. void key_scan(void) {
  73.     if(KEY_MODE == 0) {        // 切换显示模式
  74.         while(KEY_MODE == 0);  //松手消抖
  75.         display_mode ^= 1;
  76.     }
  77.     if(display_mode == 0) {    //当前时间
  78.         if(KEY_ADD == 0) {     //小时加
  79.             while(KEY_ADD == 0);
  80.             hour++; if(hour > 23) hour=0;
  81.         }
  82.         if(KEY_SUB == 0) {     //小时减
  83.             while(KEY_SUB == 0);
  84.             if(hour == 0) hour=23; else hour--;
  85.         }
  86.         if(KEY_FUNC == 0) {    //分钟加
  87.             while(KEY_FUNC == 0);
  88.             minute++; if(minute > 59) minute=0;
  89.         }
  90.     } else {                   //闹钟时间
  91.         if(KEY_ADD == 0) {
  92.             while(KEY_ADD == 0);
  93.             alarm_hour++; if(alarm_hour > 23) alarm_hour=0;
  94.         }
  95.         if(KEY_SUB == 0) {
  96.             while(KEY_SUB == 0);
  97.             if(alarm_hour == 0) alarm_hour=23; else alarm_hour--;
  98.         }
  99.         if(KEY_FUNC == 0) {
  100.             while(KEY_FUNC == 0);
  101.             alarm_minute++; if(alarm_minute > 59) alarm_minute=0;
  102.         }
  103.     }
  104. }


  105. //光敏及显示管理子模块
  106. void ldr_check(void) {
  107.     // 有光时一直亮,没光时只在按键显示
  108.     if(LDR == 1)
  109.         display_flag = 1;
  110.     else {
  111.         if(KEY_FUNC == 0) display_flag = 1;
  112.         else display_flag = 0;
  113.     }
  114. }


  115. //数码管动态显示模块
  116. void display_time(uchar h, uchar m) {
  117.     uchar disp_buf[4],i;
  118.     disp_buf[0] = h / 10;
  119.     disp_buf[1] = h % 10;
  120.     disp_buf[2] = m / 10;
  121.     disp_buf[3] = m % 10;
  122.     for(i=0; i<4; i++) {
  123.         P2 = ~(1 << i);           // 位选P2.0~P2.3共阳
  124.         P0 = seg_tab[disp_buf[i]]; // 段选
  125.         // 若想显示小数点或其它符号,可此处加处理
  126.         // 延时,用于刷新和消影
  127.     }
  128. }

  129. //闹钟蜂鸣/LED闪烁模块
  130. void alarm_task(void) {
  131.     if(alarm_flag) {
  132.         BUZZER = 1;
  133.         // 200ms LED闪烁循环(简单用定时来实现)
  134.         if(tcount % 8 < 4) LED = 1;
  135.         else LED = 0;
  136.     }
  137. }


  138. //定时器初始化与中断服务
  139. void Timer0_Init(void) {
  140.     TMOD = 0x01;     //方式1 16位
  141.     TH0 = (65536-25000)/256;  //25ms
  142.     TL0 = (65536-25000)%256;
  143.     ET0 = 1; TR0 = 1; EA = 1;
  144. }

  145. void Timer0_ISR(void) interrupt 1 {
  146.     TH0 = (65536-25000)/256; TL0 = (65536-25000)%256;
  147.     time_update();     //更新时间,每25ms进一次
  148. }



  149. //主循环
  150. void main(void) {
  151.     Timer0_Init();
  152.     alarm_clear();
  153.     while(1) {
  154.         key_scan();
  155.         ldr_check();
  156.         if(display_flag) {
  157.             if(display_mode == 0) display_time(hour, minute);
  158.             else display_time(alarm_hour, alarm_minute);
  159.         } else {
  160.             //可以关闭数码管
  161.             P0 = 0x00; P2 = 0x00;
  162.         }
  163.         alarm_task();
  164.         // 若需要按键消抖与显示稳定可增加适度延时
  165.     }
  166. }


复制代码






ID:584814 发表于 2025-11-22 12:00
啥也没有开始问,就是想白嫖文档的样子。

ID:1133081 发表于 2025-11-21 21:45
20ms频率闪烁你能看到闪?

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

Powered by 单片机教程网

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