【Proteus仿真】【Arduino单片机】多功能数字时钟设计

news2024/11/20 9:21:30

文章目录

  • 一、功能简介
  • 二、软件设计
  • 三、实验现象
  • 联系作者


一、功能简介

本项目使用Proteus8仿真Arduino单片机控制器,使用PCF8574、LCD1602液晶、DS1302温度传感器、DS1302时钟、按键、蜂鸣器等。
主要功能:
系统运行后,LCD1602显示当前日期时间和温度值,当按下K3键进入日期和时间设置模式,
每按下K3键1次,则切换不同位置,通过K1和K2键调整数据;按下K4键可保存并返回主界面。
当按下K4键,进入闹钟设置模式,可通过K4键切换不同位置,通过K1和K2键调整数据;按下
K3键可保存并返回主界面。当时间到达闹钟时间,开启闹铃,可按下K1键取消闹铃。


二、软件设计

/*
作者:嗨小易(QQ:3443792007)

*/


//系统数据获取
void sys_data_get(void)
{
  while(1)
  {
    //获取温度
    sys_ctrl.temp=ds18b20_read_temperture()*10;
    //获取时间
    ds1302_read_time();

    break;
  }
}

//系统数据显示
void sys_data_show(void)
{
  u8 buf[5];
  while(1)
  {
    //正常模式显示
    if(sys_ctrl.mode==0)
    {
      //未进入闹钟设置模式
      if(sys_ctrl.alarm_mode==0)
      {
        //日期时间显示
        lcd1602_show_nums(2,0,gDS1302_TIME[6],2,0x80);//年
        lcd1602_show_nums(5,0,gDS1302_TIME[4],2,0x80);//月
        lcd1602_show_nums(8,0,gDS1302_TIME[3],2,0x80);//日
        lcd1602_show_nums(15,0,gDS1302_TIME[5],1,0x80);//星期
        lcd1602_show_nums(0,1,gDS1302_TIME[2],2,0x80);//时
        lcd1602_show_nums(3,1,gDS1302_TIME[1],2,0x80);//分
        lcd1602_show_nums(6,1,gDS1302_TIME[0],2,0x80);//秒
        //温度显示
        if(sys_ctrl.temp<9999)
        {
          buf[0]=sys_ctrl.temp/100+0x30;
          buf[1]=sys_ctrl.temp%100/10+0x30;
          buf[2]='.';
          buf[3]=sys_ctrl.temp%100%10+0x30;
          buf[4]='\0';
          lcd1602_show_string(11,1,buf);
        }
      }
      //闹钟设置显示
      else
      {
        //闹钟时间显示
        lcd1602_show_nums(6,0,sys_ctrl.alarm_time[0],2,0x80);//时
        lcd1602_show_nums(9,0,sys_ctrl.alarm_time[1],2,0x80);//分
        //闹钟开关状态显示
        if(sys_ctrl.alarm_onoff==0)lcd1602_show_string(4,1,"OFF");
        else lcd1602_show_string(4,1," ON");

        //对应位置闪烁
        switch(sys_ctrl.alarm_mode)
        {
          case 1:
            lcd1602_show_string(6,0,"  ");
            delay(50);
            lcd1602_show_nums(6,0,sys_ctrl.alarm_time[0],2,0x80);//时
            break;
          case 2:
            lcd1602_show_string(9,0,"  ");
            delay(50);
            lcd1602_show_nums(9,0,sys_ctrl.alarm_time[1],2,0x80);//分
            break;
          case 3:
            lcd1602_show_string(4,1,"   ");
            delay(50);
            //闹钟开关状态显示
            if(sys_ctrl.alarm_onoff==0)lcd1602_show_string(4,1,"OFF");
            else lcd1602_show_string(4,1," ON");
            break;
        }
      }
    }
    //设置模式显示
    else 
    {
      //设置时间显示
      lcd1602_show_nums(2,0,sys_ctrl.set_time[6],2,0x80);//年
      lcd1602_show_nums(5,0,sys_ctrl.set_time[4],2,0x80);//月
      lcd1602_show_nums(8,0,sys_ctrl.set_time[3],2,0x80);//日
      lcd1602_show_nums(15,0,sys_ctrl.set_time[5],1,0x80);//星期
      lcd1602_show_nums(0,1,sys_ctrl.set_time[2],2,0x80);//时
      lcd1602_show_nums(3,1,sys_ctrl.set_time[1],2,0x80);//分
      lcd1602_show_nums(6,1,sys_ctrl.set_time[0],2,0x80);//秒

      //对应位置闪烁
      switch(sys_ctrl.mode)
      {
        case 1:
          lcd1602_show_string(2,0,"  ");
          delay(50);
          lcd1602_show_nums(2,0,sys_ctrl.set_time[6],2,0x80);//年
          break;
        case 2:
          lcd1602_show_string(5,0,"  ");
          delay(50);
          lcd1602_show_nums(5,0,sys_ctrl.set_time[4],2,0x80);//月
          break;
        case 3:
          lcd1602_show_string(8,0,"  ");
          delay(50);
          lcd1602_show_nums(8,0,sys_ctrl.set_time[3],2,0x80);//日
          break;
        case 4:
          lcd1602_show_string(15,0,"  ");
          delay(50);
          lcd1602_show_nums(15,0,sys_ctrl.set_time[5],1,0x80);//星期
          break;
        case 5:
          lcd1602_show_string(0,1,"  ");
          delay(50);
          lcd1602_show_nums(0,1,sys_ctrl.set_time[2],2,0x80);//时
          break;
        case 6:
          lcd1602_show_string(3,1,"  ");
          delay(50);
          lcd1602_show_nums(3,1,sys_ctrl.set_time[1],2,0x80);//分
          break;
        case 7:
          lcd1602_show_string(6,1,"  ");
          delay(50);
          lcd1602_show_nums(6,1,sys_ctrl.set_time[0],2,0x80);//秒
          break;
      }
    }

    break;
  }
}

