功能模块整合

程序架构

第一部分:所用到模块的初始化

第二部分:中断部分。利用定时中断实现呼吸灯RTC显示时间、动态图片切换、超时检测以及息屏等功能

第三部分:主逻辑循环部分。采用的是状态机扫描的方式进行的,根据按键控制页编号变量,然后页编号控制相应的功能。

具体程序如下:

主逻辑循环部分:

int a = 10;

int main(void)
{
	u8 key = 0;

	function_init();
	
	/*开机功能*/
	page_open();

	a++;
	
	while(1)
	{
		key = fun_key_scan();
		//按键控制页编号变量
		if(key == KEY_Right && key_ok_flag==0)
		{
			page_flag = 1;
			timer_buff[7] = 0;    //息屏计时开始
			OLED_clear();
			if(!oled_sta_flag)    //不息屏状态
			{
				page++;
				if(page>6)
				{
					page = 1;
				}
			}
			else
			{
				OLED_writeByte(0xAF,OLED_CMD);
				oled_sta_flag = 0;
			}
			
		}
		else if(key == KEY_Left && key_ok_flag==0)
		{
			page_flag = 1;
			timer_buff[7] = 0;    //息屏计时开始
			OLED_clear();
			if(!oled_sta_flag)
			{
				page--;
				if(page<1)
				{
					page = 6;
				}	
			}
			else
			{
				OLED_writeByte(0xAF,OLED_CMD);
				oled_sta_flag = 0;
			}
			
		}
		
		
		//页编号变量控制界面显示
		switch(page)
		{
			case 1: function_page1();break;
			case 2: function_page2(key);break;
			case 3: function_page3();break;
			case 4: function_page4();break;
			case 5: function_page5();break;
			case 6: function_page6();break;
		}
		
		
		
	
		
		
	}
	
	
	return 0;
}


中断部分:


/***********************************************
*函数名    :TIM1_BRK_TIM9_IRQHandler
*函数功能  :TIM9中断服务函数
*函数参数  :无
*函数返回值:无
*函数描述  :				
************************************************/
u32 timer_buff[10];
u8 pic_n = 0;
RTC_t val;
u8 heart_pic_n = 0;
u8 oled_sta_flag = 0;
void TIM1_BRK_TIM9_IRQHandler(void)
{
	//判断是定时器9的更新中断信号触发
	if(TIM9->SR & (1<<0))
	{
		//清除中断标志位
		TIM9->SR &= ~(1<<0);
		
		//紧急事件
		timer_buff[1]++;
		timer_buff[2]++;
		timer_buff[3]++;
		timer_buff[4]++;
		timer_buff[5]++;
		timer_buff[6]++;
		timer_buff[7]++;
		
		
		//运行指示灯500ms
		if(timer_buff[1] >= 500)
		{
			timer_buff[1] = 0;
			LED_OVERTURN;
			
		}
		
		//RTC显示时间 1000ms
		if(timer_buff[2] >= 1000)
		{
			timer_buff[2] = 0;
			//在设置时间模式下暂听获取时间
			if(key_ok_flag==0 && (page==2 || page==3))
			{
				val = get_time();
				fun_flag = 1;
			}
			
			
		}
		
		
		//timer_buff[3]== 100解锁按键标志位
		if(timer_buff[3] == 100)
		{	
			MOTOR_VAL = 0;
			
		}
		
		
		//动态图片切换
		const u8 *pics[] = {pic_0,pic_1,pic_2,pic_3,pic_4,pic_5,pic_6};
		if(timer_buff[4] >= 50)
		{	 
			if(page==1)
			{
				pic_n++;
				if(pic_n>=102)
				{
					pic_n=0;
				}				
				fun_flag = 1;
			}
			//oled_dis_pic(0,1,64,64,tkr64x64[pic_n]); 
			
			timer_buff[4] = 0;
		}
		
		
		
		//心率开始5秒失败退出时间定时
		if(timer_buff[5] == 5000)
		{	
			
			
		}
		
		
		
		
		//心率动态图
		if(timer_buff[6] == 300)
		{	    
			if(page == 4)
			{
				heart_pic_n++;
				if(heart_pic_n>1)
				{
					heart_pic_n=0;
				}
				fun_flag = 1;
				
			}
			
			timer_buff[6] = 0;
		}
		
		
		//10s息屏
		if(timer_buff[7] >= 10000)
		{	
			if(page !=4 && page != 5 && key_ok_flag==0)
			{
				OLED_writeByte(0xAE,OLED_CMD);
				oled_sta_flag = 1;
			}
			
			timer_buff[7] = 0;
			
		}
		
		
		
		
		
	}
}

