基于STC89C52单片机+PulseSensor完成心率检测显示|环球今日报

1126626497   2023-06-07 23:39:30


(资料图片仅供参考)

一、设计介绍

当前基于STC89C52单片机和PCF8591、PulseSensor心率传感器、SSD1306 OLED显示屏等元件实现了一个心率检测仪。检测仪可以通过采集心率传感器输出的模拟信号,并经过AD转换后计算出实时的心率值,然后将心率值通过IIC协议传输到OLED显示屏上进行展示。用户只需要将心率传感器固定在身体上,启动心率检测仪,就能够方便地实时监测自己的心率。

本项目的应用范围广泛,可以用于健康管理、健身锻炼、医疗等领域。在家庭中,人们可以使用该心率检测仪,及时监测自己的心率,对身体健康进行有效管理和控制;在健身房或健身教练中心,教练可以利用该心率检测仪来监测运动员的心率变化,以便针对性地调整训练计划,提高训练效果;在医疗机构中,医护人员可以使用该心率检测仪,监测患者的心率情况,及时发现异常情况,为患者的治疗提供有力的依据和参考。

二、硬件选型

本项目需要用到的硬件:

STC89C52单片机:作为主控芯片,负责读取PulseSensor心率传感器的模拟信号、进行AD转换、计算心率值,并将心率值通过IIC协议传输到OLED显示屏上进行展示。PCF8591模块:用于实现STC89C52单片机通过IIC总线对PulseSensor心率传感器进行数据采集和AD转换。PulseSensor心率传感器:用于采集人体的微弱心跳信号,并将信号输出到PCF8591模块。SSD1306 OLED显示屏:用于显示心率检测结果,包括心率值及单位。杜邦线、面包板:用于连接各个硬件模块和搭建电路原型。

三、实现代码

下面是项目核心代码,通过PCF8591接PulseSensor心率传感器采集心率,并通过IIC协议的0.96寸OLED显示屏显示出来:

