5♥☆基于STM32的智能手环√★☆

Posted 行走的皮卡丘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5♥☆基于STM32的智能手环√★☆相关的知识,希望对你有一定的参考价值。

5、♥☆基于STM32的智能手环√★☆💙💙

Introduction

With the development of society, people’s material living standards are improving day by day, and people are paying more and more attention to their health. As a measuring instrument, the pedometer can calculate the number of walking steps and the energy consumed, so people can quantitatively formulate exercise programs to exercise, and analyze the health of the human body according to the running situation, so it is becoming more and more popular. The handheld electronic pedometer is designed to meet market demand and is simple and convenient to use.

引言

随着社会的发展,人们的物质生活水平日渐提高,人们也越来越关注自己的健康。计步器作为一种测量仪器,可以计算行走的步数和消耗的能量,所以人们可以定量的制定运动方案来健身,并根据运行情况来分析人体的健康状况,因而越发流行。手持式的电子计步器是适应市场需求的设计,使用起来简单方便。

1、系统概述

1.1、设计任务

用STM32设计一个智能手环。

1.2、设计要求

  • (1)具有准确的计步功能;

  • (2)能够检测心率;

  • (3)能够检测环境和人体温度;

  • (4)所有数据在屏幕上显示出来。

2、 方案设计与论证

2.1、芯片选择方案

stm32是一个低功耗,高性能32位单片机,片内含4k Bytes ISP(In-system programmable)的可反复擦写1000次的Flash只读程序存储器。主要性能有:与MCS-51单片机产品兼容、全静态操作:0Hz~33Hz、 三级加密程序存储器、32个可编程I/O口线、三个16位定时器/计数器、八个中断源、全双工UART串行通道、掉电后中断可唤醒、看门狗定时器、双数据指针、掉电标识符、易编程。

2.2 系统概述

计步器是一种颇受欢迎的日常锻炼进度监控器,可以激励人们挑战自己,增强体质,帮助瘦身。早期设计利用加重的机械开关检测步伐,并带有一个简单的计数器。晃动这些装置时,可以听到有一个金属球来回滑动,或者一个摆锤左右摆动敲击挡块。电子计步器主要组成部分是振动传感器和电子计数器。步行的时候人的重心会上下移动。以腰部的上下位移最为明显,所以记步器挂在腰带上最为适宜。所谓的振动传感器其实就是一个平衡锤在上下振动时平衡被破坏使一个触点能出现通/断动作,由电子计数器完成了主要的记录与显示功能,其他的属于热量消耗,路程换算均由电路完成。计步器中一般采用一种加速度计来感受外界的震动。常用的加速度计原理如下:在一段塑料管中密封着一小块磁铁,管外缠绕着线圈,当塑料管运动时,磁铁由于惯性在管中反向运动,切割线圈,由于电磁感应,线圈中产生电流,人体运动时,上下起伏的加速度近似为正弦过程,线圈的输出电流也是正弦波,测量正弦波的频率就可以得出运动的步数,再计算的出距离。

心率(Heart Rate)是用来描述心动周期的专业术语,是指心脏每分钟跳动的次数,以第一声音为准。 心率,现代汉语将心率解释为“心脏跳动的频率”。频率就是在单位时间内,某件事情发生的次数。两种解释合起来就是,心脏在一定时间内跳动的次数,也就是在一定时间内,心脏跳动快慢的意思。

健康成人的心率为60~100次/分,大多数为60~80次/分,女性稍快;3岁以下的小儿常在100次/分以上;老年人偏慢。成人每分钟心率超过100次(一般不超过 160次/分)或婴幼儿超过 150次/分者,称为窦性心动过速。常见于正常人运动、兴奋、激动、吸烟、饮酒和喝浓茶后。也可见于发热、休克、贫血、甲亢、心力衰竭及应用阿托品肾上腺素麻黄素等。如果心率在 160~220次/分,常称为阵发性心动过速。心率低于60次/分者(一般在40次/分以上),称为窦性心动过缓。可见于长期从事重体力劳动和运动员;病理性的见于甲状腺机能低下、颅内压增高阻塞性黄疸、以及洋地黄、奎尼丁心得安类药物过量或中毒。如心率低于40次/分,应考虑有房室传导阻滞

基于此,本设计选择研发一种将步数和心率连接一体的智能手环。

2.3、设计要求

  • (1)具有准确的计步功能;

  • (2)能够检测心率;

  • (3)能够检测环境和人体温度;

  • (4)所有数据在屏幕上显示出来

2.4、系统总体设计思路

  • (1)、通过重力加速度传感器ADXL345检测人的状态,计算出走路步数、走路距离和平均速度。

  • (2)、通过心率传感器实时检测心率,通过温度传感器检测温度。

  • (3)、lcd1602实时显示步数、距离和平均速度、心率以及温度值。

