基于51单片机的手环设计仿真

news2024/9/23 5:09:21

目录

一、主要功能

二、硬件资源

三、程序编程

四、实现现象


一、主要功能

基于STC89C52单片机,DHT11温湿度采集温湿度,滑动变阻器连接ADC0832数模转换器模拟水位传感器检测水位,通过LCD1602显示信息,然后在程序里设置好是否有水的判断阈值,比如100,当水位没超过100,则判断没水,此时蜂鸣器报警,当水位超过100时候,蜂鸣器不报警,此时四×四按键矩阵设置湿度的下限,然后判断湿度是否低于下限,若低于下限,则继电器驱动电机转动启动加湿器,蜂鸣器报警。

二、硬件资源

基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。

三、程序编程

#include <REGX52.H>
#include<intrins.h>
#include<stdio.h>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"
#define uchar unsigned char
#define uint unsigned  int

sbit led1 = P2^4;
sbit beep = P3^0;			  //蜂鸣器引脚
sbit DS   = P3^1;                 //DS18B20温度传感器
sbit CS=P2^5;                 //adc0832引脚
sbit CLK=P2^6;
sbit DIO=P2^7;
sbit CS1=P3^2;                 //adc0832引脚
sbit CLK1=P3^3;
sbit DIO1=P3^4;
sbit CS2=P3^5;                 //adc0832引脚
sbit CLK2=P3^6;
sbit DIO2=P3^7;


unsigned char KeyNum;
static uchar u,U,R,u1,U1,R1,u2,U2,R2;      //定义心率 血氧 加速度
static uint temp;
static float ftemp = 0.0f;//温度转变
uint temp;
static unsigned char num; //计时变量
unsigned int password,count; //初始化阈值,次数,一共四位
static int wdyz,xlyz,xyyz,jsyz;
static int mode=0;
static int number=0;
static int count1=0;
static int jsflag=0;//计数标志位
static int mode1 = 0;

void tmpchange();
uint tmp();
void beep_warning();
void cshq();
void cslsz();
void csxs();

void Time0_Init()          //定时器初始化
{
TMOD = 0x01;           //定时器0工作在方式1    
IE   = 0x82;
TH0  = 0xfe;
TL0  = 0x33;     //11.0592MZ晶振,0.5ms
TR0=1;                 //定时器开始
EA=1;
}



void Time0_Int() interrupt 1 //中断程序
{
   TH0  = 0xfe;             //重新赋值
   TL0  = 0x33;
    num++;
	if(num==200)
	{
	    tmpchange();        //让18b20开始转换温度
	    temp = tmp();       //读取温度
	    ftemp = temp/10.0f; //转换温度
		  num=0;
	}
	if(jsflag == 1)
	{
	count1++;
	if(count1==1000)
	{
		number++;
		LCD_ShowNum(1,14,number,3);
		count1=0;
	}
  }
	
	
	
}

uchar get_AD_Res()            //ADC0832启动读取函数 心率
{
	uchar i, data1=0, data2=0;
	CS=0;
	
	CLK=0;DIO=1;_nop_();
	CLK=1;_nop_();
	
	CLK=0;DIO=1;_nop_(); 
	CLK=1;_nop_();
	
	CLK=0;DIO=0;_nop_();
	CLK=1;_nop_();
	
	CLK=0;DIO=1;_nop_(); 
	
	for(i=0; i<8; i++)
	{
		CLK=1;_nop_();
		CLK=0;_nop_();
		data1=(data1<<1)|(uchar)DIO; 
	}
	
	for(i=0; i<8; i++)
	{
		data2=data2|(uchar)DIO<<i;
		CLK=1;_nop_();
		CLK=0;_nop_();
	}
	CS=1;
	
	return(data1 == data2)?data1:0;
}