每页功能模块部分:

#include "main.h"                  // Device header

u8 page_flag = 1;
u8 fun_flag = 1;
u8 key_ok_flag = 0;
u8 page = 0;

RTC_t time = {2024,4,17,3,15,30,45};


/***********************************************
*函数名    :function_init
*函数功能  :初始haul配置
*函数参数  :无
*函数返回值:无
*函数描述  :
************************************************/
void function_init(void)
{
	NVIC_SetPriorityGrouping(5);   //抢占2位  响应2位
	led_init();                    //LED灯初始化配置
	
	usart1_init(115200);           //串口初始化
	tim2_ch3_pwm_motor();          //振动电机初始化
	fun_key_init();                //五方向按键
	OLED_init();                   //OLED初始化
	RTC_init(time);                //RTC初始化
	sht20_init();                  //SHT20初始化
	Hp_6_init();                   //HP6初始化
	MPU6050_init();                //MPU6050初始化配置

	tim9_interrupt_ms(1);
}


/***********************************************
*函数名    :page_open
*函数功能  :开机界面
*函数参数  :无
*函数返回值:无
*函数描述  :
************************************************/
void page_open(void)
{
	timer_buff[3] = 101;
	oled_dis_pic(0,2,128,64,open_pic);
	MOTOR_VAL = 1000;
	tim11_delay_ms(500);
	MOTOR_VAL = 0;
	OLED_clear();
	page++;
}



/***********************************************
*函数名    :function_page1
*函数功能  :1号页功能
*函数参数  :无
*函数返回值:无
*函数描述  :动态图
************************************************/
void function_page1(void)
{
	
	//只执行一次的程序
	if(page_flag == 1)
	{
		oled_dis_str(3,70,"信盈达",16);
		page_flag = 0;
	}


	//执行多次高刷程序
	if(fun_flag == 1)
	{
		oled_dis_pic(0,2,64,64,(u8 *)(tkr64x64+pic_n)); 
		fun_flag = 0;
	}
	
	
	
	
	
}