2.5、各功能模块程序实现原理分析

本设计由STM32F103C8T6单片机核心板电路+ADXL345传感器电路+心率传感器电路+温度传感器+lcd1602电路组成。

  • 1、通过重力加速度传感器ADXL345检测人的状态,计算出走路步数、走路距离和平均速度。

  • 2、通过心率传感器实时检测心率,通过温度传感器检测温度。

  • 3、lcd1602实时显示步数、距离和平均速度、心率以及温度值。

    本系统具体框图如下图所示:

2.5.1、LCD1602液晶显示模块电路设计

LCD显示器分为字段显示和字符显示两种。其中字段显示与LED显示相似,只要送对应的信号到相应的管脚就能显示。字符显示是根据需要显示基本字符。本设计采用的是字符型显示。系统中采用LCD1602作为显示器件输出信息。与传统的LED数码管显示器件相比,液晶显示模块具有体积小、功耗低、显示内容丰富等优点,而且不需要外加驱动电路,现在液晶显示模块已经是单片机应用设计中最常用的显示器件了。LCD1602可以显示2行16个汉字。

2.5.2、ADXL345倾角传感器模块电路设计

本设计选择倾角传感器ADXL345模块实时检测相关的状态信息。ADXL345是一款小而薄的超低功耗3轴加速度计,分辨率高(13位),测量范围达± 16g。数字输出数据为16位二进制补码格式,可通过SPI(3线或4线)或I2C数字接口访问。ADXL345非常适合移动设备应用。它可以在倾斜检测应用中测量静态重力加速度,还可以测量运动或冲击导致的动态加速度。其高分辨率(3.9mg/LSB),能够测量不到1.0°的倾斜角度变化。该器件提供多种特殊检测功能。活动和非活动检测功能通过比较任意轴上的加速度与用户设置的阈值来检测有无运动发生。敲击检测功能可以检测任意方向的单振和双振动作。自由落体检测功能可以检测器件是否正在掉落。这些功能可以独立映射到两个中断输出引脚中的一个。正在申请专利的集成式存储器管理系统采用一个32级先进先出(FIFO)缓冲器,可用于存储数据,从而将主机处理器负荷降至最低,并降低整体系统功耗。低功耗模式支持基于运动的智能电源管理,从而以极低的功耗进行阈值感测和运动加速度测量。

2.5.3、Pulsesensor脉搏心率传感器模块电路设计

脉搏心率传感器是用来测试心跳速率的传感器,实质是一款集成了放大电路和噪声消除电路的光学心率传感器。可以通过此传感器开发出和心率有关的互动作品。传感器可以戴在手指或者耳垂上。光电传感器将脉搏信号转换为电信号,此装置需要把手指放在传感器表盘上,光电传感器,此传感器是集成了放大电路和噪声消除电路的光学心率传感器,光电传感器一侧的发光二极管发光,当脉搏跳动时,指尖或者耳垂的动脉血管血容量发生周期性变化,透过指尖的光强度同时发生变化。另一侧的光电三极管将接收到的红外光信号转化为电信号。

2.5.4、DS18B20温度传感器模块电路设计

DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。

3、STM32性能介绍及硬件设计

3.1 STM32单片机性能介绍

STM32它拥有的资源包括:48KB SRAM、256KB FLASH、2 个基本定时器、4 个通用定时器、2个高级定时器、2个DMA 控制器(共 12 个通道)、3 个SPI、2个IIC、5个串口、1个USB、1个CAN、3个12位ADC、1个12位DAC、1个SDIO接口及51 个通用IO口,该芯片性价比极高。

各个引脚说明如下

  • PA0 作用1,按键 KEY_UP 2,可以做待机唤醒脚(WKUP) 3,可以接 DS18B20 传感器接口(P2 设置)

  • PA1作用1,NRF24L01 接口 IRQ 信号 2,接 HS0038 红外接收头(P2 设置)

  • PA2 作用 作为W25Q64 的片选信号

  • PA3 作用 作为SD 卡接口的片选脚

  • PA4 作用 作为NRF24L01 接口的 CE 信号

  • PA5 作用 作为W25Q64、SD 卡和 NRF24L01 接口的 SCK 信号

  • PA6 作用 作为 W25Q64、SD 卡和 NRF24L01 接口的 MISO 信号

  • PA7 作用 作为 W25Q64、SD 卡和 NRF24L01 接口的 MOSI 信号

  • PA8 作用 作为 接 DS0 LED 灯(红色)

  • PA9 作用 作为串口 1 TX 脚,默认连接 CH340 的 RX(P4 设置)

  • PA10 作用 作为串口 1 RX 脚,默认连接 CH340 的 TX(P4 设置)

  • PA11 作用 作为接 USB D-引脚

  • PA12 作用 作为接 USB D+引脚

  • PA13作用 作为JTAG/SWD 仿真接口,没接任何外设

  • PA14 作用 作为JTAG/SWD 仿真接口,没接任何外设

  • PA15 作用 作为1,JTAG 仿真口(JTDI) 2,PS/2 接口的 CLK 信号 3,接按键 KEY1

3.2、智能手环系统硬件设计

该程序所需要的主电路图,温度检测模块电路图,计步模块电路图,心率传感器模块电路图LCD外部接线图依次如下图所示:

4、 系统程序

4.1、主程序设计流程图

4.2、 主程序内容

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include <stdio.h>
#include "timer.h"
#include "key.h"
#include "exti.h"
#include "adxl345.h"
#include "lcd1602.h"
#include "ds18b20.h" 

unsigned char ReadAdxl345;	   //定时读取adxl345数据
unsigned char ErrorNum=0;   //记录错误次数
unsigned char CheckNum=0;   //检测次数
	  
char dis0[16];//液晶数组显示暂存
char dis1[35];

unsigned int xlTab[5];//心率数组
unsigned char count=0;	//心率滤波计数
unsigned int xinLater=0;//	心率延时处理
unsigned int xinLv =0;    //心率值

unsigned int BuShu=0;//步数
unsigned int Normal_num=0;			//正常次数
unsigned int Error_num=0;			//倾斜次数

unsigned int disBuShu = 0;  //显示步数
float disJuLi = 0;//显示距离
float temperature;  //温度
unsigned char readTemp = 0;	//读取温度标志

int main(void)
{ 
    delay_init();	    	 //延时函数初始化	  
    uart_init(9600);	 	//串口初始化为9600
    TIM3_Int_Init(49,7199);//50ms  	
    EXTIX_Init();		// 初始化外部中断
    LED_Init();		  		//初始化与LED连接的硬件接口
    KEY_Init();			//初始化按键
    Lcd_GPIO_init();  //初始化lcd引脚
    Lcd_Init();		  //初始化lcd屏幕
    delay_ms(200);

    Init_ADXL345();
    if(Single_Read_ADXL345(0X00)==0xe5)	
    {
        delay_ms(5);
    }
    else
    {
        delay_ms(3);
    }
    while(1)
    {
        if(ReadAdxl345== 1)   //定时读取adxl345数据
        {
            ReadAdxl345= 0;
            ReadData_x();  						//三轴检测函数
            CheckNum++;
            if((temp_Y>450)||(temp_Y<-450)) //查看正常次数     
            {
                Normal_num++;  //正常次数++
            }
            else
            {
                Error_num++;//倾斜次数
            }
            if((Error_num!=0)&&(Normal_num!=0))//检测到步数
            {
                BuShu++;   //步数脉冲量++
                Error_num=0;    //清除一个周期检测
                Normal_num=0;
            }
        }
        if(disFlag==1)	   //显示标志
        {
            disFlag = 0;
            readTemp++;  //定时计数
            if(readTemp >= 8)//约800ms处理一次数据 温度
            {
                readTemp =0;//重新计数
                temperature=(float)DS18B20_Get_Temp()/10;	//缩小10倍为实际值			
            }
            disBuShu = BuShu/2;  //显示步数
            disJuLi = disBuShu*0.45;//显示距离
            sprintf(dis0,"X:%03d/min %4.1f C",xinLv,temperature);//打印
            Lcd_Puts(0,0,(unsigned char *)dis0);	//显示
            Lcd_1Put(14,0,0xdf);//显示符号
            sprintf(dis1,"BS:%03d JL:%4.1fm  ",disBuShu,disJuLi);//打印
            Lcd_Puts(0,1,(unsigned char *)dis1);	//显示

        }	
    }											    
}	

4.3、ADXL345倾角传感器

#include "stm32f10x.h"
#include "delay.h"
#include "adxl345.h"

#define SDA_RCC			RCC_APB2Periph_GPIOA
#define SDA_GPIO		GPIOA
#define SDA_GPIO_PIN	GPIO_Pin_5

#define SCL_RCC			RCC_APB2Periph_GPIOA
#define SCL_GPIO		GPIOA
#define SCL_GPIO_PIN	GPIO_Pin_4

#define SCL_OUT() SCL_Set_Output() //置位scl
#define SET_SCL() GPIO_SetBits(SCL_GPIO, SCL_GPIO_PIN) //置位scl
#define CLE_SCL() GPIO_ResetBits(SCL_GPIO, SCL_GPIO_PIN)//清楚scl
                    
#define SDA_OUT() SDA_Set_Output()
#define SDA_INT() SDA_Set_Input()
#define SET_SDA() GPIO_SetBits(SDA_GPIO, SDA_GPIO_PIN)//置位sda
#define CLE_SDA() GPIO_ResetBits(SDA_GPIO, SDA_GPIO_PIN)//清楚sda
#define SDA_VAL() GPIO_ReadInputDataBit(SDA_GPIO, SDA_GPIO_PIN)

