利用51单片机完成一种智能助眠机系统的设计

发布者:晴天7777最新更新时间:2023-08-28 来源: elecfans关键字:51单片机  功能简介  ADC模块  按键模块 手机看文章 扫描二维码
随时随地手机看文章

一、功能简介

本项目使用Proteus8.12仿真51单片机控制器,使用蜂鸣器闹铃模块、LCD1602显示模块、心率血氧模块、PCF8691 ADC模块、按键模块等。


主要功能:

系统运行后,LCD1602显示传感器采集的心率和血氧值以及当前时间;可通过K3键进入时间修改模式,K3用于切换时、分、秒,K1和K2键调节;时间修改完成后可按下K4键保存并返回主界面。


可通过K4键进入助眠和起床闹铃设置模式,K4用于切换助眠时/分,起床时/分,K1和K2键调节。闹铃设置好后可按下K3键保存并返回主界面。若当前时间到达助眠时间或起床闹钟时间,则开启蜂鸣器闹铃,可通过K2键取消正在闹铃。正常界面下,可通过K1键查阅监测心率和血氧的数据信息,LCD1602显示心率及血氧的最小和最大值。


主要功能如下:

(1)心率/血氧监测;

(2)助眠/起床闹钟设置;

(3)闹铃提醒;

(4)LCD1602液晶显示。


二、软件设计

//系统数据显示

void sys_data_show(void)

{

  while(1)

  {

    //未查阅

    if(sys_ctrl.find==0)

    {

      //未进入设置闹钟模式

      if(sys_ctrl.set_alarm_mode==0)

      {

        //显示时间

        lcd1602_show_nums(6,0,sys_ctrl.hour,2,0x80);

        lcd1602_show_nums(9,0,sys_ctrl.min,2,0x80);

        lcd1602_show_nums(12,0,sys_ctrl.sec,2,0x80);


        //心率显示

        lcd1602_show_nums(3,1,sys_ctrl.heart,3,0);

        //血氧显示

        lcd1602_show_nums(12,1,sys_ctrl.oxygen,3,0);


        //时间调节位置闪烁

        switch(sys_ctrl.set_time_mode)

        {

          case 1://时

            lcd1602_show_string(6,0,"  ");

            delay_ms(50);

            lcd1602_show_nums(6,0,sys_ctrl.hour,2,0x80);

            break;

          case 2://分

            lcd1602_show_string(9,0,"  ");

            delay_ms(50);

            lcd1602_show_nums(9,0,sys_ctrl.min,2,0x80);

            break;

          case 3://秒

            lcd1602_show_string(12,0,"  ");

            delay_ms(50);

            lcd1602_show_nums(12,0,sys_ctrl.sec,2,0x80);

            break;

        }  

      }

      //进入闹钟设置模式

      else

      {

        //显示助眠时间

        lcd1602_show_nums(7,0,sys_ctrl.alarm_time[0][0],2,0x80);

        lcd1602_show_nums(10,0,sys_ctrl.alarm_time[0][1],2,0x80);

        //显示起床时间

        lcd1602_show_nums(7,1,sys_ctrl.alarm_time[1][0],2,0x80);

        lcd1602_show_nums(10,1,sys_ctrl.alarm_time[1][1],2,0x80);


        //时间调节位置闪烁

        switch(sys_ctrl.set_alarm_mode)  

        {

          case 1://助眠时

            lcd1602_show_string(7,0,"  ");

            delay_ms(50);

            lcd1602_show_nums(7,0,sys_ctrl.alarm_time[0][0],2,0x80);

            break;

          case 2://助眠分

            lcd1602_show_string(10,0,"  ");

            delay_ms(50);

            lcd1602_show_nums(10,0,sys_ctrl.alarm_time[0][1],2,0x80);

            break;

          case 3://起床时

            lcd1602_show_string(7,1,"  ");

            delay_ms(50);

            lcd1602_show_nums(7,1,sys_ctrl.alarm_time[1][0],2,0x80);

            break;

          case 4://起床分

            lcd1602_show_string(10,1,"  ");

            delay_ms(50);

            lcd1602_show_nums(10,1,sys_ctrl.alarm_time[1][1],2,0x80);

            break;

        }  

      }  

    }

    //正在查阅

    else

    {

      //显示心率最小和最大值

      lcd1602_show_nums(8,0,sys_ctrl.heart_lh[0],3,0x80);

      lcd1602_show_nums(12,0,sys_ctrl.heart_lh[1],3,0x80);

      //显示血氧最小和最大值

      lcd1602_show_nums(8,1,sys_ctrl.oxygen_lh[0],3,0x80);

      lcd1602_show_nums(12,1,sys_ctrl.oxygen_lh[1],3,0x80);  

    }


    break;      

  }

}



//系统数据设置

void sys_data_set(void)

