【Proteus仿真】【STM32单片机】智能语音家居陪护机器人

news2024/11/15 0:47:28

文章目录

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


一、功能简介

本项目使用Proteus8仿真STM32单片机控制器,使用OLED显示模块、红外传感器、蜂鸣器、DS18B20温度传感器,风扇LED、语音识别模块等。

主要功能:
系统运行后,OLED显示动画效果,一段时间后静止。当到达指定时间时开启闹钟,系统需感应到有人后,此时可通过K4键或语音关闭闹铃。系统感应到有人后,OLED显示测量的人体体温、时间、LED和风扇的开关状态;此时可通过语音开关LED和风扇;可通过按键K3进入闹钟设置界面,通过K3键切换不同时间位置,K1和K2键加减调节,设置后按下K4键保存并退出,返回测温和时钟显示界面。
语音识别指令(十六进制数):
开灯–>0X01
关灯–>0X02
开风扇–>0X11
关风扇–>0X12
关闹铃–>0X22


二、软件设计

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

*/



//系统数据获取
void sys_data_get(void)
{
	static u8 i=0;
	static u8 oneflag=1;

	while(1)
	{	
		//人体红外检测
		if(IRED==0)
		{
			//温度获取
			i++;
			if(i%1==0)
			{
				TIM_Cmd(TIM2,DISABLE); //关闭定时器
				sys_ctrl.temp=DS18B20_GetTemperture()*10;
				TIM_Cmd(TIM2,ENABLE); //打开定时器
			}
			sys_ctrl.man=1;
		}
		else sys_ctrl.man=0;
		
		//界面状态显示
		if(sys_ctrl.man==0)
		{
			sys_ctrl.window=0;
			if(oneflag==0)
			{
				oneflag=1;
				sys_open_show();//系统开机界面显示	
			}			
		}
		else 
		{
			sys_ctrl.window=1;
			if(oneflag==1)
			{
				oneflag=0;
				sys_parm_show();//系统数据参数显示界面	
			}		
		}		

		break;
	}
}

//系统数据显示
void sys_data_show(void)
{
	u8 buf[9];

	while(1)
	{	
		//显示数据界面
		if(sys_ctrl.window==1)
		{	
			//正常模式下
			if(sys_ctrl.mode==0)
			{
				//温度显示
				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]='C';
				buf[5]='\0';
				OLED_ShowString(3*16,0,buf,16);	
	
				//时间显示
				buf[0]=sys_ctrl.hour/10+0x30;
				buf[1]=sys_ctrl.hour%10+0x30;
				buf[2]=':';
				buf[3]=sys_ctrl.min/10+0x30;
				buf[4]=sys_ctrl.min%10+0x30;
				buf[5]=':';
				buf[6]=sys_ctrl.sec/10+0x30;
				buf[7]=sys_ctrl.sec%10+0x30;
				buf[8]='\0';
				OLED_ShowString(3*16,2,buf,16);
	
				//灯状态显示
				if(sys_ctrl.led==1)OLED_ShowString(2*16,4,"ON ",16);
				else OLED_ShowString(2*16,4,"OFF",16);
				//风扇状态显示
				if(sys_ctrl.motor==1)OLED_ShowString(6*16+8*1,4,"ON ",16);
				else OLED_ShowString(6*16+8*1,4,"OFF",16);
			}
			//时间设置模式下
			else
			{
			   	//吃药时间显示
				buf[0]=sys_ctrl.stime[0][0]/10+0x30;
				buf[1]=sys_ctrl.stime[0][0]%10+0x30;
				buf[2]=':';
				buf[3]=sys_ctrl.stime[0][1]/10+0x30;
				buf[4]=sys_ctrl.stime[0][1]%10+0x30;
				buf[5]=':';
				buf[6]=sys_ctrl.stime[0][2]/10+0x30;
				buf[7]=sys_ctrl.stime[0][2]%10+0x30;
				buf[8]='\0';
				OLED_ShowString(3*16,0,buf,16);
				//运动时间显示
				buf[0]=sys_ctrl.stime[1][0]/10+0x30;
				buf[1]=sys_ctrl.stime[1][0]%10+0x30;
				buf[2]=':';
				buf[3]=sys_ctrl.stime[1][1]/10+0x30;
				buf[4]=sys_ctrl.stime[1][1]%10+0x30;
				buf[5]=':';
				buf[6]=sys_ctrl.stime[1][2]/10+0x30;
				buf[7]=sys_ctrl.stime[1][2]%10+0x30;
				buf[8]='\0';
				OLED_ShowString(3*16,3,buf,16);
				//休息时间显示
				buf[0]=sys_ctrl.stime[2][0]/10+0x30;
				buf[1]=sys_ctrl.stime[2][0]%10+0x30;
				buf[2]=':';
				buf[3]=sys_ctrl.stime[2][1]/10+0x30;
				buf[4]=sys_ctrl.stime[2][1]%10+0x30;
				buf[5]=':';
				buf[6]=sys_ctrl.stime[2][2]/10+0x30;
				buf[7]=sys_ctrl.stime[2][2]%10+0x30;
				buf[8]='\0';
				OLED_ShowString(3*16,6,buf,16);

				switch(sys_ctrl.mode)
				{
					case 1://吃药-时
						OLED_ShowString(3*16,0,"  ",16);
						delay_ms(50);
						buf[0]=sys_ctrl.stime[0][0]/10+0x30;
						buf[1]=sys_ctrl.stime[0][0]%10+0x30;
						buf[2]='\0';
						OLED_ShowString(3*16,0,buf,16);
						break;
					case 2://吃药-分
						OLED_ShowString(3*16+3*8,0,"  ",16);
						delay_ms(50);
						buf[0]=sys_ctrl.stime[0][1]/10+0x30;
						buf[1]=sys_ctrl.stime[0][1]%10+0x30;
						buf[2]='\0';
						OLED_ShowString(3*16+3*8,0,buf,16);
						break;
					case 3://吃药-秒
						OLED_ShowString(3*16+6*8,0,"  ",16);
						delay_ms(50);
						buf[0]=sys_ctrl.stime[0][2]/10+0x30;
						buf[1]=sys_ctrl.stime[0][2]%10+0x30;
						buf[2]='\0';
						OLED_ShowString(3*16+6*8,0,buf,16);
						break;
					case 4://运动-时
						OLED_ShowString(3*16,3,"  ",16);
						delay_ms(50);
						buf[0]=sys_ctrl.stime[1][0]/10+0x30;
						buf[1]=sys_ctrl.stime[1][0]%10+0x30;
						buf[2]='\0';
						OLED_ShowString(3*16,3,buf,16);
						break;
					case 5://运动-分
						OLED_ShowString(3*16+3*8,3,"  ",16);
						delay_ms(50);
						buf[0]=sys_ctrl.stime[1][1]/10+0x30;
						buf[1]=sys_ctrl.stime[1][1]%10+0x30;
						buf[2]='\0';
						OLED_ShowString(3*16+3*8,3,buf,16);
						break;
					case 6://运动-秒
						OLED_ShowString(3*16+6*8,3,"  ",16);
						delay_ms(50);
						buf[0]=sys_ctrl.stime[1][2]/10+0x30;
						buf[1]=sys_ctrl.stime[1][2]%10+0x30;
						buf[2]='\0';
						OLED_ShowString(3*16+6*8,3,buf,16);
						break;
					case 7://休息-时
						OLED_ShowString(3*16,6,"  ",16);
						delay_ms(50);
						buf[0]=sys_ctrl.stime[2][0]/10+0x30;
						buf[1]=sys_ctrl.stime[2][0]%10+0x30;
						buf[2]='\0';
						OLED_ShowString(3*16,6,buf,16);
						break;
					case 8://休息-分
						OLED_ShowString(3*16+3*8,6,"  ",16);
						delay_ms(50);
						buf[0]=sys_ctrl.stime[2][1]/10+0x30;
						buf[1]=sys_ctrl.stime[2][1]%10+0x30;
						buf[2]='\0';
						OLED_ShowString(3*16+3*8,6,buf,16);
						break;
					case 9://休息-秒
						OLED_ShowString(3*16+6*8,6,"  ",16);
						delay_ms(50);
						buf[0]=sys_ctrl.stime[2][2]/10+0x30;
						buf[1]=sys_ctrl.stime[2][2]%10+0x30;
						buf[2]='\0';
						OLED_ShowString(3*16+6*8,6,buf,16);
						break;
				}
			}	
		}
		
		break;		
	}
}


//系统数据设置
void sys_data_set(void)
{
	u8 key=0;
	static u8 oneflag=0;
	//有人的时候
	if(sys_ctrl.window==1)
	{
		key=KEY_Scan(1);
		//语音识别
		if(USART1_RX_BUF[0]==LED_ON_CMD)//开灯
		{
			USART1_RX_BUF[0]=0;
			LED=0;
			sys_ctrl.led=1;	
		}
		else if(USART1_RX_BUF[0]==LED_OFF_CMD)//关灯
		{
			USART1_RX_BUF[0]=0;
			LED=1;
			sys_ctrl.led=0;	
		}
		else if(USART1_RX_BUF[0]==MOTOR_ON_CMD)//开风扇
		{
			USART1_RX_BUF[0]=0;
			MOTOR=0;
			sys_ctrl.motor=1;	
		}
		else if(USART1_RX_BUF[0]==MOTOR_OFF_CMD)//关风扇
		{
			USART1_RX_BUF[0]=0;
			MOTOR=1;
			sys_ctrl.motor=0;
		}
		else if(USART1_RX_BUF[0]==ALARM_OFF_CMD)//关闹铃
		{
			USART1_RX_BUF[0]=0;
			sys_ctrl.alarm=0;
			OLED_ShowString(0,6,"        ",16);
		}	
	}	
	//模式设置
	if(key==KEY3_PRESS)
	{
		sys_ctrl.mode++;
		if(sys_ctrl.mode>9)sys_ctrl.mode=1;	
		if(oneflag==0)//时间设置界面仅显示1次
		{
			oneflag=1;
			sys_time_set_show();//系统时间设置界面显示	
		}
	}
	//在设置模式下,加
	else if(key==KEY1_PRESS)
	{
		switch(sys_ctrl.mode)
		{
			case 1://吃药-时
				sys_ctrl.stime[0][0]++;
				if(sys_ctrl.stime[0][0]>23)sys_ctrl.stime[0][0]=0; 
				break;
			case 2://吃药-分
				sys_ctrl.stime[0][1]++;
				if(sys_ctrl.stime[0][1]>59)sys_ctrl.stime[0][1]=0; 
				break;
			case 3://吃药-秒
				sys_ctrl.stime[0][2]++;
				if(sys_ctrl.stime[0][2]>59)sys_ctrl.stime[0][2]=0; 
				break;
			case 4://运动-时
				sys_ctrl.stime[1][0]++;
				if(sys_ctrl.stime[1][0]>24)sys_ctrl.stime[1][0]=0; 
				break;
			case 5://运动-分
				sys_ctrl.stime[1][1]++;
				if(sys_ctrl.stime[1][1]>59)sys_ctrl.stime[1][1]=0; 
				break;
			case 6://运动-秒
				sys_ctrl.stime[1][2]++;
				if(sys_ctrl.stime[1][2]>59)sys_ctrl.stime[1][2]=0; 
				break;
			case 7://休息-时
				sys_ctrl.stime[2][0]++;
				if(sys_ctrl.stime[2][0]>24)sys_ctrl.stime[2][0]=0; 
				break;
			case 8://休息-分
				sys_ctrl.stime[2][1]++;
				if(sys_ctrl.stime[2][1]>59)sys_ctrl.stime[2][1]=0; 
				break;
			case 9://休息-秒
				sys_ctrl.stime[2][2]++;
				if(sys_ctrl.stime[2][2]>59)sys_ctrl.stime[2][2]=0; 
				break;		
		}		
	}
	//在设置模式下,减
	else if(key==KEY2_PRESS)
	{
		switch(sys_ctrl.mode)
		{
			case 1://吃药-时
				sys_ctrl.stime[0][0]--;
				if(sys_ctrl.stime[0][0]<0)sys_ctrl.stime[0][0]=23; 
				break;
			case 2://吃药-分
				sys_ctrl.stime[0][1]--;
				if(sys_ctrl.stime[0][1]<0)sys_ctrl.stime[0][1]=59; 
				break;
			case 3://吃药-秒
				sys_ctrl.stime[0][2]--;
				if(sys_ctrl.stime[0][2]<0)sys_ctrl.stime[0][2]=59; 
				break;
			case 4://运动-时
				sys_ctrl.stime[1][0]--;
				if(sys_ctrl.stime[1][0]<0)sys_ctrl.stime[1][0]=23; 
				break;
			case 5://运动-分
				sys_ctrl.stime[1][1]--;
				if(sys_ctrl.stime[1][1]<0)sys_ctrl.stime[1][1]=59; 
				break;
			case 6://运动-秒
				sys_ctrl.stime[1][2]--;
				if(sys_ctrl.stime[1][2]<0)sys_ctrl.stime[1][2]=59; 
				break;
			case 7://休息-时
				sys_ctrl.stime[2][0]--;
				if(sys_ctrl.stime[2][0]<0)sys_ctrl.stime[2][0]=23; 
				break;
			case 8://休息-分
				sys_ctrl.stime[2][1]--;
				if(sys_ctrl.stime[2][1]<0)sys_ctrl.stime[2][1]=59; 
				break;
			case 9://休息-秒
				sys_ctrl.stime[2][2]--;
				if(sys_ctrl.stime[2][2]<0)sys_ctrl.stime[2][2]=59; 
				break;		
		}	
	}
	//确定
	else if(key==KEY4_PRESS)
	{	
		if(oneflag==1)
		{
			sys_ctrl.mode=0;
			oneflag=0;
			sys_parm_show();//系统数据参数显示界面	
		}
		//闹铃
		if(sys_ctrl.alarm==1)
		{
			sys_ctrl.alarm=0;
			OLED_ShowString(0,6,"        ",16);	
		}	
	}
}