/***********************************************
*函数名    :function_page2
*函数功能  :2号页功能
*函数参数  :无
*函数返回值:无
*函数描述  :时间显示
************************************************/
void function_page2(u8 key)
{
	u8 buff[30] = {0};
	
	
	//只执行一次程序
	if(page_flag)
	{
		timer_buff[2] = 1000;     //到此页面马上获取时间显示
		printf("你好,第二页\r\n");
		page_flag = 0;
	}
	
	
	
	//执行多次高刷程序
	if(fun_flag == 1 && key_ok_flag==0)
	{
		//转换时间成字符串
		sprintf((char *)buff,"%d.%d.%d ",val.year,val.mon,val.day);
		oled_dis_str(1,30,buff,16);
		sprintf((char *)buff,"%02d:%02d:%02d",val.h,val.m,val.s);
		oled_dis_str(3,0,buff,24);
		sprintf((char *)buff,"week:%d",val.week);
		oled_dis_str(6,40,buff,16);
		fun_flag = 0;
	}

	//垂直界面进出设置模式
	static u8 set_list = 0;
	static RTC_t t_val;
	
	if(key == KEY_OK)
	{
		key_ok_flag =  !key_ok_flag;   
		OLED_clear();
		//进入到设置界面
		if(key_ok_flag == 1)
		{
			set_list = 0;
			//只显示时间
			sprintf((char *)buff,"%02d:%02d:%02d",val.h,val.m,val.s);
			oled_dis_str(2,set_list,buff,24);
			oled_dis_str(5,set_list,"--",24);
			t_val = val;
			printf("获取原始时间\r\n");
		}
		//退出设置界面
		if(key_ok_flag == 0)
		{
			//如果没有修改时间值,继续获取RTC原本运行时间
			if(t_val.h!=val.h || t_val.m!=val.m || t_val.s!=val.s)
			{
				set_time(val);
				
			}
			timer_buff[2] = 1000;  //马上获取时间显示
		}
	}

	
	
	
	//定位更改的时间(时  分   秒)
	else if(key_ok_flag==1 && key == KEY_Right)
	{
		oled_dis_str(5,set_list,"  ",24);
		set_list+=48;
		if(set_list>96) {set_list=0;}
		oled_dis_str(5,set_list,"--",24);
	}
	
	else if(key_ok_flag==1 && key == KEY_Left)
	{
		oled_dis_str(5,set_list,"  ",24);
		set_list-=48;
		
		if(set_list>200)
		{
			set_list = 96;
		}
		oled_dis_str(5,set_list,"--",24);
	}
	
	//根据定位调整数值 上调
	else if(key_ok_flag==1 && key == KEY_UP)
	{
		if(set_list==0)   //调整小时
		{
			//时间数据结构体中的小时成员
			val.h++;
			if(val.h>23) {val.h = 0;}
//			sprintf((char *)buff,"%02d",val.h);
//			oled_dis_str(2,set_list,buff,24);
			
		}
		else if(set_list==48)   //调整分钟
		{
			//时间数据结构体中的分钟成员
			val.m++;
			if(val.m>59) {val.m = 0;}
//			sprintf((char *)buff,"%02d",val.m);
//			oled_dis_str(2,set_list,buff,24);
		}
		else if(set_list==96)   //调整秒
		{
			//时间数据结构体中的秒成员
			val.s++;
			if(val.s>59) {val.s = 0;}
//			sprintf((char *)buff,"%02d",val.s);
//			oled_dis_str(2,set_list,buff,24);
		}
		
		sprintf((char *)buff,"%02d:%02d:%02d",val.h,val.m,val.s);
		oled_dis_str(2,0,buff,24);
		
	}
	//根据定位调整数值 下调	
	else if(key_ok_flag==1 && key == KEY_Down)
	{
		if(set_list==0)   //调整小时
		{
			//时间数据结构体中的小时成员
			val.h--;
			if(val.h>200) {val.h = 23;}
			sprintf((char *)buff,"%02d",val.h);
			oled_dis_str(2,set_list,buff,24);
		}
		else if(set_list==48)   //调整分钟
		{
			//时间数据结构体中的分钟成员
			val.m--;
			if(val.m>200) {val.m = 59;}
		}
		else if(set_list==96)   //调整秒
		{
			//时间数据结构体中的秒成员
			val.s--;
			if(val.s>200) {val.s = 59;}
		}
		sprintf((char *)buff,"%02d:%02d:%02d",val.h,val.m,val.s);
		oled_dis_str(2,0,buff,24);
	}
	
	
}






/***********************************************
*函数名    :function_page3
*函数功能  :3号页功能
*函数参数  :无
*函数返回值:无
*函数描述  :温湿度显示
************************************************/
void function_page3(void)
{
	TRH_n trh_data; 
	u8 buff[30];
	
	//只执行一次程序
	if(page_flag)
	{
		if(val.h>=6 && val.h<18)   //白天图片
		{
			oled_dis_pic(0,0,64,64,sun);
		}
		else                       //黑天
		{
			oled_dis_pic(0,0,64,64,night);
		}
		//关闭心率
		HP_6_CloseRate();    
		page_flag = 0;
	}
	
	
	
	//执行多次高刷程序
	//停留此界面,在这两个时间点变换图片
	if((val.h==6 || val.h==18) && val.m==0 && val.s==0)
	{
		page_flag = 1;
	}
	
	
	//获取温度
	trh_data = sht20_rec_val(SHT20_T);
	//转换成字符串
	sprintf((char *)buff,"T:%0.1f℃",trh_data.t);
	//显示字符串
	oled_dis_str(1,65,buff,16);
	
	
	//获取湿度
	trh_data = sht20_rec_val(SHT20_RH);
	//转换成字符串
	sprintf((char *)buff,"RH:%d%%",trh_data.rh);
	//显示字符串
	oled_dis_str(4,65,buff,16);
	
}


/***********************************************
*函数名    :function_page4
*函数功能  :4号页功能
*函数参数  :无
*函数返回值:无
*函数描述  :心率测量功能
************************************************/
void function_page4(void)
{
	static u8 err;
	u8 result = 0;
	u8 buff[20];
	static u8 old_val;
	//只执行一次程序
	if(page_flag)
	{
		//关闭血压
		HP_6_Closebp();
		
		//显示界面提示
		oled_dis_str(1,80,"心率",16);
		oled_dis_str(4,80,"test",16);
		oled_dis_pic(0,0,54,54,heart[1]);
		//开启心率测量
		err = HP_6_OpenRate();
		//超时启动报告传感器错误
		if(err == 0)
		{
			oled_dis_str(4,80,"err!",16);
		}
		
		page_flag = 0;
	}

	
	
	//执行多次高刷程序
	if(fun_flag == 1 && err)
	{
		oled_dis_pic(0,0,54,54,heart[heart_pic_n]);
		fun_flag = 0;
	}
	//获取心率数据
	HP_6_GetRateResult(&result);  
	if(result!=0 && err && old_val!=result)     
	{
		old_val = result;
		sprintf((char *)buff,"%03d",result);
		oled_dis_str(4,70,buff,24);
	}	
	
}




/***********************************************
*函数名    :function_page5
*函数功能  :5号页功能
*函数参数  :无
*函数返回值:无
*函数描述  :血压测量功能
************************************************/
void function_page5(void)
{
	u8 bpResult[2] = {0};
	u8 buff[20];
	
	
	//只执行一次程序
	if(page_flag)
	{
		//关闭心率
		HP_6_CloseRate();
		
		//显示测试量血压图片
		oled_dis_pic(0,0,54,54,bmp);
		oled_dis_str(1,80,"血压",16);
		oled_dis_str(3,80,"test",16);
		//开启血压
		u8 err = HP_6_Openbp();
		//超时启动报告传感器错误
		if(err == 0)
		{
			oled_dis_str(3,80,"err!",16);
		}
		
		
		page_flag = 0;
	}
	
	
	
	//执行多次高刷程序
	HP_6_Get_bpResult(bpResult);
	if(bpResult[0]!=0 && bpResult[1]!=0)
	{
		sprintf((char *)buff,"H:%3dPa",bpResult[0]);
		oled_dis_str(3,70,buff,16);
		sprintf((char *)buff,"L:%3dPa",bpResult[1]);
		oled_dis_str(5,70,buff,16);
	}
	
	
	
}



/***********************************************
*函数名    :function_page6
*函数功能  :6号页功能
*函数参数  :无
*函数返回值:无
*函数描述  :MPU6050
************************************************/
void function_page6(void)
{
	ACCG_t ag;
	u8 buff[15];
	
	//只执行一次程序
	if(page_flag)
	{
		//关闭血压
		HP_6_Closebp();
		page_flag = 0;
	}
	
	
	
	//执行多次高刷程序
	//获取六轴数据
	ag = ReadAcceData();
		
	/*显示*/
	sprintf((char *)buff,"Ax:%0.1f Gx:%0.1f ",ag.x_Axis ,ag.x_Gxis );
	oled_dis_str(0,2,buff,16);
	sprintf((char *)buff,"Ay:%0.1f Gy:%0.1f ",ag.y_Axis,ag.y_Gxis);
	oled_dis_str(2,2,buff,16);
	sprintf((char *)buff,"Az:%0.1f Gz:%0.1f ",ag.z_Axis,ag.z_Gxis);
	oled_dis_str(4,2,buff,16); 
	
}












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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

10M和100M网口的编码及EMC影响

10M网口编码技术 10M网口&#xff0c;即10Base-T&#xff0c;采用的是曼彻斯特编码方法 。在这种编码中&#xff0c;“0”由“”跳变到“-”&#xff0c;而“1”由“-”跳变到“” 。这种编码方式的特点是信号的DC平衡&#xff0c;即信号在任何一段时间内的平均电压为零&#…

docker基本使用

参考视频&#xff1a; 参考视频https://www.bilibili.com/video/BV1e64y1F7pJ/?share_sourcecopy_web&vd_source8fc0c76c477d3db71f89fa5ae5b258c7 docker容器操作&#xff1a; 拉取镜像&#xff1a; 拉取官网ubuntu镜像 sudo docker pull ubuntu 运行镜像&#xff1a;…

音频信号采集前端电路分析

音频信号采集前端电路 一、实验要求 要求设计一个声音采集系统 信号幅度&#xff1a;0.1mVpp到1Vpp 信号频率&#xff1a;100Hz到16KHz 搭建一个带通滤波器&#xff0c;滤除高频和低频部分 ADC采用套件中的AD7920&#xff0c;转换率设定为96Ksps &#xff1b;96*161536 …

构建高效在线教育:SpringBoot课程管理系统

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理在线课程管理系统的相关信息成为必然。开发…

【云计算网络安全】解析 Amazon 安全服务:构建纵深防御设计最佳实践

文章目录 一、前言二、什么是“纵深安全防御”&#xff1f;三、为什么有必要采用纵深安全防御策略&#xff1f;四、以亚马逊云科技为案例了解纵深安全防御策略设计4.1 原始设计缺少安全策略4.2 外界围栏构建安全边界4.3 访问层安全设计4.4 实例层安全设计4.5 数据层安全设计4.6…

基于LiteFlow的风控系统指标版本控制

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview 更新日志 最近关于https://github.com/wnhyang/coolGuard此项目更新了如下内容&#xff1a;https://g…

Spring:AOP切入点表达式

对于AOP中切入点表达式&#xff0c;我们总共会学习三个内容&#xff0c;分别是语法格式、通配符和书写技巧。 语法格式 首先我们先要明确两个概念: 切入点:要进行增强的方法切入点表达式:要进行增强的方法的描述方式 对于切入点的描述&#xff0c;我们其实是有两中方式的&a…

docker搭建私有的仓库

docker搭建私有仓库 一、为什么要搭建私有的仓库&#xff1f; 因为在国内&#xff0c;访问&#xff1a;https://hub.docker.com/ 会出现无法访问页面。。。。&#xff08;已经使用了魔法&#xff09; 当然现在也有一些国内的镜像管理网站&#xff0c;比如网易云镜像服务、Dao…

大白话讲Promise(最详细)

学前端的大家都知道promise是重中之重&#xff0c;也是面试的必考项。但是刚接触promise我一直很晕头晕脑的&#xff0c;搜集文章前看后看基本都是讲解promise的状态它的方法就没有再深入了&#xff0c;以至于面试时候面试官一旦往深问我就懵了。所以今天我们就详细的说一下pro…

【笔记】自动驾驶预测与决策规划_Part7_数据驱动的预测方法

文章目录 0. 前言1. 多模态传感器的编码方式1.1 栅格化表示1.2 向量化表示 Vectornet1.3 基于点云或者多模态输入的预测1.4 基于Transformer的方法 2. 网络输出的表达形式2.1 多模态轨迹回归2.2 轨迹分类2.3 轨迹回归轨迹分类2.4 目标点预测 3.场景级别的预测和决策3.1 论文&am…

