功能介绍:
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;}}

仿真演示视频:
https://www.bilibili.com/video/BV1qB4y1j7Ki/

实物演示视频:
https://www.bilibili.com/video/BV1aP411J7uW/

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

  1. 基于51单片机的模拟心率电子脉搏器proteus仿真原理图PCB

    功能介绍: 0.本系统采用STC89C52作为单片机 1.系统可检测心率脉搏值,通过LCD1602液晶实时显示测量值 2.心率脉搏超过设定阈值,蜂鸣器将报警 3.四个功能按键可修改心率脉搏上下限阈值 ...

  2. 基于51单片机声音噪声分贝检测采集显示proteus仿真原理图PCB程序设计

    硬件设计 (末尾附文件) 功能说明: 1.基于STC89C51/52(与AT89S51/52.AT89C51/52通用)单片机作为主控制器 2.采用LCD1602液晶显示屏实时显示分贝值: 3.使用小 ...

  3. 基于51单片机的智能水表水流量计流量报警器proteus仿真原理图PCB

    功能: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶显示水流量/累计流量/累计流量阈值 2.按'清零'键清除累计流量,按'加''减'设置累计流量报警阈值,按'启停'启动停止水泵 3 ...

  4. 基于51单片机的智能蓝牙路灯街灯控制系统proteus仿真原理图PCB

    功能: 0.本系统采用STC89C52作为单片机 1.液晶实时显示时间/环境光强/工作模式 2.每隔5s向蓝牙串口发送一次信息 3.支持路灯故障检测 4.工作时间18~24时,两个路灯同时点亮,24时 ...

  5. 基于51单片机的水温温度PID算法控制系统proteus仿真原理图PCB

    1.本系统采用STC89C52作为单片机 2.采用液晶LCD1602液晶实时显示相关数据 3.采用矩阵键盘可设置PID相关参数 4.采用L298驱动功率电阻模拟加热过程 5.当温度超过设定值的一定范围 ...

  6. 基于51单片机的智能护眼台灯设计proteus仿真原理图PCB

    功能介绍: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示当前时间/环境光强/工作模式 2.当检测到人体距离灯光太近时,蜂鸣器报警提醒 3.当使用时间超过设定阈值时,蜂鸣器报 ...

  7. 基于51单片机的智能饮水机烧水控制系统proteus仿真原理图PCB

    功能介绍: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示当前温度和设定温度 2.当温度到达100℃时,蜂鸣器报警提醒水烧开了 3.按键可更改预设温度值,当温度低于设定温度5 ...

  8. 基于51单片机电子秤称重系统10kg量程proteus仿真原理图PCB

    功能: 1.本系统采用STC89C52作为单片机 2.本系统LCD1602液晶实时显示时间和当前重量 3.四个功能按键其中,按'设置'键进入时间设置,按'去皮'键实现去皮功能 4.系统设置有重量阈值, ...

  9. 基于51单片机太阳能风能太阳能风光互补路灯proteus仿真原理图PCB

    功能: 0.本系统采用STC89C52作为单片机 1.手动模式下,由手动开关控制小灯的亮灭 2.自动模式下,由光强决定小灯的亮灭 3.本系统具备太阳能和风能两种方式给系统的锂电池充电,锂电池再经过升压 ...

最新文章

  1. ubuntu chrome java插件_在Ubuntu中为Chrome安装Java插件
  2. [转]C++/CLI与C#常用语法对比
  3. 如何查看linux系统是32位还是64位
  4. 暴富、投机,金钱、欲望、人性,一个叫 Fomo3D的游戏正在刷新你的世界观
  5. 自制操作系统学习笔记(2)-汇编程序体验
  6. 【CV】OpenCV 入门之旅
  7. svn版利用什么技术实现_金葱粉涂料印花利用了什么技术?
  8. 电脑向linux服务器传输文件,windows如何通过ssh工具向linux服务器上传和下载文件?...
  9. apiDoc构建源代码注释的接口文档
  10. python3 在线加密_Python3对称加密算法AES、DES3实例详解
  11. Ubuntu16.04装机2:安装CUDA10.2+cuDNN7.6.5
  12. 4.数据结构 --- 串
  13. 26. Postpone variable definitions as long as possible
  14. [翻译]:Cinemachine 官方文档(0)
  15. 黑鲨重装计算机安装无法继续,示例黑鲨装机大师装机失败无法开机怎么办?
  16. (CPU)关于x86、x86_64/x64、amd64和arm64/aarch64
  17. 研究生期间论文发表经验总结
  18. dcn网络与公网_DCN网
  19. 计算机某浏览器设置主页地址,如何查看电脑中的浏览器主页是被什么软件修改的...
  20. java获取连续日期天数

热门文章

  1. 操作系统课程设计总结
  2. 收入与未来就业2—科技革命的力量
  3. 公爵 侯爵 伯爵 子爵 男爵
  4. matlab 绘制一分钟k线图,超短线分钟,1分钟k线图最佳买卖点
  5. 我的不客观,真体验之阿里云开发平台
  6. 2021年重庆奉节高考成绩查询,重庆市奉节中学2021招生计划
  7. nfs-ganesha使用
  8. 战略分析思路——商业模式拆解(1)
  9. 识别动物的软件,动物园碰到不认识的动物就用它
  10. C / C++ 以Dijkstra为基础求最短路径及行进路线 伪代码及源代码