功能模块整合

程序架构

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

第二部分:中断部分。利用定时中断实现呼吸灯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]++;//运行指示灯500msif(timer_buff[1] >= 500){timer_buff[1] = 0;LED_OVERTURN;}//RTC显示时间 1000msif(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 headeru8 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); }

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

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

相关文章

【创建型设计模式】工厂模式

【创建型设计模式】工厂模式 创建型设计模式第二期&#xff01;本期介绍简单工厂模式和工厂方法模式。 简单工厂模式 简单工厂模式&#xff08;又叫作静态工厂方法模式&#xff09;&#xff0c;其属于创建型设计模式&#xff0c;简单工厂模式不属于设计模式中的 23 种经典模…

RabbitMQ和RocketMQ相关面试题

RabbitMQ和RocketMQ面试题 RabbitMQ1.RabbitMQ各部分角色2.如何确保RabbitMQ消息的可靠性&#xff1f;3.什么样的消息会成为死信&#xff1f;4.死信交换机的使用场景是什么&#xff1f;5.TTL6.延迟队列7.消息堆积问题8.MQ集群 RocketMQ1.RocketMQ各部分角色2.RocketMQ如何保证高…

基于LLama_factory的Qwen2.5大模型的微调笔记

Qwen2.5大模型微调记录 LLama-facrotyQwen2.5 模型下载。huggingface 下载方式Modelscope 下载方式 数据集准备模型微调模型训练模型验证及推理模型导出 部署推理vllm 推理Sglang 推理 LLama-facroty 根据git上步骤安装即可&#xff0c;要求的软硬件都装上。 llama-factory运行…

Linux系统Docker部署开源在线协作笔记Trilium Notes与远程访问详细教程

目录 ⛳️推荐 前言 1. 安装docker与docker-compose 2. 启动容器运行镜像 3. 本地访问测试 4.安装内网穿透 5. 创建公网地址 6. 创建固定公网地址 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下…

Spark——安装步骤详细教程

1、安装步骤 1、上传 cd /opt/modules 2、解压 tar -zxf spark-3.1.2-bin-hadoop3.2.tgz -C /opt/installs 3、重命名 cd /opt/installs mv spark-3.1.2-bin-hadoop3.2 spark-local 4、创建软链接 ln -s spark-local spark 5、配置环境变量&#xff1a; vi /etc/prof…

Vue第一篇:组件模板总结

前言 本文希望读者有一定的Vue开发经验&#xff0c;样例采用vue中的单文件组件&#xff0c;也是我的个人笔记&#xff0c;欢迎一起进步 必须有根元素 这是一个最简单的vue单文件组件&#xff0c;<template></template>被称为模板&#xff0c;模板中必须有一个根元素…

MacOS通过X11转发远程运行virt-manager进行虚机分配

今天需要通过本地macbook机器连接远程物理机&#xff0c;执行虚机分配&#xff0c;现有文档仅提供window环境安装&#xff0c;如下整理Mac环境下的安装步骤 操作篇 前提条件 支持x11转发的terminal&#xff0c;我本地使用iTerm2&#xff1b;本地安装XQuartz&#xff0c;作为…

flowable流程图详细绘制教程

文章目录 前言一、flowable是什么&#xff1f;回答下之前的问题 二、flowable-modeler使用1. 使用步骤2.开始绘制弄一个请假的流程 三 加载该流程总结 前言 flowable有些晦涩难懂的东西&#xff1a; 我最开始接触的时候,还是用的activity,当时觉得好复杂,那么这次经过我自己在…

C/C++链接数据库(MySQL)(超级详细)

目录 1.进入MySQL后&#xff0c;用mysql数据库 1.1查看一看user表 ​编辑1.2从user拿出来User和Host 1.3创建一个用户表&#xff0c;只允许本地&#xff08;想要远端链接就把localhost改成%&#xff09; 1.4再查一下用户就有了&#xff08;connector&#xff09; 1.5测试…

Jmeter中的定时器