//系统数据设置
void sys_data_set(void)
{
  u8 key=0;
  static u8 oneflag=0;
  static u8 nzoneflag=0;
  u8 i=0;

  key=key_scan(0);
  if(key!=0)beep_alarm(100,1000);//提示音
  //设置
  if(key==KEY3_PRESS)
  {
    //未进入闹钟设置
    if(sys_ctrl.alarm_mode==0)
    {
      sys_ctrl.mode++;
      if(sys_ctrl.mode>7)sys_ctrl.mode=1;
      if(oneflag==0)
      {
        oneflag=1;
        //获取当前时间记录
        for(i=0;i<7;i++)sys_ctrl.set_time[i]=gDS1302_TIME[i];
        _sys_parm_set_show();//系统参数设置界面显示      
      }
    } 
    //进入闹钟设置
    else
    {
      sys_ctrl.alarm_mode=0;
      nzoneflag=0;
      sys_open_show();//系统开机界面显示
    }
  }
  //加
  else if(key==KEY1_PRESS)
  {
    //时间修改
    if(sys_ctrl.mode!=0)
    {
      switch(sys_ctrl.mode)
      {
        case 1://年
          sys_ctrl.set_time[6]++;
          if(sys_ctrl.set_time[6]>99)sys_ctrl.set_time[6]=0;
          break;
        case 2://月
          sys_ctrl.set_time[4]++;
          if(sys_ctrl.set_time[4]>12)sys_ctrl.set_time[4]=1;
          break;
        case 3://日
          sys_ctrl.set_time[3]++;
          if(sys_ctrl.set_time[3]>31)sys_ctrl.set_time[3]=1;
          break;
        case 4://星期
          sys_ctrl.set_time[5]++;
          if(sys_ctrl.set_time[5]>7)sys_ctrl.set_time[5]=1;
          break;
        case 5://时
          sys_ctrl.set_time[2]++;
          if(sys_ctrl.set_time[2]>23)sys_ctrl.set_time[2]=0;
          break;
        case 6://分
          sys_ctrl.set_time[1]++;
          if(sys_ctrl.set_time[1]>59)sys_ctrl.set_time[1]=0;
          break;
        case 7://秒
          sys_ctrl.set_time[0]++;
          if(sys_ctrl.set_time[0]>59)sys_ctrl.set_time[0]=0;
          break;
      }
    }
    //闹钟设置
    if(sys_ctrl.alarm_mode!=0)
    {
      switch(sys_ctrl.alarm_mode)
      {
        case 1:
          sys_ctrl.alarm_time[0]++;
          if(sys_ctrl.alarm_time[0]>23)sys_ctrl.alarm_time[0]=0;
          break;
        case 2:
          sys_ctrl.alarm_time[1]++;
          if(sys_ctrl.alarm_time[1]>59)sys_ctrl.alarm_time[1]=0;
          break;
        case 3:
          sys_ctrl.alarm_onoff=!sys_ctrl.alarm_onoff;
          break;
      }
    }

    //已闹铃,取消
    if(sys_ctrl.naoling==1)sys_ctrl.naoling=0;
  }
  //减
  else if(key==KEY2_PRESS)
  {
    //时间修改
    if(sys_ctrl.mode!=0)
    {
      switch(sys_ctrl.mode)
      {
        case 1://年
          sys_ctrl.set_time[6]--;
          if(sys_ctrl.set_time[6]<0)sys_ctrl.set_time[6]=99;
          break;
        case 2://月
          sys_ctrl.set_time[4]--;
          if(sys_ctrl.set_time[4]<0)sys_ctrl.set_time[4]=12;
          break;
        case 3://日
          sys_ctrl.set_time[3]--;
          if(sys_ctrl.set_time[3]<0)sys_ctrl.set_time[3]=31;
          break;
        case 4://星期
          sys_ctrl.set_time[5]--;
          if(sys_ctrl.set_time[5]<0)sys_ctrl.set_time[5]=7;
          break;
        case 5://时
          sys_ctrl.set_time[2]--;
          if(sys_ctrl.set_time[2]<0)sys_ctrl.set_time[2]=23;
          break;
        case 6://分
          sys_ctrl.set_time[1]--;
          if(sys_ctrl.set_time[1]<0)sys_ctrl.set_time[1]=59;
          break;
        case 7://秒
          sys_ctrl.set_time[0]--;
          if(sys_ctrl.set_time[0]<0)sys_ctrl.set_time[0]=59;
          break;
      }
    }
    //闹钟设置
    if(sys_ctrl.alarm_mode!=0)
    {
      switch(sys_ctrl.alarm_mode)
      {
        case 1:
          sys_ctrl.alarm_time[0]--;
          if(sys_ctrl.alarm_time[0]<0)sys_ctrl.alarm_time[0]=23;
          break;
        case 2:
          sys_ctrl.alarm_time[1]--;
          if(sys_ctrl.alarm_time[1]<0)sys_ctrl.alarm_time[1]=59;
          break;
        case 3:
          sys_ctrl.alarm_onoff=!sys_ctrl.alarm_onoff;
          break;
      }
    }
  }
  //确定
  else if(key==KEY4_PRESS)
  {
    //时间修改
    if(sys_ctrl.mode!=0)
    {
      sys_ctrl.mode=0;
      oneflag=0;
      ds1302_set_time(sys_ctrl.set_time[6],sys_ctrl.set_time[4],sys_ctrl.set_time[3],sys_ctrl.set_time[2],sys_ctrl.set_time[1],sys_ctrl.set_time[0]);
      sys_open_show();//系统开机界面显示
    }
    //闹钟设置
    else
    {
      sys_ctrl.alarm_mode++;
      if(sys_ctrl.alarm_mode>3)sys_ctrl.alarm_mode=1;
      if(nzoneflag==0)
      {
        nzoneflag=1;
        _sys_alarm_set_show();//闹钟设置界面显示
      }
    }
  }
}




