首页 > 编程语言 >基于STM32的人体健康管理系统Proteus仿真+源码

基于STM32的人体健康管理系统Proteus仿真+源码

时间:2024-11-23 21:32:27浏览次数:8  
标签:10 ds1302 read DS1302 STM32 源码 GPIO Proteus data

一、功能介绍

1.心率实时检测,心率数值显示在LCD1602屏幕上

2.利用超声波测量身高,显示在LCD1602屏幕上

3.通过ADC读取体重,通过计算BMI指数,给出肥胖指数,显示在LCD1602屏幕上

4.DS1302读取年月日和实时时间,显示在LCD1602屏幕上

5.心率阈值可以通过按键修改,DS1302的年月日和时间都可以通过按键设置

6.设计了LCD1602的多级菜单,通过按键翻页,选择功能,增强交互性

二、设计软件

程序采用Keil5编写,重点代码都有详细注释,容易理解。仿真用Proteus绘制。

三、原理图

仿真图

1.芯片采用STM32F103R6

2.心率和体重通过电位器模拟

3.按键采用硬件消抖

三、软件讲解

1.RTC部分


#include "DS1302.h"

extern char DS1302_start_Data[7]={0x24,0x04,0x19,0x14,0x00,0x00,0x07};//年月日时分秒周
struct TIMEData TimeData;
char read_time[7];
char DS1302_data_1[10];
char DS1302_data_2[8];
 
void ds1302_gpio_init()//CE,SCLK端口初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PC.11  CE
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOC.11
GPIO_ResetBits(GPIOB,GPIO_Pin_2); 
 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //PC.12  SCLK
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOC.12
GPIO_ResetBits(GPIOB,GPIO_Pin_3); 
}
 
void ds1302_DATAOUT_init()//配置双向I/O端口为输出态
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //PC.10  DATA
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOC.10
GPIO_ResetBits(GPIOB,GPIO_Pin_4);
}
 
void ds1302_DATAINPUT_init()//配置双向I/O端口为输入态
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //PC.10 DATA
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOC.10
}
 
 
void ds1302_write_onebyte(unsigned char data)//向DS1302发送一字节数据
{
	unsigned char count=0;
ds1302_DATAOUT_init();
SCLK_L;
for(count=0;count<8;count++)
	{	SCLK_L;
		if(data&0x01)
		{DATA_H;}
		else{DATA_L;}//先准备好数据再发送
		SCLK_H;//拉高时钟线,发送数据
		data>>=1;
	}
}
 
void ds1302_wirte_rig(unsigned char address,unsigned char data)//向指定寄存器地址发送数据
{
unsigned char temp1=address;
unsigned char temp2=data;
CE_L;SCLK_L;Delay_us(1);
CE_H;Delay_us(2);
ds1302_write_onebyte(temp1);
ds1302_write_onebyte(temp2);
CE_L;SCLK_L;Delay_us(2);
}
 
unsigned char ds1302_read_rig(unsigned char address)//从指定地址读取一字节数据
{
unsigned char temp3=address;
unsigned char count=0;
unsigned char return_data=0x00;
CE_L;SCLK_L;Delay_us(3);
CE_H;Delay_us(3);
ds1302_write_onebyte(temp3);
ds1302_DATAINPUT_init();//配置I/O口为输入
Delay_us(2);
for(count=0;count<8;count++)
	{
	Delay_us(2);//使电平持续一段时间
	return_data>>=1;
	SCLK_H;Delay_us(4);//使高电平持续一段时间
	SCLK_L;Delay_us(14);//延时14us后再去读取电压,更加准确
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_4))
	{return_data=return_data|0x80;}
	
	}
Delay_us(2);
CE_L;DATA_L;
return return_data;
}
 


 
 
void ds1302_init()
{
ds1302_wirte_rig(0x8e,0x00);//关闭写保护
ds1302_wirte_rig(0x80,DS1302_start_Data[5]);//seconds 
ds1302_wirte_rig(0x82,DS1302_start_Data[4]);//minutes 
ds1302_wirte_rig(0x84,DS1302_start_Data[3]);//hours   
ds1302_wirte_rig(0x86,DS1302_start_Data[2]);//date  
ds1302_wirte_rig(0x88,DS1302_start_Data[1]);//months  
ds1302_wirte_rig(0x8a,DS1302_start_Data[6]);//days    
ds1302_wirte_rig(0x8c,DS1302_start_Data[0]);//year    
ds1302_wirte_rig(0x8e,0x80);//关闭写保护
}

 
void ds1302_read_time()
{
read_time[0]=ds1302_read_rig(0x81);//读秒
read_time[1]=ds1302_read_rig(0x83);//读分
read_time[2]=ds1302_read_rig(0x85);//读时
read_time[3]=ds1302_read_rig(0x87);//读日
read_time[4]=ds1302_read_rig(0x89);//读月
read_time[5]=ds1302_read_rig(0x8B);//读星期
read_time[6]=ds1302_read_rig(0x8D);//读年
}
 
