1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 基于51单片机的跑步机心率计速度测量系统proteus仿真原理图PCB

基于51单片机的跑步机心率计速度测量系统proteus仿真原理图PCB

时间:2022-07-16 22:20:26

相关推荐

基于51单片机的跑步机心率计速度测量系统proteus仿真原理图PCB

功能介绍:

0.本系统采用STC89C52作为单片机

1.系统实现监测跑步者心率和跑步机速度并显示

2.可以设置跑步速度

3.当心率低于设定下限阈值时跑步机升高速度档位

4.当心率超过设定上限阈值时跑步机降低速度档位,同时蜂鸣器发出警报

5.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:

PCB :

主程序:

#include <reg52.h> //调用单片机头文件#include <intrins.h>#include <stdio.h>#include "lcd1602.h"#include "main.h"#define DIAMETER 20 //直径mmbit rekey; //按键标志bit startFlag = 0; //启动标志bit setFlag = 0; //设置标志unsigned char setIndex = 0;unsigned char datIndex = 0;unsigned int heartRateBuf[6] = {0}; //暂存心率值unsigned int heartRate = 0;unsigned int heartRateH = 120;unsigned int heartRateL = 60;unsigned char tab0[16]; //显示内容缓存unsigned char motorPWM = 1; //设定速度档位unsigned char realMotorPWM = 1; //真实速度档位unsigned int xdata pulseCnt = 0;unsigned int timeCnt = 0;bit dispFlag = 0; //更新显示标志bit updateFlag = 0; //更新心率标志bit refreshFlag = 0;/****************主函数***************/void main(){LED_GREEN = OFF;LED_RED = ON;BUZZER = OFF;EA = 0;Timer0_Init(); //初始化定时器Timer1_Init();Ext0_1_Init(); //外部中断0初始化程序LCD_Init(); //初始化液晶DelayMs(20); //延时有助于稳定LCD_Clear(); //清屏DelayMs(10);MOTOR_INA = 1;MOTOR_INB = 1;EA = 1;while (1){if (refreshFlag == 1) //刷新心率{EX0 = 0;TR0 = 0;refreshFlag = 0;heartRateBuf[datIndex] = timeCnt * 5; //算出间隔时间TH0 = 0xEE; //(65536 - 0.005*11059200/12 + 200) / 256TL0 = 0xC8; //(65536 - 0.005*11059200/12 + 200) % 256 5mstimeCnt = 0; //50ms计数清零datIndex++;if (datIndex > 3) //记录到超过等于2次时间{datIndex = 1; //计数从1开始updateFlag = 1; //测得4次开始显示}EX0 = 1;TR0 = 1;}if (dispFlag == 1) //更新显示标志置位{dispFlag = 0; //更新显示标志清零if (setFlag == 0){if (updateFlag == 0) //如果显示关 检测心率是否真实{heartRate = 0;}else //如果显示开{heartRate = 60000 / ((heartRateBuf[1]>>1) + (heartRateBuf[2]>>1)); //心率计算 2次求平均值}if (startFlag == 1) //跑步机启动情况下{if (heartRate > heartRateH) //心率超过阈值{realMotorPWM = motorPWM - 1; //速度档位降低1档//BUZZER = ON; //蜂鸣器报警}else if (heartRate < heartRateL){realMotorPWM = motorPWM + 1; //速度档位升高1档BUZZER = OFF;}else{realMotorPWM = motorPWM; //速度档位等于设定档位BUZZER = OFF;}}else{realMotorPWM = motorPWM; //速度档位等于设定档位BUZZER = OFF;}DelayMs(20);DispNormal();}}KeyProcess();}}/************************* 正常显示 *************************/void DispNormal(void){sprintf(tab0, "H:%3dbpm S%2d A%2d", heartRate, (int)motorPWM, (int)realMotorPWM); //显示心率和速度档位EA = 0;LCD_DispStr(0, 0, tab0); //显示心率EA = 1;sprintf(tab0, "Speed:%5.1fkm/h", (float)pulseCnt*3.6*3.14*DIAMETER/1000); //显示速度pulseCnt = 0;EA = 0;LCD_DispStr(0, 1, tab0); //显示转速EA = 1;}/************************* 显示设定心率上下限 *************************/void DispSetLimit(unsigned char setIndex){LCD_DispStr(0, 0, " Set Limit ");sprintf(tab0, " L:%3d H:%3d ", heartRateL, heartRateH); //显示心率上下限LCD_DispStr(0, 1, tab0); //显示心率switch (setIndex){case 1: LCD_SetCursor(6, 1, 1); break;case 2: LCD_SetCursor(13, 1, 1); break;default:;} }/************************* 按键处理 *************************/void KeyProcess(){if (KEY_SET == 0) //设置键按下{DelayMs(20);if (KEY_SET == 0) //设置键按下{if (setFlag == 0){setFlag = 1; //进入设置setIndex = 1;DispSetLimit(setIndex);}else{setIndex++; //切换设置位置DispSetLimit(setIndex);if (setIndex > 2){setFlag = 0;setIndex = 0;LCD_WriteCommand(0x0C, 0); //关闭闪烁}}}while (KEY_SET == 0);}if (KEY_ADD == 0) //加键按下{DelayMs(200);if (KEY_ADD == 0) //加键按下{if (setFlag == 0){if (motorPWM < 10){motorPWM++;}}else{if (setIndex == 1){heartRateL++;if (heartRateL >= heartRateH){heartRateL = 60;}}else if (setIndex == 2){heartRateH++;if (heartRateH > 140){heartRateH = heartRateL + 1;}}DispSetLimit(setIndex);}}}if (KEY_SUB == 0) //减键按下{DelayMs(200);if (KEY_SUB == 0) //减键按下{if (setFlag == 0){if (motorPWM > 1){motorPWM--;}}else{if (setIndex == 1){heartRateL--;if (heartRateL < 60){heartRateL = heartRateH - 1;}}else if (setIndex == 2){heartRateH--;if (heartRateH <= heartRateL){heartRateH = 140;}}DispSetLimit(setIndex);}}}if (KEY_SWITCH == 0) //启停{DelayMs(20);if (KEY_SWITCH == 0) //启停{startFlag = ~startFlag;if (startFlag == 1){LED_GREEN = ON;LED_RED = OFF; }else{LED_GREEN = OFF;LED_RED = ON; }}while (KEY_SWITCH == 0);}}/*************定时器初始化程序***************/void Timer0_Init(){TMOD &= 0xF0;TMOD |= 0x01; //定时器0工作方式1TH0 = 0xB8; //(65536 - 0.02*11059200/12) / 256TL0 = 0x00; //(65536 - 0.02*11059200/12) % 256 20ms//PT0 = 1; //设置高优先级ET0 = 1; //开定时器0中断TR0 = 1; //允许定时器0定时}void Timer1_Init() //定时器1初始化{TMOD &= 0x0F;TMOD |= 0x10;TL1 = 0x00;//设置定时初始值TH1 = 0xEE;//设置定时初始值 5msPT1 = 1; //设置高优先级ET1 = 1;TR1 = 1;}/***********外部中断0初始化程序****************/void Ext0_1_Init() //外部中断0和1初始化程序{IT0 = 1; //外部中断0负跳变中断IT1 = 1; //外部中断1负跳变中断PX0 = 1; //设置高优先级EX0 = 1; //允许外部中断0中断EX1 = 1; //允许外部中断0中断}void Ext0_Interrupt() interrupt 0{if (timeCnt < 80) //当连续两次检测时间间隔小于80*5ms=400ms不处理{TR0 = 1; //开定时器}else{refreshFlag = 1;}}/*************定时器0中断服务程序***************/void Timer0_Interrupt() interrupt 1{TH0 = 0xEE; //(65536 - 0.005*11059200/12 + 200) / 256TL0 = 0xC8; //(65536 - 0.005*11059200/12 + 200) % 256 5mstimeCnt++; //每5ms一次计数if (timeCnt > 250) //当超过25*50ms=1.5s没有检测到信号停止显示{datIndex = 0; //数据个数清零timeCnt = 0; //50ms计数清零updateFlag = 0; //显示关TR0 = 0;//定时器关}}void Ext1_Interrupt() interrupt 2{pulseCnt++;}void Timer1_Interrupt(void) interrupt 3{static unsigned int time5ms = 0;static unsigned char IN1Count = 0;TL1 = 0x00;//设置定时初始值TH1 = 0xEE;//设置定时初始值 5mstime5ms++;if (time5ms > 200) //定时1秒{time5ms = 0;dispFlag = 1; //更新数据标志置位}/************************* 电机PWM控制 *************************/if (startFlag == 1) //跑步机启动情况下{IN1Count++;if (IN1Count > realMotorPWM+15) //关闭时间段{MOTOR_INA = 1; //关闭}else if (IN1Count <= realMotorPWM+15) //占空比调节{MOTOR_INA = 0; //开启}if (IN1Count > 10+15){IN1Count = 0; //一个周期结束}}else{MOTOR_INA = 1;}}

仿真演示视频:

/video/BV1qB4y1j7Ki/

实物演示视频:

/video/BV1aP411J7uW/

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。