{

  u8 key=0;

  static u8 oneflag=0;



  key=key_scan(0);

  //设置时间

  if(key==KEY3_PRESS)

  {

    //未进入设置闹钟模式

    if(sys_ctrl.set_alarm_mode==0)

    {

      TR1=0;//关闭定时器

      sys_ctrl.set_time_mode++;

      if(sys_ctrl.set_time_mode >=4)sys_ctrl.set_time_mode=1;  

    }

    //闹钟设置模式,确定

    else

    {

      oneflag=0;

      sys_ctrl.set_alarm_mode=0;

      sys_open_show();//开机界面显示

      TR1=1;//开启定时器  

    }    

  }

  //加

  else if(key==KEY1_PRESS)

  {

    //时间设置模式

    switch(sys_ctrl.set_time_mode)

    {

      case 1://时

        sys_ctrl.hour++;

        if(sys_ctrl.hour >23)sys_ctrl.hour=0;

        break;

      case 2://分

        sys_ctrl.min++;

        if(sys_ctrl.min >59)sys_ctrl.min=0;

        break;

      case 3://秒

        sys_ctrl.sec++;

        if(sys_ctrl.sec >59)sys_ctrl.sec=0;

        break;

    }  

    //闹钟设置模式

    switch(sys_ctrl.set_alarm_mode)

    {

      case 1://助眠时

        sys_ctrl.alarm_time[0][0]++;

        if(sys_ctrl.alarm_time[0][0] >23)sys_ctrl.alarm_time[0][0]=0;

        break;

      case 2://助眠分

        sys_ctrl.alarm_time[0][1]++;

        if(sys_ctrl.alarm_time[0][1] >59)sys_ctrl.alarm_time[0][1]=0;

        break;

      case 3://起床时

        sys_ctrl.alarm_time[1][0]++;

        if(sys_ctrl.alarm_time[1][0] >23)sys_ctrl.alarm_time[1][0]=0;

        break;

      case 4://起床分

        sys_ctrl.alarm_time[1][1]++;

        if(sys_ctrl.alarm_time[1][1] >59)sys_ctrl.alarm_time[1][1]=0;

        break;    

    }

    //正常模式下,查阅血氧心率信息

    if(sys_ctrl.set_time_mode==0 && sys_ctrl.set_alarm_mode==0)

    {

      sys_ctrl.find=!sys_ctrl.find;

      //查阅

      if(sys_ctrl.find==1)

      {

        lcd1602_clear();

        lcd1602_show_string(0,0," Heart- >000-000");

        lcd1602_show_string(0,1,"Oxygen- >000-000");    

      }

      //退出查阅

      else

      {

        sys_open_show();//开机界面显示  

      }  

    }  

  }

  //减

  else if(key==KEY2_PRESS)

  {

    //时间设置模式

    switch(sys_ctrl.set_time_mode)

    {

      case 1://时

        sys_ctrl.hour--;

        if(sys_ctrl.hour< 0)sys_ctrl.hour=23;

        break;

      case 2://分

        sys_ctrl.min--;

        if(sys_ctrl.min< 0)sys_ctrl.min=59;

        break;

      case 3://秒

        sys_ctrl.sec--;

        if(sys_ctrl.sec< 0)sys_ctrl.sec=59;

        break;

    }

    //闹钟设置模式

    switch(sys_ctrl.set_alarm_mode)

    {

      case 1://助眠时

        sys_ctrl.alarm_time[0][0]--;

        if(sys_ctrl.alarm_time[0][0]< 0)sys_ctrl.alarm_time[0][0]=23;

        break;

      case 2://助眠分

        sys_ctrl.alarm_time[0][1]--;

        if(sys_ctrl.alarm_time[0][1]< 0)sys_ctrl.alarm_time[0][1]=59;

        break;

      case 3://起床时

        sys_ctrl.alarm_time[1][0]--;

        if(sys_ctrl.alarm_time[1][0]< 0)sys_ctrl.alarm_time[1][0]=23;

        break;

      case 4://起床分

        sys_ctrl.alarm_time[1][1]--;

        if(sys_ctrl.alarm_time[1][1]< 0)sys_ctrl.alarm_time[1][1]=59;

        break;    

    }

    sys_ctrl.alarm_flag=0;//解除闹铃      

  }

  //确定

  else if(key==KEY4_PRESS)

  {

    //时间设置模式

    if(sys_ctrl.set_time_mode!=0)

    {

      sys_ctrl.set_time_mode=0;

      TR1=1;//开启定时器  

    }

    //闹钟设置模式

    else

    {

      TR1=0;//关闭定时器

      if(oneflag==0)//只显示1次界面

      {

        oneflag=1;

[1] [2]
关键字:51单片机  功能简介  ADC模块  按键模块 引用地址:利用51单片机完成一种智能助眠机系统的设计

上一篇:如何利用51单片机实现一种超声波测距功能呢
下一篇:零基础:学51单片机定时器

推荐阅读最新更新时间:2024-11-13 08:14

51单片机驱动 LCD1602液晶显示系统
废话不多说先上实物图 LCD1602+51单片机最小系统应用仿真及制作 好了,接下来正式进入制作环节: 第一步:仿真 绘制好原理图,仿真时单片机最小系统只放一个单片机就可以了,但实际电路中需要加上电源模块、复位模块。如下图: 原理图文件请在附件中找。 原理图绘制好后,编写代码并生成hex文件。参考代码如下: /*功能/ /使用外部中断INTO改变LED状态,并且用1602显示出其状态/ #include reg51.h #include intrins.h #define uint unsigned int #define uchar unsigned char uchar code table = H
[单片机]
<font color='red'>51单片机</font>驱动 <font color='red'>LCD1602</font>液晶<font color='red'>显示</font><font color='red'>系统</font>
51单片机入门——矩阵建盘的基本操作
矩阵键盘的原理图和基本原理 原理图 基本原理 首先我们要进行扫描,扫描矩阵键盘中每个按键的状态,对与矩阵键盘,我们只能逐行扫描,然后读取列的状态信号。如果R3行输出低电平,那么黄色按键如果有按下动作的话,那读取C2列信号也应该为低电平,而该行上其他没有按下动作的按键的列信号则为高电平。 每个按键内部的结构 独立按键 - 矩阵键盘 检测 每次输入检测是都只保证一个为低电平,其余为高电平,只要某一行输入0,在某一列也输出0,则检测成功(成功按下) 例题 代码如下 #include reg52.h sfr P4 = 0xC0; sbit HC138_A = P2^5; sbit HC1
[单片机]
<font color='red'>51单片机</font>入门——矩阵建盘的基本操作
51单片机做信号发生器实例编程
//用51单片机做信号发生器,同时输出四种频率的方波。 //要求:晶振为12MHz,用T0做定时器,在P1的低四位输出四种频率的方波: // P1.3 = 1.25kHz、P1.2 = 2.5kHz、P1.1 = 5kHz、P1.0 = 10kHz //另外,上述四个频率要求用一个四选一数据选择器,再选出其中的一个输出出去。 //P1.6、P1.7的输出用来控制四选一数据选择器的选择位,它们由P3.0按键控制。 //悬赏分:10 - 解决时间:2009-12-5 10:45 //=================================================== //最佳答案: //本题目早在一年前就回答完毕
[单片机]
<font color='red'>51单片机</font>做信号发生器实例编程
51单片机与A/D接口设计
A/D 转换器用于实现模拟量→数字量的转换,按转换原理可分为4种,即:计数式A/D转换器、双积分式A/D转换器、逐次逼近式A/D转换器和并行式A/D转换器。 目前最常用的是双积分式A/D转换器和逐次逼近式A/D转换器。双积分式A/D转换器的主要优点是转换精度高,抗干扰性能好,价格便宜。其缺点是转换速度较慢,因此,这种转换器主要用于速度要求不高的场合。 另一种常用的A/D转换器是逐次逼近式的,逐次逼近式A/D转换器是一种速度较快,精度较高的转换器,其转换时间大约在几μs到几百μs之间。通常使用的逐次逼近式典型A/D转换器芯片有: (1)ADC0801~ADC0805型8位MOS型A/D转换器(美国国家半导体公司产
[单片机]
<font color='red'>51单片机</font>与A/D接口设计
51单片机之工作周期与时序
介绍一下XTAL1、XTAL2引脚: XTAL1、XTAL2引脚是用于无缘晶振和无缘晶振,从而来产生时钟信号的引脚 1、当接入无缘晶振后 1、当接入有缘晶振后 例如:在XTAL1、XTAL2引脚外接晶振为12MHz,则 振荡周期:1/12us 状态周期:1/6us 机器周期:1us
[单片机]
<font color='red'>51单片机</font>之工作周期与时序
51单片机基础之流水灯(二)
代码: #include reg52.h #include intrins.h //这个头文件里包含所需左移右移函数 #define LED P2 //宏定义端口P2 void delay(unsigned int u16) //不再赘述 { while(u16--); } void main(void) { unsigned int i; LED=0x7f; delay(50000); while(1) { for(i=0;i 7;i++) { LED=_cror_(L
[单片机]
<font color='red'>51单片机</font>基础之流水灯(二)
51单片机设计方案TOP10(六)
传统的伏特表在我们的日常生活及科学研究中起到了其独特的作用,但是在科学技术日新月异、集成芯片在日常生活中的应用越来越广泛的今天显得比较落伍:①它们的量程往往在出厂以前就限定好的,不能根据具体使用场合进行相应调整;②测量精度有限;③不能够将测量结果用语音播放出来。本文将介绍一种由单片机最小系统、模-数转换电路 、语音电路、LED显示电路组成的单片机式语音播报伏特表。    1、硬件设计   整个系统的组成可以分成四大部分:单片机、模-数转换电路、语音电路、LED显示电路。下面就主要的部分进行具体介绍。   1.1、单片机   目前流行的单片机很多,其中89C51自带有片内ROM和一定数量的RAM,一般不需要扩展片外的存储器,并且
[模拟电子]
<font color='red'>51单片机</font>设计方案TOP10(六)
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved