这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是
基于STM32单片机的智能手环设计与实现
学长这里给一个题目综合评分(每项满分5分)
选题指导, 项目分享:
https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md
本次是基于STM32单片机的简易蓝牙手环,手指放在心率检测处,心率传感器就能实时的检测使用者的心率的变化,并在显示屏上进行显示;通过DS18B20检测体温,体温数值也会在显示屏上进行显示;通过震动传感器进行震动采集,每个震动的变化会被系统认为步数的变化,进而实现计步的目的。通过蓝牙模块可以将采集的数据上传到手机端的蓝牙APP内进行显示。
手指放在心率传感器上可检测心跳
两根手指捏住体温传感器可测试体温
翻转晃动机体,可改变步数
DS18B20数字温度计提供9位温度读数。信息经过单线接口送入或送出DS18B20传感器,因此从中央处理器到DS18B20仅需要提供电源以及一根数据线,就可以工作。
(1) 数据线拉到低电平“0”。
(2) 延时480微妙(该时间的时间范围可以从480到960微妙)。
(3) 数据线拉到高电平“1”。
(4) 延时等待80微妙。如果初始化成功则在15到60微妙时间内产生一个由DS18B20所返回的低电平“0”.根据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时判断。
(5) 若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第3步的时间算起)最少要480微妙。
(1) 将数据线拉低“0”。
(2) 延时1微妙。
(3) 将数据线拉高“1”,释放总线准备读数据。
(4) 延时10微妙。 //等待数据稳定
(5) 读数据线的状态得到1个状态位,并进行数据处理。
(6) 延时45微妙。
(7) 重复1~7步骤,直到读完一个字节。
(1) 数据线先置低电平“0”
(2) 延时15微妙。
(3) 按从低位到高位的顺序发送数据(一次只发送一位)。
(4) 延时60微妙。
(5) 将数据线拉到高电平。
(6) 重复1~5步骤,直到发送完整的字节。
(7) 最后将数据线拉高。
传感器参数
传感器原理
原理:没有震动时,震动轴静止,导针A和导针B处于导通状态,平时任何角度开关都是接通状态,受到振动或移动时,震动轴会产生移动或振动,从而导致导针A和B会出现断开。
这种开关的特点是平时一般处于导通状态耐振动时会短暂断开,所以它的灵敏度很高,同时没有震动时电路导通,所以他是常闭式震动传感器。
注意这里是传感器的原理,不是模块的原理,下面是SW-420振动传感器模块的原理
简介
它是汇承公司出品的一个蓝牙主从机一体可用作无线串口透传通讯的模块。
原理图
相关参数讲解
6根引脚,名称与功能如下;
通讯方式(tx、rx)
HC-05通过TX和RX引脚,支持使用标准AT命令。为此,用户必须在设备启动时进入特殊命令模式。启动进入数据模式,这样它就可以与其他设备进行无线通信
常见的AT指令
AT指令不区分大小写,但是都要以回车符结尾,下面是常用的AT指令
/*******************************************************************************
* 函 数 名 : DS18B20_Check
* 函数功能 : 检测DS18B20是否存在
* 输 入 : 无
* 输 出 : 1:未检测到DS18B20的存在,0:存在
*******************************************************************************/
u8 DS18B20_Check(void)
{
u8 retry=0;
DS18B20_IO_IN();//SET PG11 INPUT
while (DS18B20_DQ_IN&&retry<200)
{
retry++;
delay_us(1);
};
if(retry>=200)
return 1;
else
retry=0;
while (!DS18B20_DQ_IN&&retry<240)
{
retry++;
delay_us(1);
};
if(retry>=240)
return 1;
return 0;
}
/*******************************************************************************
* 函 数 名 : DS18B20_Read_Bit
* 函数功能 : 从DS18B20读取一个位
* 输 入 : 无
* 输 出 : 1/0
*******************************************************************************/
u8 DS18B20_Read_Bit(void) // read one bit
{
u8 data;
DS18B20_IO_OUT();//SET PG11 OUTPUT
DS18B20_DQ_OUT=0;
delay_us(2);
DS18B20_DQ_OUT=1;
DS18B20_IO_IN();//SET PG11 INPUT
delay_us(12);
if(DS18B20_DQ_IN)
data=1;
else
data=0;
delay_us(50);
return data;
}
/*******************************************************************************
* 函 数 名 : DS18B20_Read_Byte
* 函数功能 : 从DS18B20读取一个字节
* 输 入 : 无
* 输 出 : 一个字节数据
*******************************************************************************/
u8 DS18B20_Read_Byte(void) // read one byte
{
u8 i,j,dat;
dat=0;
for (i=1;i<=8;i++)
{
j=DS18B20_Read_Bit();
dat=(j<<7)|(dat>>1);
}
return dat;
}
/*******************************************************************************
* 函 数 名 : DS18B20_Write_Byte
* 函数功能 : 写一个字节到DS18B20
* 输 入 : dat:要写入的字节
* 输 出 : 无
*******************************************************************************/
void DS18B20_Write_Byte(u8 dat)
{
u8 j;
u8 testb;
DS18B20_IO_OUT();//SET PG11 OUTPUT;
for (j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if (testb)
{
DS18B20_DQ_OUT=0;// Write 1
delay_us(2);
DS18B20_DQ_OUT=1;
delay_us(60);
}
else
{
DS18B20_DQ_OUT=0;// Write 0
delay_us(60);
DS18B20_DQ_OUT=1;
delay_us(2);
}
}
}
/**
* 函数功能: SW420震动模块传感器IO引脚初始化.
* 输入参数: 无
* 返 回 值: 无
* 说 明:引脚进行初始化
*
*/
void SW420_GPIO_Init(void)
{
/* 定义IO硬件初始化结构体变量 */
GPIO_InitTypeDef GPIO_InitStruct;
/* 使能(开启)SW420引脚对应IO端口时钟 */
SW420_RCC_CLK_ENABLE();
/* 设定SW420对应引脚IO编号 */
GPIO_InitStruct.Pin = SW420_GPIO_PIN;
/* 设定SW420对应引脚IO操作速度*/
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
/* 设定SW420对应引脚IO为浮空输入模式 */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
/* 初始化SW420对应引脚IO */
HAL_GPIO_Init(SW420_GPIO, &GPIO_InitStruct);
}
/**
* 函数功能: 简单粗暴的延时函数
* 输入参数: time;延时时间设置
* 返 回 值: 无
* 说 明:软件消抖
*/
static void SW420_ScanDelay(void)
{
uint32_t i,j;
for(i=0;i<100;++i)
for(j=0;j<1000;++j){ }
}
/**
* 函数功能: 读取引脚的状态
* 输入参数:无
* 返 回 值: SW420_HIGH:有震动;
* SW420_LOW:无震动
* 说 明:无。
*/
SW420_State_TypeDef SW420_StateRead(void)
{
/* 读取模块输出信号,若此时输出的是高电平 ,则进入下一步判断*/
if(HAL_GPIO_ReadPin(SW420_GPIO,SW420_GPIO_PIN)==SW420_ACTIVE_LEVEL)
{
/* 延时一小段时间,消除抖动 */
SW420_ScanDelay();
/* 延时时间后再来判断引脚状态,如果还是高电平那么确实就是高电平 */
if(HAL_GPIO_ReadPin(SW420_GPIO,SW420_GPIO_PIN)==SW420_ACTIVE_LEVEL)
{
/* 扫描完毕,确定有震动,返回震动状态(高电平) */
return SW420_HIGH;
}
}
/* 无震动,返回无震动状态 */
return SW420_LOW;
}
//查角色
u8 HC05_Get_Role(void)
{
u8 retry=0x0a;
u8 temp,t;
while(retry--)
{
HC05_KEY=1;
delay_ms(5);
u3_printf("AT+ROLE?\r\n");
for(t=0;t<15;t++)//次循环用于等待hc05相应
{
delay_ms(10);
if(USART3_RX_STA&0X8000)break;
}
HC05_KEY=0;
if(USART3_RX_STA&0x8000)
{
temp=USART3_RX_STA&0x7fff;
USART3_RX_STA=0;
if(temp==13&&USART3_RX_BUF[0]=='+')//接收到正确的应答了
{
temp=USART3_RX_BUF[6]-'0';
break;
}
}
}
if(retry==0)temp=0xff;
return temp;
}