三、实验现象

B站演示视频:https://space.bilibili.com/444388619

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

联系作者

视频地址:https://space.bilibili.com/444388619/video
专注于51单片机、STM32、国产32、DSP、Proteus、arduino、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1232947.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

放大招:腾讯云5年服务器和3年轻量应用服务器租用价格表

腾讯云3年轻量和5年云服务器CVM优惠活动入口&#xff0c;3年轻量应用服务器配置可选2核2G4M和2核4G5M带宽&#xff0c;5年CVM云服务器可以选择2核4G和4核8G配置可选&#xff0c;阿腾云atengyun.com分享腾讯云3年轻量应用服务器和5年云服务器CVM优惠活动入口和配置报价&#xff…

【C++上层应用】5. 文件和流

文章目录 【 1. 打开文件 】1.1 open 函数1.2 open 多种模式的结合使用 【 2. 关闭文件 】【 3. 写入 & 读取文件 】【 4. 文件位置指针 】 和 iostream 库中的 cin 标准输入流和 cout 标准输出流类似&#xff0c;C中另一个库 fstream 也存在文件的读取流和标准写入流。fst…

erlang语言为什么天生支持高并发

Erlang 语言天生支持高并发的主要原因可以归结于它的设计哲学和一些核心特性。以下是 Erlang 支持高并发的几个关键方面&#xff1a; 轻量级进程&#xff1a;Erlang 使用轻量级的并发实体&#xff0c;通常称为“进程”&#xff0c;这些进程在Erlang虚拟机内部运行&#xff0c;而…

为什么几乎所有的量化交易都用Python?

因为python好用啊&#xff01;Python&#xff0c;作为一种功能强大且易于学习的编程语言&#xff0c;已经成为金融分析师的首选工具。 以下我将从3个方面给大家分析python为何成为量化交易的理想选择。 一、语言特性与金融分析的匹配性 1、简单易懂的语言 Python就像我们的日…

存储区域网络(SAN)之FC-SAN和IP-SAN的比较