4&#xff09;定时器 1--固定定时器 功能特点 固定延迟&#xff1a;在每个请求之间添加固定的延迟时间。精确控制&#xff1a;可以精确控制请求的发送频率。简单易用&#xff1a;配置简单&#xff0c;易于理解和使用。 配置步骤 添加固定定时器 右键点击需要添加定时器的请求…

msvcr100.dll丢失的解决方法,六种解决msvcr100.dll丢失的方法

在使用Windows操作系统的过程中&#xff0c;用户可能会遇到各种各样的问题&#xff0c;其中之一就是“msvcr100.dll丢失”的错误提示。这个问题通常出现在尝试运行某些软件或游戏时&#xff0c;由于缺少这个重要的动态链接库文件&#xff0c;导致程序无法正常启动。本文将详细介…

排序(Java数据结构)

1. 排序的概念及引用 1.1 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。(所有的排序都是默认从小到大排序) 稳定性&#xff1a;假定在待排序的记录序列中&#xff…

VH6501国产替代同星TH7011干扰仪?

文章目录 同星TH7011干扰仪VH6501有使用过TH7011的么,可以在评论区讨论一下~ 同星TH7011干扰仪 干货分享 | 一文详解同星CAN总线干扰仪的使用方法 VH6501

蓝桥杯每日真题 - 第23天

题目&#xff1a;&#xff08;直线&#xff09; 题目描述&#xff08;12届 C&C B组C题&#xff09; 解题思路&#xff1a; 题目理解: 在平面直角坐标系中&#xff0c;从给定的点集中确定唯一的直线。 两点确定一条直线&#xff0c;判断两条直线是否相同&#xff0c;可通过…

目录遍历漏洞-CVE-2021-41773

目录 简介 原理 例子 Apache路径穿越漏洞 环境搭建 漏洞原理 漏洞利用 简介 目录遍历漏洞&#xff08;也称为路径遍历漏洞&#xff09;是一种由于Web服务器或Web应用程序对用户输入的文件名称的安全性验证不足而导致的安全漏洞。 原理 目录遍历漏洞允许攻击者在未授权…

.NET9 - 新功能体验(三)

书接上回&#xff0c;我们继续来聊聊.NET9和C#13带来的新变化。 01、Linq新方法 CountBy 和 AggregateBy 引入了新的方法 CountBy 和 AggregateBy后&#xff0c;可以在不经过GroupBy 分配中间分组的情况下快速完成复杂的聚合操作&#xff0c;同时方法命名也非常直观&#xff0…

Android蓝牙架构,源文件目录/编译方式学习

Android 版本 发布时间 代号&#xff08;Codename&#xff09; Android 1.0 2008年9月23日 无 Android 1.1 2009年2月9日 Petit Four Android 1.5 2009年4月27日 Cupcake Android 1.6 2009年9月15日 Donut Android 2.0 2009年10月26日 Eclair Android 2.1 2…

YOLO-World解读:零基础学习开放世界模型

文章目录 一、摘要二、引言相关工作方法预训练公式模型架构可重新参数化的视觉-语言路径聚合网络&#xff08;RepVL-PAN&#xff09; 3.4 预训练方案 实验YOLO-World: 利用多样化数据集进行开放词汇对象检测的预训练方法YOLO-World: LVIS数据集上的零样本性能评估YOLO-World: 预…

信创改造 - TongRDS 安装方式之控制台安装【Window】

安装前准备 安装 jdk1.8 即可&#xff0c;并配上 环境变量 安装 1&#xff09;解压缩 2&#xff09;启动 进入安装路径的console\bin目录&#xff0c;在cmd命令行窗口运行console.bat 输入序号 1 如果想查看运行状态&#xff0c;可以重新执行 console.bat&#xff0c;然后输…

志愿者小程序源码社区网格志愿者服务小程序php

志愿者服务小程序源码开发方案&#xff1a;开发语言后端php&#xff0c;tp框架&#xff0c;前端是uniapp。 一 志愿者端-小程序&#xff1a; 申请成为志愿者&#xff0c;志愿者组织端进行审核。成为志愿者后&#xff0c;可以报名参加志愿者活动。 志愿者地图&#xff1a;可以…