#define	SlaveAddress   0xA6   //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改                  //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A

unsigned char BUF[8];                         //接收数据缓存区      	
unsigned char ge,shi,bai,qian,wan;           //显示变量
unsigned char err;
float temp_X,temp_Y,temp_Z;

void SCL_Set_Output(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = SCL_GPIO_PIN;				 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 
	GPIO_Init(SCL_GPIO, &GPIO_InitStructure);					 					
}	

void SDA_Set_Output(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = SDA_GPIO_PIN;				 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 
	GPIO_Init(SDA_GPIO, &GPIO_InitStructure);					 					
}	

void SDA_Set_Input(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = SDA_GPIO_PIN;				 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 		 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 
	GPIO_Init(SDA_GPIO, &GPIO_InitStructure);					 
}

/**************************************
起始信号
**************************************/
void ADXL345_Start(void)
{
    SCL_OUT();
    SDA_OUT();
    SET_SDA();//SDA = 1;                    //拉高数据线
    SET_SCL();//SCL = 1;                    //拉高时钟线
    delay_us(2);//Delay5us();                 //延时
    CLE_SDA();//SDA = 0;                    //产生下降沿
    delay_us(2);//Delay5us();                 //延时
    CLE_SCL();//SCL = 0;                    //拉低时钟线
}

/**************************************
停止信号
**************************************/
void ADXL345_Stop(void)
{
    SCL_OUT();
    SDA_OUT();
    CLE_SDA();//SDA = 0;                    //拉低数据线
    SET_SCL();//SCL = 1;                    //拉高时钟线
    delay_us(2);//Delay5us();                 //延时
    SET_SDA();//SDA = 1;                    //产生上升沿
    delay_us(2);//Delay5us();                 //延时
    CLE_SCL();
}

/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void ADXL345_SendACK(uchar ack)
{   
    SCL_OUT();
    SDA_OUT();
    if(ack==0)//SDA = ack;                  //写应答信号
    {
      CLE_SDA();
    }
    else
    {
      SET_SDA();
    }
    SET_SCL();//SCL = 1;                    //拉高时钟线
    delay_us(2);//Delay5us();                 //延时
    CLE_SCL();//SCL = 0;                    //拉低时钟线
    delay_us(5);//Delay5us();                 //延时
}
/**************************************
接收应答信号
**************************************/
uchar ADXL345_RecvACK(void)
{
    SDA_INT();
    SCL_OUT();
    SET_SCL();//SCL = 1;                    //拉高时钟线
    delay_us(2);//    Delay5us();                 //延时
    SET_SCL();
    if(SDA_VAL()== Bit_SET)   //CY = SDA;                   //读应答信号
    {
        err = 1;
    }
    else
    {
        err = 0;
    }
    CLE_SCL() ;//SCL = 0;                    //拉低时钟线
    delay_us(5);//    Delay5us();                 //延时
    SDA_OUT();
    return err;
}

/**************************************
向IIC总线发送一个字节数据
**************************************/
void ADXL345_SendByte(unsigned char dat)
{
    unsigned char i;
    SCL_OUT();
    SDA_OUT();
    for (i=0; i<8; i++)         //8位计数器
    {
        delay_us(5);             //延时
        if(dat&0x80)  //SDA = CY;               //送数据口
        {SET_SDA();}
        else
        {CLE_SDA();}       
        delay_us(5);             //延时
        SET_SCL();//SCL = 1;                //拉高时钟线
        delay_us(5);             //延时
        CLE_SCL();//SCL = 0;                //拉低时钟线
        dat <<= 1;              //移出数据的最高位
    }
    ADXL345_RecvACK();
}
/**************************************
从IIC总线接收一个字节数据
**************************************/
unsigned char ADXL345_RecvByte(void)
{
    unsigned char i;
    unsigned char Mid;
    unsigned char dat = 0;
    SDA_INT();
    SCL_OUT();

    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;
        delay_us(5);            //延时
        SET_SCL();

        if(SDA_VAL()== Bit_SET)   //CY = SDA;                   //读应答信号
        {
            Mid = 1;
        }
        else
        {
            Mid = 0;
        }
        if(Mid) dat++;
        delay_us(5);     
        CLE_SCL();//SCL = 0;                //拉低时钟线
    }
    return dat;
}

//******单字节写入*******************************************

void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
{
    ADXL345_Start();                  毕业设计 - 基于单片机的智能手环 -计步器 嵌入式 物联网 stm32

基于STM32单片机项目设计目录-加油吧√

基于STM32单片机项目设计目录-加油吧√

基于STM32跑步路径记录

基于STM32设计的云端健康管理系统(采用阿里云物联网平台)

基于STM32设计的云端健康管理系统(采用阿里云物联网平台)