存储区域网络(Storage Area Network&#xff0c;SAN)用于将多个系统连接到存储设备和子系统。 早期FC-SAN&#xff1a; 采用光纤通道(Fibre Channel&#xff0c;FC)技术&#xff0c;通过光纤通道交换机连接存储阵列和服务器主机&#xff0c;建立专用于数据存储的区域网络。 传…

Ubuntu apt-get换源

一、参考资料 ubuntu16.04更换镜像源为阿里云镜像源 二、相关介绍 1. apt常用命令 sudo apt-get clean sudo apt-get update2. APT加速工具 轻量小巧的零配置 APT 加速工具&#xff1a;APT Proxy GitHub项目地址&#xff1a;apt-proxy 三、换源关键步骤 1. 更新阿里源 …

【开源】基于JAVA的学生日常行为评分管理系统

项目编号&#xff1a; S 010 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S010&#xff0c;文末获取源码。} 项目编号&#xff1a;S010&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、系统设计2.1 功能模块设计2.2.1 登录注册模块2.2…

美国费米实验室SQMS启动“量子车库”计划!30+顶尖机构积极参与

​11月6日&#xff0c;美国能源部费米国家加速器实验室(SQMS)正式启动了名为“量子车库”的全新旗舰量子研究设施。这个6,000平方英尺的实验室是由超导量子材料与系统中心负责设计和建造&#xff0c;旨在联合国内外的科学界、工业领域和初创企业&#xff0c;共同推动量子信息科…

Java零基础-Mybatis篇

【Mybatis】 1.JDBC不足 JDBC作为Java操作数据库的模板&#xff0c;如果想要对数据库进行操作&#xff0c;必须使用JDBC&#xff0c;但是在使用JDBC进行数据库操作时&#xff0c;重复代码多&#xff0c;动态SQL构建繁琐&#xff0c;将查询结果转化为对象&#xff0c;相当麻烦…

基于SSM的网盘管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

企业办公文件数据防泄密系统 | 文件、文档、设计图纸、源代码、音视频等核心数据资料防止外泄!

天锐绿盾防泄密软件采用智能透明加密技术&#xff0c;对文件、文档、图纸、源代码、音视频等数据进行加密保护&#xff0c;防止数据泄露。这种加密技术是内核级透明加密技术&#xff0c;可以在不影响员工正常工作的情况下&#xff0c;对需要保护的数据进行加密操作。 PC端访问地…

DCDC同步降压控制器SCT82A30\SCT82630

SCT82A30是一款100V电压模式控制同步降压控制器&#xff0c;具有线路前馈。40ns受控高压侧MOSFET的最小导通时间支持高转换比&#xff0c;实现从48V输入到低压轨的直接降压转换&#xff0c;降低了系统复杂性和解决方案成本。如果需要&#xff0c;在低至6V的输入电压下降期间&am…

一种可度量的测试体系-精准测试

行业现状 软件行业长期存在一个痛点&#xff0c;即测试效果无法度量。通常依赖于测试人员的能力和经验&#xff0c;测试结果往往不可控&#xff0c;极端情况下同一个业务功能&#xff0c;即使是同一个人员在不同的时间段&#xff0c;测试场景和过程也可能不一致&#xff0c;从而…

十大最常用电子元器件基础知识

对于电子行业的工程师来说&#xff0c;电子元件&#xff0c;就像人们入口的大米&#xff0c;每天都需要接触和使用。但事实上&#xff0c;许多工程师可能都不完全理解里面的门道。以下是工程师常用的十种电子元件以及相关的基本概念和知识。让我们一起学习了解一下。 一&#…

护眼灯亮度多少合适?亮度适合学生的护眼台灯推荐

护眼灯亮度满足国AA级标准就好了。可以肯定的是&#xff0c;护眼灯一般可以达到护眼的效果。 看书和写字时&#xff0c;光线应适度&#xff0c;不宜过强或过暗&#xff0c;护眼灯光线较柔和&#xff0c;通常并不刺眼&#xff0c;眼球容易适应&#xff0c;可以防止光线过强或过…

【HarmonyOS】低代码平台组件拖拽使用技巧之页签容器

【关键字】 HarmonyOS、低代码平台、Tabs、TabContent、页签导航 1、写在前面 前面几篇分别介绍了低代码平台中的堆叠容器、滚动容器、网格布局等三种容器的使用&#xff0c;实际开发中我们经常会有这样的需求&#xff0c;页面底部是三个Tab按钮点击时会分别切换不同的视图内…

【点云上采样】基于移动最小二乘(MLS)的上采样

文章目录 声明简介代码参考 声明 示例结果比较奇怪&#xff0c;可能是参数没调好&#xff0c;如有问题&#xff0c;望指正&#xff01; 简介 基于MLS&#xff08;Moving Least Squares&#xff09;的上采样是一种常用的点云处理方法&#xff0c;用于增加稀疏点云数据的密度和…

「Qt Widget中文示例指南」如何创建一个计算器?(一)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文将展示如何使用…

Django 入门学习总结8-管理页面的生成

修改polls/admin.py文件为&#xff1a; from django.contrib import admin from .models import Choice, Question class ChoiceInline(admin.StackedInline): model Choice extra 3 class QuestionAdmin(admin.ModelAdmin): fieldsets [ (None, {&q…