uchar get_AD_Res1()            //ADC0832启动读取函数 血氧
{
	uchar i, data1=0, data2=0;
	CS1=0;
	
	CLK1=0;DIO1=1;_nop_();
	CLK1=1;_nop_();
	
	CLK1=0;DIO1=1;_nop_(); 
	CLK1=1;_nop_();
	
	CLK1=0;DIO1=0;_nop_();
	CLK1=1;_nop_();
	
	CLK1=0;DIO1=1;_nop_(); 
	
	for(i=0; i<8; i++)
	{
		CLK1=1;_nop_();
		CLK1=0;_nop_();
		data1=(data1<<1)|(uchar)DIO1; 
	}
	
	for(i=0; i<8; i++)
	{
		data2=data2|(uchar)DIO1<<i;
		CLK1=1;_nop_();
		CLK1=0;_nop_();
	}
	CS1=1;
	
	return(data1 == data2)?data1:0;
}

uchar get_AD_Res2()            //ADC0832启动读取函数 加速度
{
	uchar i, data1=0, data2=0;
	CS2=0;
	
	CLK2=0;DIO2=1;_nop_();
	CLK2=1;_nop_();
	
	CLK2=0;DIO2=1;_nop_(); 
	CLK2=1;_nop_();
	
	CLK2=0;DIO2=0;_nop_();
	CLK2=1;_nop_();
	
	CLK2=0;DIO2=1;_nop_(); 
	
	for(i=0; i<8; i++)
	{
		CLK2=1;_nop_();
		CLK2=0;_nop_();
		data1=(data1<<1)|(uchar)DIO2; 
	}
	
	for(i=0; i<8; i++)
	{
		data2=data2|(uchar)DIO2<<i;
		CLK2=1;_nop_();
		CLK2=0;_nop_();
	}
	CS2=1;
	
	return(data1 == data2)?data1:0;
}

void dsreset(void)            //发出命令
{
  uint i;
  DS=0;		              
  i=103;				   //将总线拉低480us~960us

  while(i>0)i--;
  DS=1;					   //然后拉高总线,若DS18B20做出反应会将在15us~60us后将总线拉低
  i=4;					   //15us~60us等待
  while(i>0)i--;
  //while(DS);
}
bit tmpreadbit(void)          //读取数据
{
   uint i;
   bit dat;
   DS=0;i++;          //i++ for delay
   DS=1;i++;i++;
   dat=DS;
   i=8;while(i>0)i--;
   return (dat);
}
uchar tmpread(void)           //读取数据
{
  uchar i,j,dat;
  dat=0;
  for(i=1;i<=8;i++)
  {
    j=tmpreadbit();
    dat=(j<<7)|(dat>>1);   //读出的数据最低位在最前面,这样刚好一个字节在DAT里
  }
  return(dat);
}
void tmpwritebyte(uchar dat)  //传输数据给DS18B20
{
  uint i;
  uchar j;
  bit testb;
  for(j=1;j<=8;j++)
  {
    testb=dat&0x01;
    dat=dat>>1;
    if(testb)     //write 1
    {
      DS=0;
      i++;i++;
      DS=1;
      i=8;while(i>0)i--;
    }
    else
    {
      DS=0;       //write 0
      i=8;while(i>0)i--;
      DS=1;
      i++;i++;
    }
  }
}
void tmpchange(void)          //DS18B20开始工作
{
  dsreset();
  Delay(1);
  tmpwritebyte(0xcc);  
  tmpwritebyte(0x44);  
}					  
uint tmp()                    //获得温度
{
  float tt;
  uchar a,b;
  dsreset();
  Delay(1);
  tmpwritebyte(0xcc);
  tmpwritebyte(0xbe);
  a=tmpread();//低八位
  b=tmpread();//高八位
  temp=b;
  temp<<=8;             //two byte  compose a int variable
  temp=temp|a;
  tt=temp*0.0625; //算出来的是测到的温度,数值可到小数点后两位
  temp=tt*10+0.5; //为了显示温度后的小数点后一位并作出四舍五入,因为取值运算不能取小数点后的数
  return temp;
}

