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

发布时间:2023-08-28  

一、功能简介

本项目使用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;

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>