//应用控制系统
void appdemo_show(void)
{
	u8 i=10;
	KEY_Init();
	ctrl_pin_init();
	BEEP_Init();
	DS18B20_Init();
	//等待温度数据稳定
	while(i--)
	{
		sys_ctrl.temp=DS18B20_GetTemperture()*10;
		delay_ms(100);	
	}
	OLED_Init();
	USART1_Init(9600);
	printf("USART1_Init OK\r\n");
	TIM2_Init(400-1,70);//定时10ms
	sys_parm_init();//系统参数初始化
	sys_open_show();//系统初始界面显示
	TIM_Cmd(TIM2,ENABLE); //打开定时器
	while(1)
	{
		sys_data_get();//系统数据获取
		sys_data_show();//系统数据显示
		sys_data_set();//系统数据设置
		sys_fun_ctrl();//系统功能控制		
	}
}









三、实验现象

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

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


联系作者

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

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

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

相关文章

asp.net古代服饰系统VS开发sqlserver数据库web结构c#编程包含购物答题功能点

一、源码特点 asp.net 古代服饰系统 是一套完善的web设计管理系统(含购物 答题)&#xff0c;系统采用mvc模式&#xff08;BLLDALENTITY&#xff09;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境 为vs2010&#xff0c;数据库为sqlserver…

华为数通方向HCIP-DataCom H12-831题库(多选题:81-100)

第81题 经典的网络转发方式是基于路由表转发。OpenFlow交换机的转发方式是基于流表转发。对于这两种转发方式,以下说法正确的有哪些选项? A、流表的匹配方式是同时匹配流量的MAC地址和IP地址。 B、路由表的匹配方式是匹配拥有最长掩码的目的网段路由 C、流表是变长的。一台网…

双十一购物狂欢节准备好买什么了吗?双十一这些好物不能错过

双十一是电商节&#xff0c;各大电商平台都会推出各种促销活动&#xff0c;吸引消费者抢购商品。在这个特别的时刻&#xff0c;许多人都迫不及待地开始筹备自己的购物清单&#xff0c;想要趁着这个机会购买自己心仪的商品。那么&#xff0c;在这个双十一购物狂欢节&#xff0c;…

MATLAB中polyval函数用法

目录 语法 说明 示例 计算几个点处的多项式值 对四次多项式求积分 具有误差估计值的线性回归 使用中心化和缩放改善数值属性 polyval函数的功能是多项式计算。 语法 y polyval(p,x) [y,delta] polyval(p,x,S) y polyval(p,x,[],mu) [y,delta] polyval(p,x,S,mu) …

招商平台小程序开发制作方案

招商平台小程序旨在为企业提供一个便捷、高效的招商信息发布和合作伙伴寻找的平台。通过整合企业资源&#xff0c;打造一个集信息发布、信息筛选、在线沟通、合作洽谈等功能于一体的综合性招商服务平台。 一、招商平台小程序的用户需求 1. 企业用户&#xff1a;需要一个便捷的…

华为升腾C92安装黑群晖

华为升腾C92安装黑群晖 升腾C92&#xff1a;几年前完小校配置了一批班班通&#xff0c;现在基本已退出历史舞台&#xff0c;这样一批小电脑闲置吃灰也挺可惜的&#xff0c;总想再利用起来。&#xff08;如果手头没有的话&#xff0c;某宝上面二手货大约250元&#xff09; CPU类…

什么是React Router?它的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

《从零开始大模型开发与微调 :基于PyTorch与ChatGLM》简介

内 容 简 介 大模型是深度学习自然语言处理皇冠上的一颗明珠&#xff0c;也是当前AI和NLP研究与产业中最重要的方向之一。本书使用PyTorch 2.0作为学习大模型的基本框架&#xff0c;以ChatGLM为例详细讲解大模型的基本理论、算法、程序实现、应用实战以及微调技术&#xff0c;…

Linux - 进程状态 - Linux 当中的进程状态是如何维护的?

进程状态 一个进程在 系统当中有很多的状态&#xff0c;比如&#xff1a;一个进程正在被cpu执行&#xff0c;那这个进程就是一个 r 状态&#xff1b;一个进程已经准备好了&#xff0c;但是其中的运行这个进程需要的资源没有准备好&#xff0c;那么这个进程一人不能运行。 比如…

【2021集创赛】平头哥杯三等奖:智能头盔设计

本作品参与极术社区组织的有奖征集|秀出你的集创赛作品风采,免费电子产品等你拿~活动。 杯赛题目&#xff1a;基于平头哥无线智能开发板的创新应用项目设计 参赛组别&#xff1a;A组、B组 赛题内容&#xff1a; 本次大赛将结合玄铁开源E902处理器以及内含玄铁803处理器的TXW830…

JetBrains IntelliJ IDEA 2023:打造高效开发环境(IDE)的不二之选

您是否正在寻找一款能够帮助您更加高效地进行项目开发的集成开发环境&#xff08;IDE&#xff09;&#xff1f;那么&#xff0c;JetBrains IntelliJ IDEA 2023可能是您的最佳选择。 IntelliJ IDEA是一款为Java开发者准备的综合性IDE&#xff0c;以其强大的智能代码助手和用户友…

Maven实战-私服搭建详细教程

Maven实战-私服搭建详细教程 1、为什么需要私服 首先我们为什么需要搭建Maven私服&#xff0c;一切技术来源于解决需求&#xff0c;因为我们在实际开发中&#xff0c;当我们研发出来一个 公共组件&#xff0c;为了能让别的业务开发组用上&#xff0c;则搭建一个远程仓库很有…

SK海力士:将成为引领人工智能时代的定制型半导体存储器公司

AI芯片是一种专门针对人工智能应用设计的芯片&#xff0c;能够高效地处理人工智能任务&#xff0c;如机器学习、深度学习等。AI芯片具有高运算速度、低功耗、便于集成等特点&#xff0c;是人工智能领域的重要发展方向之一。 目前&#xff0c;AI芯片主要分为GPU、FPGA和ASIC三种…

无符号数与有符号数的比较

无符号数与有符号数的比较 无符号数与有符号数的比较 无符号数与有符号数的比较一、无符号数与有符号数的比较二、无符号数与有符号数的取值范围 一、无符号数与有符号数的比较 一个有符号的整型数据可以分为两部分一部分是符号位、一部分是数字位 无符号数据类型只包含数字位…

8.3 矢量图层点要素单一符号使用二

文章目录 前言单一符号&#xff08;Single symbol&#xff09;渲染图片标记&#xff08;Raster Image marker&#xff09;QGis代码实现 动画标记&#xff08;Animated marker&#xff09;QGis代码实现 总结 前言 上一篇教程介绍了矢量图层点要素单一符号中简单标记和svg标记本…

初识Java语言

&#x1f435;本文将对Java的一些基本名称和基本数据类型进行讲解 1. 第一个Java程序 public class Hello {public static void main(String[] args) {System.out.println("Hello World");} } public class Hello 被class修饰的称为类&#xff0c;而当类被public修…

渗透测试工具-sqlmap使用

sqlmap是一个开源渗透测试的自动化工具&#xff0c;可以自动检测和利用SQL注入漏洞并接管数据库服务器。它配备了一个强大的检测引擎&#xff0c;许多用于终极渗透测试的利基功能&#xff0c;以及广泛的开关&#xff0c;包括数据库指纹识别、从数据库中获取数据、访问底层文件系…

NI Multisim 14.0使用技巧

资料 信号发生器 频率 占空比 振幅 偏置 示波器

【Java集合类面试二十八】、说一说TreeSet和HashSet的区别

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;说一说TreeSet和HashSet…