void beep_warning() //温度传感器蜂鸣器警报并且电机转动
{
 if(ftemp>wdyz)
 {
	 beep = 1;
	 led1 = 1;
 }
 
 if(R>xlyz)
 {
	 beep = 1;
	 led1 =1;
 }
 
 if(R1>xyyz)
 {
	 beep = 1;
	 led1 = 1;
 }
 
 if(R2>jsyz)
 {
	 beep = 1;
	 led1 = 1;
 }
 
 if(ftemp<wdyz && R< xlyz && R1<xyyz && R2<jsyz)
 {
	 beep = 0;
	 led1 = 0;
 }
}


void main()					  //主函数
{	
  led1 = 0;
	beep = 0;			    //蜂鸣器关掉
	LCD_Init();         //显示屏初始化
	LCD_ShowString(1,1,"----shouhuan----");
	Delay(1000);
	LCD_Init();         //显示屏初始化
  Time0_Init();
	ET0=1;
	while(1)
	{
		  cshq(); //参数获取
      cslsz();//按键设置
		  if(mode == 5)
			{
			 beep_warning(); 
			}
		  if(mode1 == 0)
			{
				csxs();//参数显示
			}
	}
}

void csxs() //参数显示
{
	LCD_ShowString(1,1,"wd:");
	LCD_ShowNum(1,4,ftemp,3);
	LCD_ShowString(1,7,"xl:");
	LCD_ShowNum(1,10,R,3);
	LCD_ShowString(2,1,"xy:");
	LCD_ShowNum(2,4,R1,3);
	LCD_ShowString(2,8,"jsd:");
	LCD_ShowNum(2,12,R2,3);
}

void cshq() //参数获取
{
	 u=get_AD_Res();
		  U=(250*u)/128;     //此处将数字信号转化为模拟信号,要根据上拉电阻阻值来确定
		  R=200*U/250;     //获取心率
	
	 u1=get_AD_Res1();
		  U1=(250*u1)/128;     //此处将数字信号转化为模拟信号,要根据上拉电阻阻值来确定
		  R1=200*U1/250;     //获取血氧
	
	 u2=get_AD_Res2();
		  U2=(250*u2)/128;     //此处将数字信号转化为模拟信号,要根据上拉电阻阻值来确定
		  R2=200*U2/250;     //获取加速度
}

void cslsz()//按键判断
{
	KeyNum = MatrixKey();//键盘输入的值进行传递
	if(KeyNum){	
	if(KeyNum <= 10) //把按键的范围定义在0~9
	{			
	  if(count < 3)
		{
			password*=10; //出水量左移一位
			password += KeyNum % 10; //获取一位出水量
			count++;    //计次++,对应出水量位数
		}
			LCD_ShowNum(1,4,password,3); //LCD更新显示
	}	
	//确认键
	  if(KeyNum == 11) //把11表示确认,对阈值进行确认
		{
		 LCD_ShowNum(1,4,password,3); //LCD更新显示
			switch(mode)
			{
				case 1:wdyz = password;LCD_ShowNum(2,1,wdyz,3);break;
				case 2:xlyz = password;LCD_ShowNum(2,5,xlyz,3);break;
				case 3:xyyz = password;LCD_ShowNum(2,9,xyyz,3);break;
				case 4:jsyz = password;LCD_ShowNum(2,13,jsyz,3);break;
			}
		}		
		//取消键
		if(KeyNum == 12)
			{
				password = 0;
				count = 0;
				LCD_ShowNum(1,4,password,3); //LCD更新显示
			}
			
			if(KeyNum == 13)  //q切换
			{
				mode++;
				password = 0;
				count = 0;
				LCD_ShowNum(1,4,password,3); //LCD更新显示
				switch(mode)
			{
				case 1:LCD_ShowString(1,1,"wd:");break;
				case 2:LCD_ShowString(1,1,"xl:");break;
				case 3:LCD_ShowString(1,1,"xy:");break;
				case 4:LCD_ShowString(1,1,"js:");break;
			}
				password = 0;
				count = 0;
				if(mode>5)
				{
					mode = 0;
				}
			}
			
			if(KeyNum == 14)
			{
				jsflag++;
				if(jsflag>1)
				{
					jsflag = 0;
				}
			}
			if(KeyNum==15)
			{
				LCD_Init();         //显示屏初始化
				mode1++;
				if(mode1>1)
				{
					mode1=0;
				}
			}
		} 
	

  
}

