阳江市网站建设_网站建设公司_SQL Server_seo优化
2026/1/18 17:38:38 网站建设 项目流程

stm32智能手表 - 实践

2026-01-18 17:36  tlnshuju  阅读(0)  评论(0)    收藏  举报

成为粉丝可看全文。有相关代码、硬件和软件说明图。

主程序流程图

说明图:

主程序代码如下,可以修改为自己适用代码

#include "stm32f10x.h"
#include "OLED_I2C.h"
#include "ds1302.h"
#include "ds18b20.h"
#include "usart1.h"
#include "led.h"
#include "delay.h"
#include "max30102_read.h"
#include "myiic.h"
#include "key.h"
#include "iic.h"
#include "stdio.h"
#include "string.h"
#include "adxl345.h"
#include "timer.h"
#include 
#include 
#include 
#define FLASH_SAVE_ADDR  ((u32)0x0800F000) 				//设置FLASH 保存地址(必须为偶数)
#define STM32_RX1_BUF       Usart1RecBuf
#define STM32_Rx1Counter    RxCounter
#define STM32_RX1BUFF_SIZE  USART1_RXBUFF_SIZE
unsigned char setn=0;
unsigned char  p_r=0;		 						//平年/润年  =0表示平年,=1表示润年
float adx,ady,adz;
float acc;
float acc2,acc3;
u8 flag=0;
u16 bushu=0;
long mileage=0;//里程
u16 mileage_bushu = 0;//里程的步数
u16 bu_long = 40;//步长
long warnMileage=1000;//提醒里程
short temperature=0;
u16 xinlvMin=60,xinlvMax=120;//心率下限上限
u16 spo2Min=80;//血氧下限
u16 tempMax=373;//温度上限
u16 tempMin=150;//温度下限
char display[16];
u8 shanshuo=0;
u8 beepFlag=0x00; //蜂鸣器报警标志
u8 page = 0;      //页面切换变量
u8 sendFlag = 1;
/*定时时间*/
long timeCountRecord=0;
long shi=1,fen=0,miao=0;
bool startFlag=0;        //开始定时标志
bool timingReminder=0;   //定时时间提醒标志
bool mileageReminder=0;  //里程提醒标志
bool sendSetValueFlag=0;
int32_t hrAvg;//心率
int32_t spo2Avg;//血氧浓度
void DisplayTime(void)//显示时间函数
{unsigned char i=0,x=0;u16 nian_temp;if(setn==0)DS1302_DateRead(&SysDate);//读时间nian_temp=2000+SysDate.year;if((nian_temp%400==0)||((nian_temp%100!=0)&&(nian_temp%4==0)))  //判断是否为闰年p_r=1;elsep_r=0;if(setn<8 && page==0){OLED_ShowChar((x++)*8,0,'2',2,setn+1-1);OLED_ShowChar((x++)*8,0,'0',2,setn+1-1);OLED_ShowChar((x++)*8,0,SysDate.year/10+'0',2,setn+1-1);OLED_ShowChar((x++)*8,0,SysDate.year%10+'0',2,setn+1-1);OLED_ShowChar((x++)*8,0,'-',2,0);OLED_ShowChar((x++)*8,0,SysDate.mon/10+'0',2,setn+1-2);OLED_ShowChar((x++)*8,0,SysDate.mon%10+'0',2,setn+1-2);OLED_ShowChar((x++)*8,0,'-',2,0);OLED_ShowChar((x++)*8,0,SysDate.day/10+'0',2,setn+1-3);OLED_ShowChar((x++)*8,0,SysDate.day%10+'0',2,setn+1-3);OLED_ShowCN(i*16+88,0,0,setn+1-4);//测试显示中文:周switch(SysDate.week){case 1:OLED_ShowCN(i*16+104,0,1,setn+1-4);//测试显示中文:一break;case 2:OLED_ShowCN(i*16+104,0,2,setn+1-4);//测试显示中文:二break;case 3:OLED_ShowCN(i*16+104,0,3,setn+1-4);//测试显示中文:三break;case 4:OLED_ShowCN(i*16+104,0,4,setn+1-4);//测试显示中文:四break;case 5:OLED_ShowCN(i*16+104,0,i+5,setn+1-4);//测试显示中文:五break;case 6:OLED_ShowCN(i*16+104,0,6,setn+1-4);//测试显示中文:六break;case 7:OLED_ShowCN(i*16+104,0,7,setn+1-4);//测试显示中文:日break;}x=0;OLED_ShowChar((x++)*8,2,SysDate.hour/10+'0',2,setn+1-5);OLED_ShowChar((x++)*8,2,SysDate.hour%10+'0',2,setn+1-5);OLED_ShowChar((x++)*8,2,':',2,0);OLED_ShowChar((x++)*8,2,SysDate.min/10+'0',2,setn+1-6);OLED_ShowChar((x++)*8,2,SysDate.min%10+'0',2,setn+1-6);OLED_ShowChar((x++)*8,2,':',2,0);OLED_ShowChar((x++)*8,2,SysDate.sec/10+'0',2,setn+1-7);OLED_ShowChar((x++)*8,2,SysDate.sec%10+'0',2,setn+1-7);}
}
void GetHeartRateSpO2(void)
{unsigned char x=0;ReadHeartRateSpO2();  //读取心率血氧if(page==0){//显示相关的信息if(((hrAvg!=0)&&(hrAvg>=xinlvMax||hrAvg<=xinlvMin))&&shanshuo==1){OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,' ',2,0);}else{//显示相关的信息OLED_ShowChar((x++)*8,6,hrAvg%1000/100+'0',2,0);OLED_ShowChar((x++)*8,6,hrAvg%100/10+'0',2,0);OLED_ShowChar((x++)*8,6,hrAvg%10+'0',2,0);}x=6;if(((spo2Avg!=0)&&(spo2Avg<=spo2Min))&&shanshuo==1){OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,' ',2,0);}else{//显示相关的信息OLED_ShowChar((x++)*8,6,spo2Avg%1000/100+'0',2,0);OLED_ShowChar((x++)*8,6,spo2Avg%100/10+'0',2,0);OLED_ShowChar((x++)*8,6,spo2Avg%10+'0',2,0);}}
}
void DisplayTemperature(void)//显示温度函数
{unsigned char x=10;//显示的第几个字符temperature=DS18B20_Get_Temp();if(page==0){if((temperature<=tempMin||temperature>=tempMax)&&shanshuo==1){OLED_ShowChar((x++)*8,2,' ',2,0);OLED_ShowChar((x++)*8,2,' ',2,0);OLED_ShowChar((x++)*8,2,' ',2,0);OLED_ShowChar((x++)*8,2,' ',2,0);}else{OLED_ShowChar((x++)*8,2,temperature/100+'0',2,0);OLED_ShowChar((x++)*8,2,temperature%100/10+'0',2,0);OLED_ShowChar((x++)*8,2,'.',2,0);OLED_ShowChar((x++)*8,2,temperature%10+'0',2,0);}}
}
void Store_Data(void) //存储数据
{u16 DATA_BUF[10];DATA_BUF[0] =   bushu;DATA_BUF[1] =   mileage_bushu;DATA_BUF[2] =   bu_long;DATA_BUF[3] =   xinlvMin;DATA_BUF[4] =   xinlvMax;DATA_BUF[5] =   spo2Min;DATA_BUF[6] =   tempMin;DATA_BUF[7] =   tempMax;DATA_BUF[8] =   (warnMileage>>16)&0xFFFF;DATA_BUF[9] =   (warnMileage>>0)&0xFFFF;STMFLASH_Write(FLASH_SAVE_ADDR + 0x20,(u16*)DATA_BUF,10); //写入数据DelayMs(50);
}
void Read_Data(void) //读出数据
{u16 DATA_BUF[10];STM32F10x_Read(FLASH_SAVE_ADDR + 0x20,(u16*)DATA_BUF,10); //读取数据bushu         =  DATA_BUF[0];mileage_bushu =  DATA_BUF[1];bu_long       =  DATA_BUF[2];xinlvMin      =  DATA_BUF[3];xinlvMax      =  DATA_BUF[4];spo2Min       =  DATA_BUF[5];tempMin       =  DATA_BUF[6];tempMax       =  DATA_BUF[7];warnMileage   =  DATA_BUF[8]<<16|DATA_BUF[9];
}
void CheckNewMcu(void)  // 检查是否是新的单片机,是的话清空存储区,否则保留
{u8 comper_str[6];STM32F10x_Read(FLASH_SAVE_ADDR,(u16*)comper_str,5);comper_str[5] = '\0';if(strstr((char *)comper_str,"FDYDZ") == NULL)  //新的单片机{STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)"FDYDZ",5); //写入“FDYDZ”,方便下次校验DelayMs(50);Store_Data();//存储下初始数据DelayMs(50);}Read_Data(); //开机读取下相关数据(步数里程卡路里步长)
}
void GetSteps(void)//获取步数函数
{static u16 temp=0;float tempMileage=0.0;u16 x=11;adxl345_read_average(&adx,&ady,&adz,10);//获取数据acc=ady;if(acc>0)//在正轴{if(acc/10>=4&&flag==1)//加速度值,在正轴值是否大于5,并且flag为1,则视为一个周期完成,步数加1{flag=0;if(bushu<60000)bushu++;	//步数加1if(mileage_bushu<60000)mileage_bushu++;	//步数加1if(temp!=bushu)//当步数发生变化才去存储步数{temp=bushu;Store_Data(); //存储步数}}}if(acc<0)//在负轴{acc=-acc;if(acc/10>=4)//加速度值,在负轴是否小于-5{flag=1;//falg置1}}mileage = (mileage_bushu * bu_long)/100;//计算里程tempMileage = (float)mileage/1000;//转换为千米if(page==0){if(bushu>9999){OLED_ShowChar((x++)*8,6,bushu/10000+'0',2,0);OLED_ShowChar((x++)*8,6,bushu%10000/1000+'0',2,0);OLED_ShowChar((x++)*8,6,bushu%1000/100+'0',2,0);OLED_ShowChar((x++)*8,6,bushu%100/10+'0',2,0);OLED_ShowChar((x++)*8,6,bushu%10+'0',2,0);}else if(bushu>999){OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,bushu%10000/1000+'0',2,0);OLED_ShowChar((x++)*8,6,bushu%1000/100+'0',2,0);OLED_ShowChar((x++)*8,6,bushu%100/10+'0',2,0);OLED_ShowChar((x++)*8,6,bushu%10+'0',2,0);}else if(bushu>99){OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,bushu%1000/100+'0',2,0);OLED_ShowChar((x++)*8,6,bushu%100/10+'0',2,0);OLED_ShowChar((x++)*8,6,bushu%10+'0',2,0);}else if(bushu>9){OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,bushu%100/10+'0',2,0);OLED_ShowChar((x++)*8,6,bushu%10+'0',2,0);OLED_ShowChar((x++)*8,6,' ',2,0);}else{OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,bushu%10+'0',2,0);OLED_ShowChar((x++)*8,6,' ',2,0);OLED_ShowChar((x++)*8,6,' ',2,0);}}else{sprintf(display,"%6.3fkm ",tempMileage);OLED_ShowStr(48,2,(u8 *)display,2);}
}
void DisplaySetValue(void) //显示设置值
{if(page==0){if(setn==8||setn==9){OLED_ShowChar(48,4,xinlvMin/100+'0',2,setn+1-8);//显示OLED_ShowChar(56,4,xinlvMin%100/10+'0',2,setn+1-8);//显示OLED_ShowChar(64,4,xinlvMin%10+'0',2,setn+1-8);//显示OLED_ShowChar(48,6,xinlvMax/100+'0',2,setn+1-9);//显示OLED_ShowChar(56,6,xinlvMax%100/10+'0',2,setn+1-9);//显示OLED_ShowChar(64,6,xinlvMax%10+'0',2,setn+1-9);//显示}if(setn==10){OLED_ShowChar(48,4,spo2Min/100+'0',2,setn+1-10);//显示OLED_ShowChar(56,4,spo2Min%100/10+'0',2,setn+1-10);//显示OLED_ShowChar(64,4,spo2Min%10+'0',2,setn+1-10);//显示}if(setn==11||setn==12){OLED_ShowChar(48,4,tempMin/100+'0',2,setn+1-11);//显示OLED_ShowChar(56,4,tempMin%100/10+'0',2,setn+1-11);//显示OLED_ShowChar(64,4,'.',2,setn+1-11);OLED_ShowChar(72,4,tempMin%10+'0',2,setn+1-11);//显示OLED_ShowChar(48,6,tempMax/100+'0',2,setn+1-12);//显示OLED_ShowChar(56,6,tempMax%100/10+'0',2,setn+1-12);//显示OLED_ShowChar(64,6,'.',2,setn+1-12);OLED_ShowChar(72,6,tempMax%10+'0',2,setn+1-12);//显示}}else{if(setn==4){sprintf((char *)display,"%dcm  ",bu_long);OLED_ShowStr(48, 4, (u8*)display, 2);//显示经度}if(setn==5){sprintf(display,"%6.3fkm ",(float)warnMileage/1000);OLED_ShowStr(35,4,(u8 *)display,2);}}
}
bool press = 0;
void KeySettings(void)//按键设置函数
{unsigned char keynum = 0,i;static u16 pressCount=0;u16 beepCount=0;keynum = KEY_Scan(1);//获取按键值if(keynum==1)//设置{setn++;if(page==1){if(setn > 5){setn=0;sendSetValueFlag=1;Store_Data();OLED_CLS();//清屏for(i=0;i<2;i++)OLED_ShowCN(i*16,2,i+44,0);//显示中文:里程OLED_ShowChar(32,2,':',2,0);}if(setn==4){OLED_CLS();//清屏for(i=0;i<4;i++)OLED_ShowCN(i*16+32,0,i+46,0);//测试显示中文:设置步长}if(setn==5){for(i=0;i<6;i++)OLED_ShowCN(i*16+16,0,i+50,0);//测试显示中文:设置提醒里程}}else{if(setn > 12){setn=0;sendSetValueFlag=1;OLED_CLS();//清屏for(i=0;i<2;i++)OLED_ShowCN(i*16,4,i+16,1);//测试显示中文:心率for(i=0;i<2;i++)OLED_ShowCN(i*16+48,4,i+18,1);//测试显示中文:血氧for(i=0;i<2;i++)OLED_ShowCN(i*16+95,4,i+20,1);//测试显示中文:步数OLED_ShowCentigrade(112, 2);    //℃DelayMs(50);Store_Data();}if(setn==8){OLED_CLS();//清屏for(i=0;i<4;i++)OLED_ShowCN(i*16+32,0,i+22,0);//测试显示中文:设置心率for(i=0;i<2;i++)OLED_ShowCN(i*16,4,i+26,0);   //测试显示中文:下限for(i=0;i<2;i++)OLED_ShowCN(i*16,6,i+28,0);   //测试显示中文:上限OLED_ShowChar(34,4,':',2,0);OLED_ShowChar(34,6,':',2,0);}if(setn==10){for(i=0;i<4;i++)OLED_ShowCN(i*16+32,0,i+30,0);//测试显示中文:设置血氧for(i=0;i<2;i++)OLED_ShowCN(i*16,4,i+26,0);   //测试显示中文:下限OLED_ShowStr(0,6,"                ", 2);}if(setn==11){for(i=0;i<4;i++)OLED_ShowCN(i*16+32,0,i+34,0);//测试显示中文:设置温度for(i=0;i<2;i++)OLED_ShowCN(i*16,4,i+26,0);   //测试显示中文:下限for(i=0;i<2;i++)OLED_ShowCN(i*16,6,i+28,0);   //测试显示中文:上限OLED_ShowChar(34,4,':',2,0);OLED_ShowChar(34,6,':',2,0);}}DisplaySetValue();}if(keynum==2)//加{if(setn == 0 && page==1){if(pressCount<10)pressCount++;if(press==0){press=1;BEEP=1;DelayMs(100);BEEP=0;if(timingReminder==1)  //如果是提醒时间到了,先关闭提醒{timingReminder=0;beepFlag&=0xFD;}else{startFlag=!startFlag;}}if(pressCount>=5)   //长按进行时间清零{startFlag=0;timeCountRecord=0;while(beepCount<1000){BEEP=1;beepCount++;DelayMs(1);}BEEP=0;pressCount=0;}}if(page==1){if(setn == 1)//设置提醒时间的小时{shi ++;if(shi == 100)shi=0;}if(setn == 2)//设置提醒时间的分钟{fen ++;if(fen == 60)fen=0;}if(setn == 3)//设置提醒时间的秒{miao ++;if(miao == 60)miao=0;}if(setn == 4)//设置步长{if(bu_long<200)bu_long++;}if(setn == 5)//设置提醒里程{if(warnMileage<20000)warnMileage+=10;}}else{if(setn == 1)//设置年{SysDate.year ++;if(SysDate.year == 100)SysDate.year=0;DS1302_DateSet(&SysDate);//设置时间}if(setn == 2)//设置月{SysDate.mon ++;if(SysDate.mon == 13)SysDate.mon = 1;if((SysDate.mon==4)||(SysDate.mon==6)||(SysDate.mon==9)||(SysDate.mon==11)){if(SysDate.day>30)SysDate.day=1;}else{if(SysDate.mon==2){if(p_r==1){if(SysDate.day>29)SysDate.day=1;}else{if(SysDate.day>28)SysDate.day=1;}}}DS1302_DateSet(&SysDate);//设置时间}if(setn == 3)//设置日{SysDate.day ++;if((SysDate.mon==1)||(SysDate.mon==3)||(SysDate.mon==5)||(SysDate.mon==7)||(SysDate.mon==8)||(SysDate.mon==10)||(SysDate.mon==12))//大月{if(SysDate.day==32)//最大31天SysDate.day=1;//从1开始}else{if(SysDate.mon==2)//二月份{if(p_r==1)//闰年{if(SysDate.day==30)//最大29天SysDate.day=1;}else{if(SysDate.day==29)//最大28天SysDate.day=1;}}else{if(SysDate.day==31)//最大30天SysDate.day=1;}}DS1302_DateSet(&SysDate);//设置时间}if(setn == 4)//设置星期{SysDate.week ++;if(SysDate.week == 8)SysDate.week=1;DS1302_DateSet(&SysDate);//设置时间}if(setn == 5)//设置时{SysDate.hour ++;if(SysDate.hour == 24)SysDate.hour=0;DS1302_DateSet(&SysDate);//设置时间}if(setn == 6)//设置分{SysDate.min ++;if(SysDate.min == 60)SysDate.min=0;DS1302_DateSet(&SysDate);//设置时间}if(setn == 7)//设置秒{SysDate.sec ++;if(SysDate.sec == 60)SysDate.sec=0;DS1302_DateSet(&SysDate);//设置时间}if((setn==8)&&(xinlvMax-xinlvMin>1))xinlvMin++;if((setn==9)&&(xinlvMax<300))xinlvMax++;if((setn==10)&&(spo2Min<200))spo2Min++;if((setn==11)&&(tempMax-tempMin>1))tempMin++;if((setn==12)&&(tempMax<999))tempMax++;}DisplaySetValue();}else{if(press==1){press=0;pressCount=0;}}if(keynum==3)//减{if(page==1){if(setn == 0){if(mileageReminder==1)   //如果是提醒里程到了,先关闭提醒{mileageReminder=0;BEEP=0;}else if(mileageReminder==0)   //里程清零{mileage=0;mileage_bushu=0;Store_Data(); //存储步数}}if(setn == 1)//设置提醒时间的小时{if(shi == 0)shi=100;shi --;}if(setn == 2)//设置提醒时间的分钟{if(fen == 0)fen=60;fen --;}if(setn == 3)//设置提醒时间的秒{if(miao == 0)miao=60;miao --;}if(setn == 4)//设置步长{if(bu_long>0)bu_long--;}if(setn == 5)//设置提醒里程{if(warnMileage>=10)warnMileage-=10;}}else{if(setn == 1)//设置年{if(SysDate.year == 0)SysDate.year=100;SysDate.year --;DS1302_DateSet(&SysDate);}if(setn == 2)//设置月{if(SysDate.mon == 1)SysDate.mon=13;SysDate.mon --;if((SysDate.mon==4)||(SysDate.mon==6)||(SysDate.mon==9)||(SysDate.mon==11)){if(SysDate.day>30)SysDate.day=1;}else{if(SysDate.mon==2){if(p_r==1){if(SysDate.day>29)SysDate.day=1;}else{if(SysDate.day>28)SysDate.day=1;}}}DS1302_DateSet(&SysDate);}if(setn == 3)//设置日{SysDate.day --;if((SysDate.mon==1)||(SysDate.mon==3)||(SysDate.mon==5)||(SysDate.mon==7)||(SysDate.mon==8)||(SysDate.mon==10)||(SysDate.mon==12)){if(SysDate.day==0)SysDate.day=31;}else{if(SysDate.mon==2){if(p_r==1){if(SysDate.day==0)SysDate.day=29;}else{if(SysDate.day==0)SysDate.day=28;}}else{if(SysDate.day==0)SysDate.day=30;}}DS1302_DateSet(&SysDate);}if(setn == 4)//设置星期{if(SysDate.week == 1)SysDate.week=8;SysDate.week --;DS1302_DateSet(&SysDate);}if(setn == 5)//设置时{if(SysDate.hour == 0)SysDate.hour=24;SysDate.hour --;DS1302_DateSet(&SysDate);}if(setn == 6)//设置分{if(SysDate.min == 0)SysDate.min=60;SysDate.min --;DS1302_DateSet(&SysDate);}if(setn == 7)//设置秒{if(SysDate.sec == 0)SysDate.sec=60;SysDate.sec --;DS1302_DateSet(&SysDate);}if((setn==8)&&(xinlvMin>0))xinlvMin--;if((setn==9)&&(xinlvMax-xinlvMin>1))xinlvMax--;if((setn==10)&&(spo2Min>0))spo2Min--;if((setn==11)&&(tempMin>0))tempMin--;if((setn==12)&&(tempMax-tempMin>1))tempMax--;}DisplaySetValue();}if(keynum==4&&page==0)//步数清零{bushu = 0;Store_Data();//存储数据}if(keynum==5 && setn == 0)//切换显示界面{page=!page;OLED_CLS();//清屏if(page==0){for(i=0;i<2;i++)OLED_ShowCN(i*16,4,i+16,1);//测试显示中文:心率for(i=0;i<2;i++)OLED_ShowCN(i*16+48,4,i+18,1);//测试显示中文:血氧for(i=0;i<2;i++)OLED_ShowCN(i*16+95,4,i+20,1);//测试显示中文:步数OLED_ShowCentigrade(112, 2);    //℃}else{for(i=0;i<2;i++)OLED_ShowCN(i*16,2,i+44,0);//显示中文:里程OLED_ShowChar(32,2,':',2,0);}}
}
void displayTimeCunt(void)  //显示定时时间
{if(page==1){if(setn==0){OLED_ShowChar(32,0,timeCountRecord/3600/10+'0',2,0);OLED_ShowChar(40,0,timeCountRecord/3600%10+'0',2,0);OLED_ShowChar(48,0,':',2,0);OLED_ShowChar(56,0,timeCountRecord%3600/60/10+'0',2,0);OLED_ShowChar(64,0,timeCountRecord%3600/60%10+'0',2,0);OLED_ShowChar(72,0,':',2,0);OLED_ShowChar(80,0,timeCountRecord%3600%60/10+'0',2,0);OLED_ShowChar(88,0,timeCountRecord%3600%60%10+'0',2,0);}else{if(setn<4){OLED_ShowChar(32,0,shi/10+'0',2,setn+1-1);OLED_ShowChar(40,0,shi%10+'0',2,setn+1-1);OLED_ShowChar(48,0,':',2,0);OLED_ShowChar(56,0,fen/10+'0',2,setn+1-2);OLED_ShowChar(64,0,fen%10+'0',2,setn+1-2);OLED_ShowChar(72,0,':',2,0);OLED_ShowChar(80,0,miao/10+'0',2,setn+1-3);OLED_ShowChar(88,0,miao%10+'0',2,setn+1-3);}}}
}
void UsartSendReceiveData(void)   //串口发送接收数据
{char *str1=0,*str2=0,i;int  setValue=0;char setvalue[4]={0};if(strlen(STM32_RX1_BUF) > 0){DelayMs(10);if(strstr(STM32_RX1_BUF,"setHeartMin:")!=NULL)    //接收到设置心率下限的指令{str1 = strstr(STM32_RX1_BUF,"setHeartMin:");while(*str1 < '0' || *str1 > '9')        //判断是不是0到9有效数字{str1 = str1 + 1;DelayMs(10);}i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == '\r')break;            //换行符,直接退出while循环DelayMs(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=300){xinlvMin = setValue;    //设置的心率下限DisplaySetValue();Store_Data();//存储数据}}if(strstr(STM32_RX1_BUF,"setHeartMax:")!=NULL)		//接收到设置心率上限的指令{str1 = strstr(STM32_RX1_BUF,"setHeartMax:");while(*str1 < '0' || *str1 > '9')        //判断是不是0到9有效数字{str1 = str1 + 1;DelayMs(10);}i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == '\r')break;            //换行符,直接退出while循环DelayMs(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=300){xinlvMax = setValue;    //设置的心率上限DisplaySetValue();Store_Data();//存储数据}}if(strstr(STM32_RX1_BUF,"setSpo2Min:")!=NULL)  //接收到设置血氧下限的指令{str1 = strstr(STM32_RX1_BUF,"setSpo2Min:");while(*str1 != ':')        //判断是不是0到9有效数字{str1 = str1 + 1;DelayMs(10);}str1 = str1 + 1;i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == '\r')break;            //换行符,直接退出while循环DelayMs(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=200){spo2Min = setValue;    //设置的血氧下限DisplaySetValue();Store_Data();//存储数据}}if(strstr(STM32_RX1_BUF,"setTempMin:")!=NULL)  //接收到设置温度下限的指令{str1 = strstr(STM32_RX1_BUF,"setTempMin:");while(*str1 < '0' || *str1 > '9')        //判断是不是0到9有效数字{str1 = str1 + 1;DelayMs(10);}i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == '.')break;            //换行符,直接退出while循环DelayMs(10);}if(*str1 == '.'){str1 = str1 + 1;}if(*str1 >= '0' && *str1 <= '9'){setvalue[i] = *str1;}i = i + 1;setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=999){tempMin = setValue;    //设置的温度下限DisplaySetValue();Store_Data();//存储数据}}if(strstr(STM32_RX1_BUF,"setTempMax:")!=NULL)  //接收到设置温度上限的指令{str1 = strstr(STM32_RX1_BUF,"setTempMax:");while(*str1 < '0' || *str1 > '9')        //判断是不是0到9有效数字{str1 = str1 + 1;DelayMs(10);}i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == '.')break;            //换行符,直接退出while循环DelayMs(10);}if(*str1 == '.'){str1 = str1 + 1;}if(*str1 >= '0' && *str1 <= '9'){setvalue[i] = *str1;}i = i + 1;setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=999){tempMax = setValue;    //设置的温度上限DisplaySetValue();Store_Data();//存储数据}}if(strstr(STM32_RX1_BUF,"setSteps:")!=NULL)  //接收到设置步长的指令{str1 = strstr(STM32_RX1_BUF,"setSteps:");while(*str1 < '0' || *str1 > '9')        //判断是不是0到9有效数字{str1 = str1 + 1;DelayMs(10);}i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == '\r')break;            //换行符,直接退出while循环DelayMs(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=200){bu_long = setValue;    //设置的步长DisplaySetValue();Store_Data();//存储数据}}if(strstr(STM32_RX1_BUF,"setMileage:")!=NULL)  //接收到设置里程的指令{str1 = strstr(STM32_RX1_BUF,"setMileage:");while(*str1 < '0' || *str1 > '9')        //判断是不是0到9有效数字{str1 = str1 + 1;DelayMs(10);}i = 0;while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == '.')break;            //换行符,直接退出while循环DelayMs(10);}if(*str1 == '.'){str1 = str1 + 1;}while(*str1 >= '0' && *str1 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str1;i ++; str1 ++;if(*str1 == '\r')break;            //换行符,直接退出while循环DelayMs(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=999){warnMileage = setValue*10;    //设置的提醒里程DisplaySetValue();Store_Data();//存储数据}}if(strstr(STM32_RX1_BUF,"warntime")!=NULL)  //接收到设置提醒时间的指令{press=1;BEEP = 1;DelayMs(80);BEEP = 0;str2 = strstr(STM32_RX1_BUF,"warntime");while(*str2 < '0' || *str2 > '9')        //判断是不是0到9有效数字{str2 = str2 + 1;DelayMs(10);}i = 0;while(*str2 >= '0' && *str2 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str2;i ++; str2 ++;if(*str2 == ':')break;DelayMs(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=99){shi = setValue;   //提醒时间的小时displayTimeCunt();}str2 = str2 + 1;i = 0;while(*str2 >= '0' && *str2 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str2;i ++; str2 ++;if(*str2 == ':')break;DelayMs(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=59){fen = setValue;   //提醒时间的分钟displayTimeCunt();}str2 = str2 + 1;i = 0;while(*str2 >= '0' && *str2 <= '9')        //判断是不是0到9有效数字{setvalue[i] = *str2;i ++; str2 ++;if(*str2 == '\r')break;DelayMs(10);}setvalue[i] = '\0';            //加上结尾符setValue = atoi(setvalue);if(setValue>=0 && setValue<=59){miao = setValue;   //提醒时间的秒displayTimeCunt();}}if(strstr(STM32_RX1_BUF,"stepsClear")!=NULL)   //收到步数清零指令{press=1;BEEP = 1;DelayMs(80);BEEP = 0;bushu = 0;Store_Data();  //存储数据}if(strstr(STM32_RX1_BUF,"mileageClear")!=NULL)  //收到里程清零指令{press=1;BEEP = 1;DelayMs(80);BEEP = 0;mileage=0;mileage_bushu=0;Store_Data(); //存储数据}if(strstr(STM32_RX1_BUF,"timeClear")!=NULL) //收到时间清零指令{press=1;BEEP = 1;DelayMs(80);BEEP = 0;timingReminder=0;beepFlag&=0xFD;startFlag=0;timeCountRecord=0;}if(strstr(STM32_RX1_BUF,"startTiming")!=NULL) //收到开始定时指令{press=1;BEEP = 1;DelayMs(80);BEEP = 0;startFlag=1;}if(strstr(STM32_RX1_BUF,"pauseTiming")!=NULL)//收到暂停定时指令{press=1;BEEP = 1;DelayMs(80);BEEP = 0;startFlag=0;}if(strstr(STM32_RX1_BUF,"offMileage")!=NULL)  //收到关闭里程提醒指令{press=1;BEEP = 1;DelayMs(80);BEEP = 0;mileageReminder=0;}if(strstr(STM32_RX1_BUF,"offTime")!=NULL)//收到关闭时间提醒指令{press=1;BEEP = 1;DelayMs(80);BEEP = 0;timingReminder=0;beepFlag&=0xFD;}memset(STM32_RX1_BUF, 0, STM32_RX1BUFF_SIZE);//清除缓存STM32_Rx1Counter = 0;}/* 蓝牙发送数据 */if(sendFlag==1){sendFlag = 0;printf("$Heartrate:%d#,$Spo2:%d#,$Temperature:%4.1f#,",hrAvg,spo2Avg,(float)temperature/10);printf("$Steps:%d#,$Mileage:%6.3f#,",bushu,(float)mileage/1000);printf("$Hour:%02d#,",(int)(timeCountRecord/3600));printf("$Min:%02d#,",(int)(timeCountRecord%3600/60));printf("$Sec:%02d#",(int)(timeCountRecord%3600%60));printf("send ok.");if(sendSetValueFlag==1){sendSetValueFlag=0;DelayMs(500);printf("$setHeartMin:%d#,",xinlvMin);printf("$setHeartMax:%d#,",xinlvMax);printf("$setSpo2Min:%d#,",spo2Min);printf("$setTempMin:%4.1f#,",(float)tempMin/10);printf("$setTempMax:%4.1f#,",(float)tempMax/10);printf("send test data.");printf("$setLength:%d#,",bu_long);printf("$setMileage:%5.2f#\r\n",(float)warnMileage/1000);}}
}
int main(void)
{unsigned char i;DelayInit();NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//设置NVIC中断分组2:2位抢占优先级,2位响应优先级KEY_Init(); //按键初始化DelayMs(200);I2C_Configuration(); //IIC初始化OLED_Init(); //OLED初始化CheckNewMcu();OLED_CLS();//清屏DS18B20_Init();DS1302_Init(&SysDate);uart1_Init(9600);DelayMs(100);for(i=0;i<8;i++)OLED_ShowCN(i*16,2,i+8,0);//测试显示中文:欢迎使用使能手环DelayMs(1000);OLED_CLS();//清屏DS1302_DateRead(&SysDate);//读时间OLED_CLS();//清屏for(i=0;i<2;i++)OLED_ShowCN(i*16,4,i+16,1);//测试显示中文:心率for(i=0;i<2;i++)OLED_ShowCN(i*16+48,4,i+18,1);//测试显示中文:血氧for(i=0;i<2;i++)OLED_ShowCN(i*16+95,4,i+20,1);//测试显示中文:步数OLED_ShowCentigrade(112, 2);    //℃IIC_init();//IIC初始化adxl345_init();//ADXL345初始化Init_MAX30102();//MAX30102初始化memset(STM32_RX1_BUF, 0, STM32_RX1BUFF_SIZE);//清除缓存STM32_Rx1Counter = 0;TIM2_Init(99,719);   //定时器初始化,定时1ms//Tout = ((arr+1)*(psc+1))/Tclk ;//Tclk:定时器输入频率(单位MHZ)//Tout:定时器溢出时间(单位us)while(1){shanshuo=!shanshuo;KeySettings();DisplayTime();displayTimeCunt();if(setn == 0)//不在设置状态下,读取相关数据{DisplayTemperature();GetSteps();GetHeartRateSpO2();}UsartSendReceiveData();DelayMs(10);}
}
void TIM2_IRQHandler(void)//定时器2中断服务程序,用于记录时间
{static u16 timeCount1 = 0;static u16 timeCount2 = 0;static u16 timeCount3 = 0;static u16 timeCount4 = 0;if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源{TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除中断标志位/*  蜂鸣器提醒优先级:跌倒 > 心率血氧温度报警 > 时间提醒 > 里程提醒  */if(timingReminder==1 && (!(beepFlag&0x01))) //时间提醒{timeCount1 ++;if(timeCount1==1)BEEP=1;if(timeCount1==100)BEEP=0;if(timeCount1>=1000){timeCount1=0;}}else{timeCount1=0;}timeCount2 ++;if(timeCount2 >= 1000)   //1s{timeCount2 = 0;if(startFlag==1){if(timeCountRecord<(98*3600+59*60)){timeCountRecord ++;          //时间计时}if(timeCountRecord==(shi*3600+fen*60+miao))//时间到了提醒标志置1{timingReminder=1;beepFlag|=0x02;}}sendFlag = 1;}timeCount3 ++;if(timeCount3 >= 100){timeCount3=0;if(((hrAvg!=0)&&(hrAvg>=xinlvMax||hrAvg<=xinlvMin))||((spo2Avg!=0)&&(spo2Avg<=spo2Min))||(temperature>=tempMax||temperature<=tempMin))//不在范围蜂鸣器报警{BEEP=~BEEP;beepFlag|=0x01;}else{beepFlag&=0xFE;if(timingReminder==0 && mileageReminder==0 && press==0)BEEP=0;if(mileage>=warnMileage)   //里程达标,提醒标志置1{if((beepFlag>>2)==0){beepFlag|=0x04;mileageReminder=1;}}else{beepFlag&=0xFB;mileageReminder=0;}}}timeCount4 ++;if(timeCount4>=50)  //50ms{static u8 BeepCount=0;timeCount4=0;if(mileageReminder==1 && (!(beepFlag&0x03)))   //里程到了蜂鸣器提醒{BeepCount++;if(BeepCount==3)BEEP=1;if(BeepCount==6)BEEP=0;if(BeepCount==9)BEEP=1;if(BeepCount==12)BEEP=0;if(BeepCount==15)BEEP=1;if(BeepCount==18)BEEP=0;if(BeepCount==40){BEEP=0;BeepCount=0;}}}}
}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询