#include < reg52.h > #include < intrins.h > ​ #define uchar unsigned char #define uint unsigned int ​ sbit SCL = P1^0; sbit SDA = P1^1; sbit LED = P2^0; ​ #define ADDR_PCF8591    0x90    // PCF8591的IIC地址:1001 0000 #define CMD_PCF8591_WR  0x40    // PCF8591写数据命令字:0100 CCCC,CCCC为通道选择 #define CMD_PCF8591_RD  0x41    // PCF8591读数据命令字:0100 CCCC,CCCC为通道选择 ​ #define ADDR_OLED       0x78    // SSD1306 OLED显示屏的IIC地址:0111 1000 ​ uchar heartRate[3];             // 存储心率值的字符串 ​ /**  * 延时函数,控制IIC通信速度  */ void Delay() {     uint i, j;     for(i=0; i< 50; i++)         for(j=0; j< 500; j++); } ​ /**  * IIC启动信号  */ void IIC_Start() {     SCL = 1;     SDA = 1;     Delay();     SDA = 0;     Delay();     SCL = 0; } ​ /**  * IIC停止信号  */ void IIC_Stop() {     SCL = 0;     SDA = 0;     Delay();     SCL = 1;     SDA = 1;     Delay(); } ​ /**  * IIC发送一个字节的数据  * @parambyte发送的字节  * @return 接收到的应答位  */ uchar IIC_SendByte(uchar byte) {     uchar i, ack; ​     for(i=0; i< 8; i++)     {         SDA = (bit)(byte & 0x80);         byte < <= 1;         Delay();         SCL = 1;         Delay();         SCL = 0;     } ​     SDA = 1;     Delay();     SCL = 1;     Delay();     ack = SDA;     SCL = 0; ​     return ack; } ​ /**  * 初始化PCF8591模块  */ void Init_PCF8591() {     IIC_Start();     IIC_SendByte(ADDR_PCF8591);     IIC_SendByte(CMD_PCF8591_WR | 0);     IIC_Stop(); } ​ /**  * 读取PCF8591的AD值  * @param ch 选择的通道编号  * @return AD转换后的数值  */ uchar Read_PCF8591(uchar ch) {     uchar value; ​     IIC_Start();     IIC_SendByte(ADDR_PCF8591);     IIC_SendByte(CMD_PCF8591_WR | ch);     IIC_Stop(); ​     IIC_Start();     IIC_SendByte(ADDR_PCF8591 | 0x01);     value = IIC_SendByte(0xFF);     IIC_Stop(); ​     return value; } ​ /**  * 初始化SSD1306 OLED显示屏  */ void Init_OLED() {     IIC_Start();     IIC_SendByte(ADDR_OLED);     IIC_SendByte(0xAE);     // 关闭显示     IIC_SendByte(0x00);     // 列地址低4位     IIC_SendByte(0x10);     // 列地址高4位     IIC_SendByte(0x40);     // 起始行地址     IIC_SendByte(0xB0);     // 设置页地址     IIC_SendByte(0x81);     // 对比度设置命令     IIC_SendByte(0xCF);     // 对比度值     IIC_SendByte(0xA1);     // 段复用设置     IIC_SendByte(0xA6);     // 常规显示模式     IIC_SendByte(0xA8);     // 多路复用设置     IIC_SendByte(0x3F);     // 页面数-1     IIC_SendByte(0xC8);     // 扫描方式设置     IIC_SendByte(0xD3);     // 设置显示偏移     IIC_SendByte(0x00);     IIC_SendByte(0xD5);     // 频率设置命令     IIC_SendByte(0x80);     // 分频系数     IIC_SendByte(0xD9);     // 设置预充电周期     IIC_SendByte(0xF1);     IIC_SendByte(0xDA);     // 设置COM硬件连接方式     IIC_SendByte(0x12);     IIC_SendByte(0xDB);     // VCOMH设置     IIC_SendByte(0x40);     IIC_SendByte(0xA4);     // 全部点亮/正常显示     IIC_SendByte(0xA6);     // 正常/反显示控制     IIC_SendByte(0xAF);     // 开启显示     IIC_Stop(); } ​ /**  * 在OLED上显示字符串  * @param x 开始列地址  * @param y 开始页地址  * @param str 需要显示的字符串  */ void ShowString_OLED(uchar x, uchar y, uchar *str) {     uchar i = 0; ​     IIC_Start();     IIC_SendByte(ADDR_OLED);     IIC_SendByte(0x00);     // 列地址低4位     IIC_SendByte(0x10);     // 列地址高4位     IIC_SendByte(0xB0 + y);// 设置页地址     for(i=0; str[i]!="\\0"; i++)     {         IIC_SendByte(0xB0 + y);         IIC_SendByte((x + 8*i) & 0x0F);         IIC_SendByte(((x + 8*i) > > 4) | 0x10);         IIC_SendByte(str[i]);     }     IIC_Stop(); } ​ /**  * 主函数,心率计算和显示  */ void main() {     Init_PCF8591();     // 初始化PCF8591模块     Init_OLED();        // 初始化OLED显示屏 ​     while(1)     {         uchar adValue = Read_PCF8591(0); // 读取PCF8591的AD值         uint timeInterval = 100;         // 设定采集心率的时间间隔,单位为毫秒         uint count = 0;                  // 统计脉搏跳动次数的计数器         uint heartRateValue = 0;         // 计算得出的心率值 ​         for (uint i=0; i< timeInterval; i++)  // 在一定时间内采集数据         {             if (adValue > 200)          // 当AD值高于阈值时,统计脉搏跳动次数             {                 count++;                 while(adValue > 100)    // 等待一段时间,避免同一次脉搏被重复计数                 {                     adValue = Read_PCF8591(0);                 }             }             adValue = Read_PCF8591(0);  // 读取下一个AD值         } ​         heartRateValue = (uint)(count * 60.0 / timeInterval);  // 计算心率值         sprintf(heartRate, "%d", heartRateValue);              // 将心率值转换为字符串 ​         ShowString_OLED(0, 0, "Heart Rate:");     // 在OLED上显示标题         ShowString_OLED(80, 0, heartRate);       // 在OLED上显示心率值         ShowString_OLED(96, 0, "bpm");           // 在OLED上显示单位     } }

审核编辑:汤梓红

相关新闻