四、实现现象

具体动态效果看B站演示视频:

基于单片机的手环设计

全部资料(源程序、仿真文件、安装包、演示视频):

百度网盘资料下载

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

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

相关文章

vue3项目中引入词云图

在vue3中的项目引入词云图 前言&#xff1a;先看效果图步骤如下 前言&#xff1a; 公司产品要求项目中使用词云图&#xff0c;我算是第一次用&#xff0c;于是在网上查找资料&#xff0c;最后做出来了。 先看效果图 步骤如下 npm i echarts-wordcloud -S <template> …

恶意AI大模型的兴起将改变网络安全

LLM 的恶意版本&#xff08;如 ChatGPT 的黑暗变体&#xff09;的兴起正在通过使用更复杂和自动化的攻击来升级网络战。 这些模型可以生成令人信服的网络钓鱼电子邮件、传播虚假信息并制作有针对性的社会工程消息。 所有这些非法功能都对在线安全构成了重大威胁&#xff0c;并加…

2024年最新前端工程师 TypeScript 基础知识点详细教程(更新中)

1. TypeScript 概述 TypeScript 是由微软开发的、基于 JavaScript 的一种强类型编程语言。它是在 JavaScript 的基础上添加了静态类型检查、面向对象编程等功能的超集&#xff0c;最终会被编译为纯 JavaScript 代码。由于其扩展了 JavaScript 的功能&#xff0c;TypeScript 特…

[Redis][数据类型]详细讲解

1.Redis 特殊数据结构 1.Streams 应用场景&#xff1a;主要用为队列(阻塞队列) 2.Geospatial 应用场景&#xff1a;用来存储坐标(经纬度) 3.HyperLogLog 应用场景&#xff1a;估算集合中的元素个数注意&#xff1a; HyperLogLog不存储元素的内容&#xff0c;但是能够记录“…

【机器学习】ROC曲线

【机器学习】ROC曲线 1、ROC曲线简介2、ROC曲线和AUC值2.1 ROC曲线2.2 AUC值 3、实验内容3.1 准备数据集3.2 特征提取3.3 数据集划分3.4 模型训练与预测3.5 计算和绘制ROC曲线3.6 绘制混淆矩阵3.7 三分类混淆矩阵 4 源代码4.1 实现ROC二分类4.2 三分类混淆例子 1、ROC曲线简介 …

cnn机器学习时python版本不兼容报错

在使用python执行CNN算法时&#xff0c;发生如下报错&#xff1a; A module that was compiled using NumPy 1.x cannot be run in NumPy 2.1.1 as it may crash. To support both 1.x and 2.x versions of NumPy, modules must be compiled with NumPy 2.0. Some module may …

网络高级day03(Http)

目录 【1】HTTP简介 【2】 HTTP特点 【3】 HTTP协议格式 1》客户端请求消息格式 1> 请求行 2> 请求头 3> 空行 4> 请求数据 2》服务器响应消息格式 【1】HTTP简介 HTTP协议是Hyper Text Transfer Protocol &#xff08;超文本传输协议&#xff09;的缩写&a…

低代码平台:数据筛选功能的全新变革

随着软件开发需求的不断增长&#xff0c;传统的开发方法因其复杂性和耗时性而逐渐无法满足市场对快速交付和迭代的需求。低代码开发平台作为一种新型的软件开发工具&#xff0c;以其高效、易用的特点受到了广泛的关注和应用。 在软件开发领域&#xff0c;数据筛选是一项基础且…

frpc内网穿透

官网地址&#xff1a;frp官网 本次用到的Liunx包&#xff1a; https://github.com/fatedier/frp/releases/download/v0.60.0/frp_0.60.0_linux_amd64.tar.gz下载&#xff1a; wget https://github.com/fatedier/frp/releases/download/v0.60.0/frp_0.60.0_linux_amd64.tar.g…

经典大语言模型解读(3):参数量更大、泛化性能更强的生成式模型GPT-2