回溯法经典难题解析

本文将通过几个经典的回溯问题&#xff0c;展示回溯算法的应用及其在解决问题时的核心思想和技巧。这些问题包括全排列、全排列II、N皇后以及数独问题&#xff0c;本文将分别介绍每个问题的思路与实现。 46. 全排列 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有…

无线图传下的低延迟视频传输播放技术探讨

技术背景 无线图传技术即无线图像传输技术&#xff0c;是指不用布线&#xff08;线缆&#xff09;利用无线电波来传输图像数据的技术。 一、工作原理 无线图传技术主要涉及图像采集、编码、调制、发射、接收、解调、解码和图像显示等环节。 图像采集&#xff1a;通过摄像头…

软件测试面试之常规问题

1.描述一下测试过程 类似题目:测试的生命周期 思路:这是一个“范围”很大的题目&#xff0c;而且回答时间一般在3分钟之内&#xff0c;不可能非常详细的描述整个过程&#xff0c;因此答题的思路要从整体结构入手&#xff0c;不要过细。为了保证答案的准确性&#xff0c;可以引…

C++从零到满绩——类和对象(中)

目录 1>>前言 2>>构造函数&#xff08;我称之为初始化函数&#xff09; 3>>析构函数&#xff08;我称之为销毁函数&#xff09; 4>>拷贝构造函数&#xff08;我称之为复制函数&#xff09; 5>>运算符重载 5.2>>赋值运算符重载 ​编辑…

内网渗透横向移动1

1.信息收集 &#xff08;1&#xff09;判断域控 shell net time /domain shell ping OWA2010CN-God.god.org &#xff08;2&#xff09;主机探测 浏览探测->网络探测 主机列表显示&#xff1a; &#xff08;3&#xff09;域用户收集&#xff1a; shell net user /domain…

Edify 3D: Scalable High-Quality 3D Asset Generation 论文解读

目录 一、概述 二、相关工作 1、三维资产生成 2、多视图下的三维重建 3、纹理和材质生成 三、Edify 3D 1、文本生成多视角图像的扩散模型 2、文本和多视角图像生成法线图像的ControlNet 3、重建与渲染模型 4、多视角高分辨率RGB图像生成 四、训练 1、训练过程 2、…

微软正在测试 Windows 11 对第三方密钥的支持

微软目前正在测试 WebAuthn API 更新&#xff0c;该更新增加了对使用第三方密钥提供商进行 Windows 11 无密码身份验证的支持。 密钥使用生物特征认证&#xff0c;例如指纹和面部识别&#xff0c;提供比传统密码更安全、更方便的替代方案&#xff0c;从而显著降低数据泄露风险…

词云图大师(WordCloudMaster): 探索创意无限的词云世界!

在信息化时代&#xff0c;如何以一种新颖且富有创意的方式表达数据、文字或想法&#xff1f;答案是词云图&#xff01;而词云图大师(WordCloudMaster)&#xff0c;正是您的绝佳选择。 无论是个人创意项目&#xff0c;还是专业工作中的数据可视化&#xff0c;词云图大师都能以强…

pycharm使用debug的时候遇到断点不停的问题

1.首先尝试在程序最开头打断点&#xff0c;检查是否能停下&#xff0c;如果可以&#xff0c;看第二步 2.尝试在你打期望停下的代码附近print("1111111")看看是否输出了这个字符串&#xff0c;验证程序确实走到这一步了 3.如果能走到那一步&#xff0c;但是依然没有…

Epipolar-Free 3D Gaussian Splatting for Generalizable Novel View Synthesis 论文解读

目录 一、概述 二、相关工作 1、单场景3DGS 2、跨场景生成3DGS 3、几何方法解决3D任务 三、eFreeSplat 1、预训练跨视角模块 2、无外极线跨视角交互感知模块 3、迭代跨视角高斯对齐 4、高斯参数预测 一、概述 该论文设计了一种不依赖于极线约束的情况实现可推广的新视…