查看: 127|回复: 5

[天问STC8]单片机学习笔记(制作小闹钟)

[复制链接]

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
发表于 2021-7-20 10:19:13 | 显示全部楼层 |阅读模式
这两天的单片机学习的主要任务是在开发板上完成一个有闹钟功能的时钟。那笔记就记录程序从头到尾完成的过程。

需求:制作一个LED数字时钟,有闹钟功能,可以设置时间,和闹钟时间。

目录:
1、分析与需求设计。
2、程序结构设计。
3、函数的设计与实现。
4、总结。
回复

使用道具 举报

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
 楼主| 发表于 2021-7-20 11:11:17 | 显示全部楼层
需求分析与设计

需求:制作一个LED数字时钟,有闹钟功能,可以设置时间,和闹钟时间
按照需求,这个程序大致分为这么几个功能:
1、时间显示功能;
2、时间设置功能;
3、闹钟设置功能;
4、闹钟触发功能;


每一个功能当中,分别要使用不同的模块。
时间显示功能:数码管。
时间设置功能:数码管,按键。
闹钟设置功能:数码管,按键。
闹钟触发功能:数码管,蜂鸣器。

根据以上的分析进行设计,产品用key1-key4四个按键进行控制,按下key3时,进入时间设置功能,闹钟时间暂停,等待设置结束后继续流动,开始设置时间时,默认修改“时”的大小,按key1时+1,“时”超过23时归零;按下key2键进行确认,开始修改“分”的大小,按key1时+1,超过60时归零;再按下key2键确认,修改秒的大小,超过60时归零,按下key2确认,时间重新流动。

按下key4键进入闹钟设置。开始设置时间时,默认修改“时”的大小,按key1时+1,“时”超过23时归零;按下key2键进行确认,开始修改“分”的大小,按key1时+1,超过60时归零;再按下key2键确认,修改秒的大小,超过60时归零,按下key2确认。当闹钟时间和当前时间吻合时,触发蜂鸣器。




回复

使用道具 举报

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
 楼主| 发表于 2021-7-20 11:21:17 | 显示全部楼层
程序结构设计

总体结构:



变量/头文件/常量:



函数:

CarryTime函数:用于显示时间的进位。

Timedisplay函数:用于显示时间。

SET_time函数:用于设置时间。

SET_Alarm函数:设置闹钟时间。

Judge_Alarm函数:判断是否到达闹钟时间。

loop()函数:启动器。
2.PNG
1.PNG
回复

使用道具 举报

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
 楼主| 发表于 2021-7-20 11:35:12 | 显示全部楼层
函数的设计和实现

(1)Carry_Time函数:
    这个函数用于时间的进位。


源码:


void Carry_Time(){
  if(Second > 58){
    Second = 0;
    Minutes = Minutes + 1;
  }
  if(Minutes > 58){
    Minutes = 0;
    Hour = Hour + 1;
  }
  if(Hour > 22){
    Hour = 0;
  }
}



(2)Time_display函数
    用于显示时间。数码管显示功能直接用  nix_display_time2(Hour,Minutes,Second); 加以完成。

源码:
void Time_display(){
  delay(1000);
  Second = Second + 1;
  Carry_Time();
  nix_display_time2(Hour,Minutes,Second);//数码管显示时间
}

(3)SET_time函数
    设置时间。在设置时间时,数码管跳动,以提示在设置时间。

源码:
void SET_time(){
  uint8 key = 0;
  Time[(int)(0)] = Hour;
  Time[(int)(1)] = Minutes;
  Time[(int)(2)] = Second;
  while (!(key == 3)) {
    if(!P3_2){
      Time[(int)(key)] = Time[(int)(key)] + 1;
      if(Time[(int)(2)] > 58){
        Time[(int)(2)] = 0;
        Time[(int)(1)] = Time[(int)(1)] + 1;
      }
      if(Time[(int)(1)] > 58){
        Time[(int)(1)] = 0;
        Time[(int)(0)] = Time[(int)(0)] + 1;
      }
      if(Time[(int)(0)] > 22){
        Time[(int)(0)] = 0;
      }
    }
    if(!P3_3){
      key = key + 1;
    }
    nix_display_time2(Time[(int)(0)],Time[(int)(1)],Time[(int)(2)]);//数码管显示时间
    delay(50);
    nix_display_clear();//数码管清屏
    delay(50);
  }
  Hour = Time[(int)(0)];
  Minutes = Time[(int)(1)];
  Second = Time[(int)(2)];
}