概述 在GPT-1的基础上&#xff0c;OpenAI提出了包含15亿参数&#xff08;GPT-1参数量的10倍以上&#xff09;的GPT-2模型。该模型在一个更大规模的文本数据集WebText上进行预训练。与GPT-1依赖特定任务上的有监督微调来提升性能不同&#xff0c;GPT-2具备更强的零样本&#xf…

中小企业体系技术抽象沉淀-异地灾备篇

IT团队内部使用工具 系列文章&#xff1a;https://blog.csdn.net/caicongyang/article/details/136857045 DDL DML管控 https://github.com/hhyo/Archery/ flyway 文档编写 wiki 技术对外输出文档推荐gitbook 同城双活数据同步方案 总览&#xff1a; vivo 系列文章&#x…

脱离枯燥的CRUD,灵活使用Mybatis,根据mybatis动态的xml片段和接口规范动态生成代理类,轻松应付简单业务场景。

需求 需求是这样的&#xff0c;我们有一个数据服务平台的产品&#xff0c;用户先将数据源信息保存到平台上&#xff0c;一个数据源可以提供多个接口服务&#xff0c;而每个接口服务在数据库中存一个具有mybatis语法的sql片段。这样的话&#xff0c;对于一些简单的业务只需要编…

*C++:list

一.list简介 1. list 是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list 的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素…

一文 学透 力扣—N数之和

题目一&#xff1a;1. 两数之和❤ 题目思路 当我们需要查询一个元素是否出现过&#xff0c;或者一个元素是否在集合里的时候&#xff0c;就要第一时间想到哈希法。 本题呢&#xff0c;我就需要一个集合来存放我们遍历过的元素&#xff0c;然后在遍历数组的时候去询问这个集合…

第一个NDK项目

新建项目 选择Native C的项目&#xff0c;我这里给项目的命名是NDKTest。 目录分析 新增了一个cpp目录&#xff0c;里面有一个CMakeLists和.cpp文件。 CMakeLists 文件是用来配置C编译过程的。 # Sets the minimum CMake version required for this project. cmake_minimum_…

[OpenCV] 数字图像处理 C++ 学习——16直方图均衡化、直方图比较 详细讲解+附完整代码

文章目录 前言1.直方图均衡化的理论基础(1)什么是直方图(2)直方图均衡化原理(3)直方图均衡化公式 2.直方图比较理论基础(1)相关性 (Correlation)——HISTCMP_CORREL(2)卡方 (Chi-Square)——HISTCMP_CHISQR(3)十字交叉性 (Intersection) ——HISTCMP_INTERSECT(4)巴氏距离 (Bha…

缓存的思考与总结

缓存的思考与总结 什么是缓存缓存命中率数据一致性旁路模式 Cache aside双写模式直写模式 write through异步写 Write Behind 旁路和双写 案例 新技术或中间的引入&#xff0c;一定是解决了亟待解决的问题或是显著提升了系统性能&#xff0c;并且这种改变所带来的增幅&#xff…

Mysql删库跑路,如何恢复数据?

问题 删库跑路&#xff0c;数据还能恢复吗&#xff1f; 我们经常听说某某被领导训斥了&#xff0c;对领导心生痛恨&#xff0c;然后登录 Mysql 删库跑路。对于闲聊中经常听说过的一个段子&#xff0c;在现实生活中是否真的发生过&#xff0c;如果发生了&#xff0c;我们该如何解…

基于单片机的智能小车的开发与设计

摘要&#xff1a;本文论述了基于 STC89C52 单片机的智能小车的开发与设计过程。该设计采用单片机、电机驱动及光电循迹等技术&#xff0c;保证小车在无人管理状态下&#xff0c;能按照预先设定的线路实现自动循迹功能。在电路结构设计中力求方便&#xff0c;可操作&#xff0c;…

go webapi上传文件

一、导入依赖 import "net/http" 我这里用到了Guid所以安装依赖 go get github.com/google/uuid 二、main.go package mainimport ("fmt""github.com/jmoiron/sqlx""github.com/tealeg/xlsx""log""path/filepath&q…