void ds1302_read_realTime()
{
ds1302_read_time();  //BCD码转换为10进制
TimeData.second=(read_time[0]>>4)*10+(read_time[0]&0x0f);
TimeData.minute=((read_time[1]>>4)&(0x07))*10+(read_time[1]&0x0f);
TimeData.hour=(read_time[2]>>4)*10+(read_time[2]&0x0f);
TimeData.day=(read_time[3]>>4)*10+(read_time[3]&0x0f);
TimeData.month=(read_time[4]>>4)*10+(read_time[4]&0x0f);
TimeData.week=read_time[5];
TimeData.year=(read_time[6]>>4)*10+(read_time[6]&0x0f)+2000;
	DS1302_data_1[0]='2';
	DS1302_data_1[1]='0';
	DS1302_data_1[2]='0'+(TimeData.year-2000)/10;
	DS1302_data_1[3]='0'+(TimeData.year-2000)%10;
	DS1302_data_1[4]='-';
	DS1302_data_1[5]='0'+TimeData.month/10;
	DS1302_data_1[6]='0'+TimeData.month%10;
	DS1302_data_1[7]='-';
	DS1302_data_1[8]='0'+TimeData.day/10;
	DS1302_data_1[9]='0'+TimeData.day%10;
	
	DS1302_data_2[0]='0'+TimeData.hour/10;
	DS1302_data_2[1]='0'+TimeData.hour%10;
	DS1302_data_2[2]=':';
	DS1302_data_2[3]='0'+TimeData.minute/10;
	DS1302_data_2[4]='0'+TimeData.minute%10;
	DS1302_data_2[5]=':';
	DS1302_data_2[6]='0'+TimeData.second/10;
	DS1302_data_2[7]='0'+TimeData.second%10;
}



年月日时分秒封装在数组里,方便修改
在这里插入图片描述

2.多级界面部分代码

*-----------开机动画---------------*/
void StartMenu(void)
{
	WrString1602(0,"The BMI Health"); 	
}
/*------------------------------------*/
/*-----------界面2:各项数据显示页---------------*/
void SubmenuTwo(void)  //数据页面
{
	WrByte1602(0,7,' '); //消影
	WrByte1602(1,7,' '); //消影
	WrByte1602(1,8,' '); //消影

	WrByte1602(0,0,'B'); 
	WrByte1602(0,1,'M'); 
	WrByte1602(0,2,'I'); 
	WrByte1602(0,3,'='); 
	WrByte1602(1,0,'H'); 
	WrByte1602(1,1,'='); 
	WrByte1602(1,5,'C'); 
	WrByte1602(1,6,'M');
	WrByte1602(1,9,'W'); 
	WrByte1602(1,10,'=');
	WrByte1602(1,14,'K');
	WrByte1602(0,8,'P');
	WrByte1602(0,9,'=');
	WrByte1602(1,15,'G');WrByte1602(1,11,AsciiCode[temp1%1000/100]);	//显示体重百位
	WrByte1602(1,12,AsciiCode[temp1%100/10]);//显示体重十位
	WrByte1602(1,13,AsciiCode[temp1%10]);//显示体重个位

	WrByte1602(1,2,AsciiCode[UltrasonicWave_Distance%256/100]);//显示身高百位
	WrByte1602(1,3,AsciiCode[UltrasonicWave_Distance%256%100/10]);//身高十位
	WrByte1602(1,4,AsciiCode[UltrasonicWave_Distance%256%10]); 	//身高个位  

	bmi=temp1*10000/((UltrasonicWave_Distance%256)*(UltrasonicWave_Distance%256));//BMI值=体重/(身高*身高)


	WrByte1602(0,4,AsciiCode[bmi%1000/100]);	//显示BMI百位
	WrByte1602(0,5,AsciiCode[bmi%100/10]);//显示BMI十位
	WrByte1602(0,6,AsciiCode[bmi%10]);//显示BMI个位	
	
	WrByte1602(0,10,AsciiCode[temp2%1000/100]);	//显示脉搏百位
	WrByte1602(0,11,AsciiCode[temp2%100/10]);//显示脉搏十位
	WrByte1602(0,12,AsciiCode[temp2%10]);//显示脉搏个位	
	
}
/*-------------------------------------------------------*/

三、演示效果

BMI 界面

在这里插入图片描述

阈值修改界面

在这里插入图片描述

RTC界面

在这里插入图片描述

标签:10,ds1302,read,DS1302,STM32,源码,GPIO,Proteus,data
From: https://blog.csdn.net/weixin_44842222/article/details/143998470

相关文章