(4)SET_Alarm函数
    设置闹钟时间。

源码:
void SET_Alarm(){
  uint8 key = 0;
  uint8 key_2 = 0;
  Time[(int)(0)] = 12;
  Time[(int)(1)] = 0;
  Time[(int)(2)] = 0;
  while (!(key == 3)) {
    if(!P3_2){
      Time[(int)(key)] = Time[(int)(key)] + 1;
      if(Time[(int)(2)] > 58){
        Time[(int)(2)] = 0;
        Time[(int)(1)] = Time[(int)(1)] + 1;
      }
      if(Time[(int)(1)] > 58){
        Time[(int)(1)] = 0;
        Time[(int)(0)] = Time[(int)(0)] + 1;
      }
      if(Time[(int)(0)] > 22){
        Time[(int)(0)] = 0;
      }
    }
    if(!P3_3){
      key = key + 1;
    }
    nix_display_time2(Time[(int)(0)],Time[(int)(1)],Time[(int)(2)]);//数码管显示时间
    delay(50);
    nix_display_clear();//数码管清屏
    delay(50);
    key_2 = key_2 + 1;
    if(key_2 > 9){
      Second = Second + 1;
      key_2 = 0;
      Carry_Time();
    }
  }
  P_Hour = Time[(int)(0)];
  P_Minutes = Time[(int)(1)];
  P_Second = Time[(int)(2)];
}


(5)Judge_Alarm函数
    判断是否到达闹钟时间。

源码:
uint8 Judge_Alarm(){
  if (((Hour == P_Hour) && (Minutes == P_Minutes)) && (Second == P_Second)){
    return 1;}
  return 0;
}


void T_IRQ0(void) interrupt 1 using 1{
  nix_scan_callback();//数码管扫描回调函数
}




回复

使用道具 举报

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
 楼主| 发表于 2021-7-20 11:37:24 | 显示全部楼层
loop()函数

这个函数作为类似启动器,用以判断进入何模式、使用何功能。

void loop()
{
  if(!P3_4){
    SET_time();
  }
  else if(!P3_5){
    SET_Alarm();
  }
  else{
    if(Judge_Alarm() == 1){
      for (m = 0; m < 5; m = m + 1) {
        pwm_duty(PWM5_P00, 200);//pwm调整三个参数分别是引脚、频率、占空比10/PWM_DUTY_MAX
        Time_display();
        pwm_duty(PWM5_P00, 0);//pwm调整三个参数分别是引脚、频率、占空比10/PWM_DUTY_MAX
        Time_display();
      }
    }
    Time_display();
  }
}

回复

使用道具 举报

6

主题

40

帖子

112

积分

注册会员

Rank: 2

积分
112
 楼主| 发表于 2021-7-20 11:43:53 | 显示全部楼层
总结

这次设计在编程时遇到挺多困难,在设计时也有很多细节需要考虑。比如说在设置闹钟时,时间应该在继续走,闹钟响时,时间也应该在继续走,这些问题都需要进行协调。在设计之初,本来打算使用按键矩阵来完成,后来发现仅凭key1到key4四个按键就可以完成所有功能,使用按键矩阵只能加大设计的难度。总而言之,收获很多。
回复

使用道具 举报

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

本版积分规则

QQ|Archiver|手机版|小黑屋|好好搭搭在线 ( © 好好搭搭在线 浙ICP备19030393号-1 )

GMT+8, 2021-9-26 23:54 , Processed in 0.290188 second(s), 25 queries .

Powered by Discuz!

© 2001-2021 Comsenz Inc.

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