STC89C52单片机电路+ADXL345加速度传感器+DS1302时钟芯片+心率检测模块电路+LCD1602
2018-722、51手环设计-ADXL345-LCD1602-心率-DS1302-BELL
本设计由STC89C52单片机电路+ADXL345加速度传感器+DS1302时钟芯片+心率检测模块电路+LCD1602液晶显示电路+电源电路组成。
1、通过ADXL345检测步数。
2、通过DS1302检测时间。
3、通过心率传感器检测心率。
4、将步数、时间和心率实时显示在液晶LCD1602上。
5、通过蓝牙模块将步数、时间和心率实时上传到手机APP。
6、通过手机APP可以校准时间。
串口更新时间命令:*2017061218235501# (位数必须正好)
表示:2017年06月12日18时23分55秒 周01
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<stdio.h>
#include "delay.h"
#include "1602.h"
#include "ds1302.h"
#include "adxl345.h"
#include "math.h"
unsigned char i_i=0,timecount=0,displayOK=0,rate=0,aa=0;//心率变换参数
unsigned int time[6]={0}; //心率6次采集
unsigned char xdata dis0[16];//定义显示区域临时存储数组
unsigned char xdata dis1[16];
unsigned char update_flag =0; //更新标志
unsigned long xdata time_50ms=0;//定时计数
unsigned char xdata time_buf2[17]; //更新时间变量
unsigned char SetFlag =0; //时间设置标志
unsigned char i;
unsigned int buShu=0; //步数
unsigned char ReadAdxl345; //定时读取adxl345
unsigned char sendNum = 0;//发送计数
xdata unsigned char firstin =0; //首次接收到标志
xdata unsigned char tab[20]; //串口数据暂存
xdata unsigned char Count=0; //串口接收计数
xdata unsigned char uartbusy =0; //串口判忙
void Init_Timer0(void); //函数声明
void init_int0(void);
void UART_Init(void);
void uartSendStr(unsigned char *s,unsigned char length);
void uartSendByte(unsigned char dat);
void BuShuCheck(void);
void TIM2Inital(void);
/****************主函数***************/
void main()
{
EX0=1; //允许外部中断0中断
EA=1; //开总中断
IT0 = 1; //外部中断0负跳变中断
Init_Timer0(); //初始化定时器
TIM2Inital();
UART_Init();
LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear(); //清屏
DelayMs(50);
Init_ADXL345();
if(Single_Read_ADXL345(0X00)==0xe5) //读出的数据为0XE5,表示正确
{
DelayMs(5);
}
else
{
DelayMs(3);
}
Ds1302_Init();
Ds1302_Read_Time();//读取时间参数
sprintf(dis0,"Now:%3d/min",(unsigned int)rate);
LCD_Write_String(0,0,dis0); //显示心率
sprintf(dis1,"%02d:%02d:%02d BS:%3d",(int)time_buf1[4],(int)time_buf1[5],(int)time_buf1[6],buShu);//时分秒
LCD_Write_String(0,1,dis1);//显示时间
uartSendStr("ready ok !",10);
while(1)
{
BuShuCheck(); //检测步数
if(displayOK==0)//如果显示关 检测心率是否真实
{
rate = 0;
}
else//如果显示开
{
rate=60000/(time[1]/5+time[2]/5+time[3]/5+time[4]/5+time[5]/5); //心率计算 5次求平均值
}
}
}
void BuShuCheck(void)
{
static unsigned int ErrorNum=0;
static unsigned int NormalNum=0;
if(ReadAdxl345==1) //定时读取adxl345数据
{
ReadAdxl345=0;
ReadData_x();
if((temp_X<650)||(abs(temp_Y)>400)) //查看正常次数
{
ErrorNum++;
}
else
{NormalNum++;}
if((NormalNum!=0)&&(ErrorNum!=0)) // 从角度判断走了一步
{
ErrorNum=0;
NormalNum=0;
buShu++;
}
}
}
/*************定时器0初始化程序***************/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
// TH0=(65536-20000)/256; //重新赋值 20ms
// TL0=(65536-20000)%256;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
void int0() interrupt 0
{
EX0=0;//暂时关外部中断
if(timecount<8) //当连续两次检测时间间隔小于8*50ms=400ms不处理
{
TR0=1;//开定时器
}
else
{
time[i_i]=timecount*50+TH0*0.256+TL0/1000;//算出间隔时间
TH0 = 0x3c;
TL0 = 0xb0; // 50ms 12M
timecount=0;//50ms计数清零
i_i++;
if(i_i==6)//记录到超过等于6次时间
{
i_i=1;//计数从1开始
displayOK=1; //测得5次开始显示?
}
}
EX0=1;
}
/*************定时器0中断服务程序***************/
void time0_int() interrupt 1
{
TH0 = 0x3c;
TL0 = 0xb0; // 50ms 12M
timecount++;//每50ms一次计数
if(timecount>65) //当超过25*50ms=1.5s没有检测到信号停止显示
{
i_i=0;//数据个数清零
timecount=0;//50ms计数清零
displayOK=0;//显示关
TR0=0;//定时器关
TH0 = 0x3c;
TL0 = 0xb0; // 50ms 12M
}
}
void TIM2Inital(void)
{
RCAP2H = (65536-60000)/256;//晶振12M 60ms 16bit 自动重载
RCAP2L = (65536-60000)%256;
ET2=1; //打开定时器中断
EA=1; //打开总中断
TR2=1; //打开定时器开关
}
void TIM2(void) interrupt 5 using 1//定时器2中断
{
TF2=0;
time_50ms++;
ReadAdxl345 =1;
if(time_50ms%2==0)
{
update_flag=1;
}
if(uartbusy>0) //串口数据采集处理
{uartbusy--;}
else
{
firstin =0;
Count=0;
}
}
void UART_Init(void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TL1 = TH1;
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
void uartSendByte(unsigned char dat)
{
unsigned char time_out;
time_out=0x00;
SBUF = dat; //将数据放入SBUF中
while((!TI)&&(time_out<100)) //检测是否发送出去
{time_out++;DelayUs2x(10);} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
void uartSendStr(unsigned char *s,unsigned char length)
{
unsigned char NUM;
NUM=0x00;
while(NUM<length) //发送长度对比
{
uartSendByte(*s); //放松单字节数据
s++; //指针++
NUM++; //下一个++
}
}
void UART_SER (void) interrupt 4 //串行中断服务程序
{
unsigned char r_buf;
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
r_buf = SBUF;
uartbusy = 10;
if(r_buf=='*') //接收到起始标志
{
firstin = 1; //接收标志成功
Count = 0;
tab[Count++]=r_buf;
}
else if(firstin == 1) //接收到其实标志成功
{
tab[Count++]=r_buf;
if((Count>=18)&&(tab[17] == '#'))
{
for(i=0;i<16;i++)
{
time_buf2[i]=tab[1+i]&0x0F;
}
SetFlag=1 ;
firstin =0;
Count=0;
}
}
}
if(TI) //如果是发送标志位,清零
TI=0;
}
资料下载地址