1602液晶显示51单片机电子脉搏器程序

畅学单片机 2021-02-23 00:00

脉搏器的传感器采用的是光电红外发射和接收的传感器,检测人体内血流动时对光的透过率或反射率不同而将其转换成电信号,电信号经过LM358进行信号放大,滤波电路,比较电路,后经过单片机处理,再显示出来,手指放在红外传感器处两秒内读出脉搏,按键是设置脉搏最高警报值和最低警报值,电位器是用于灵敏度调节的,因为每个人的手指厚度都不同,所以检测时需要调节到比较合适的灵敏度。

#include "reg52.h"

#include "intrins.h" // 包含头文件

#define uint unsigned int

#define uchar unsigned char

#define ulong unsigned long //宏定义

#define LCD_DATA P0 //定义P0口为LCD_DATA

sbit LCD_RS =P2^5;

sbit LCD_RW =P2^6;

sbit LCD_E =P2^7; //定义LCD控制引脚

sbit Xintiao =P1^0 ; //脉搏检测输入端定义

sbit speaker =P2^4; //蜂鸣器引脚定义

void delay5ms(void); //误差 0us

void LCD_WriteData(uchar LCD_1602_DATA);

void LCD_WriteCom(uchar LCD_1602_COM);

void lcd_1602_word(uchar Adress_Com,uchar Num_Adat,uchar *Adress_Data);

void InitLcd();//液晶初始化函数

void Tim_Init();

uchar Xintiao_Change=0; //

uint Xintiao_Jishu;

uchar stop;

uchar View_Data[3];

uchar View_L[3];

uchar View_H[3];

uchar Xintiao_H=100; //脉搏上限

uchar Xintiao_L=40; //脉搏下限

uchar Key_Change;

uchar Key_Value; //按键键值

uchar View_Con; //设置的位(0正常工作,1设置上限,2设置下限)

uchar View_Change;

void main() //主函数

{

InitLcd();

Tim_Init();

lcd_1602_word(0x80,16,"Heart Rate: "); //初始化显示

TR0=1;

TR1=1; //打开定时器

while(1) //进入循环

{

if(Key_Change) //有按键按下并已经得出键值

{

Key_Change=0; //将按键使能变量清零,等待下次按键按下

View_Change=1;

switch(Key_Value) //判断键值

{

case 1: //设置键按下

{

View_Con++; //设置的位加

if(View_Con==3) //都设置好后将此变量清零

View_Con=0;

break; //跳出,下同

}

case 2: //加键按下

{

if(View_Con==2) //判断是设置上限

{

if(Xintiao_H

Xintiao_H++; //上限+

}

if(View_Con==1) //如果是设置下限

{

if(Xintiao_L

Xintiao_L++; //下限值加

}

break;

}

case 3: //减键按下

{

if(View_Con==2) //设置上限

{

if(Xintiao_H>Xintiao_L+1)//上限数据大于下限+1(同样上限值不能小于下限)

Xintiao_H--; //上限数据减

}

if(View_Con==1) //设置下限

{

if(Xintiao_L>30) //下限数据大于30时

Xintiao_L--; //下限数据减

}

break;

}

}

}

if(View_Change)//开始显示变量

{

View_Change=0;//变量清零

if(stop==0) //心率正常时

{

if(View_Data[0]==0x30) //最高位为0时不显示

View_Data[0]=' ';

}

else //心率不正常(计数超过5000,也就是两次信号时间超过5s)不显示数据

{

View_Data[0]=' ';

View_Data[1]=' ';

View_Data[2]=' ';

}

switch(View_Con)

{

case 0: //正常显示

{

lcd_1602_word(0x80,16,"Heart Rate: ");//显示一行数据

lcd_1602_word(0xc0,16," ");//显示第二行数据

lcd_1602_word(0xcd,3,View_Data); //第二行显示心率

break;

}

case 1: //设置下限时显示

{

lcd_1602_word(0x80,16,"Heart Rate: ");//第一行显示心率

lcd_1602_word(0x8d,3,View_Data);

View_L[0]=Xintiao_L/100+0x30; //将下限数据拆字

View_L[1]=Xintiao_L0/10+0x30;

View_L[2]=Xintiao_L+0x30;

if(View_L[0]==0x30) //最高位为0时,不显示

View_L[0]=' ';

lcd_1602_word(0xC0,16,"Warning L : ");//第二行显示下限数据

lcd_1602_word(0xCd,3,View_L);

break;

}

case 2: //设置上限时显示(同上)

{

lcd_1602_word(0x80,16,"Heart Rate: ");

lcd_1602_word(0x8d,3,View_Data);

View_H[0]=Xintiao_H/100+0x30;

View_H[1]=Xintiao_H0/10+0x30;

View_H[2]=Xintiao_H+0x30;

if(View_H[0]==0x30)

View_H[0]=' ';

lcd_1602_word(0xC0,16,"Warning H : ");

lcd_1602_word(0xCd,3,View_H);

break;

}

}

}

}

}

void Time1() interrupt 3 //定时器1服务函数

{

static uchar Key_Con,Xintiao_Con;

TH1=0xd8; //10ms

TL1=0xf0; //重新赋初值

switch(Key_Con) //无按键按下时此值为0

{

case 0: //每10ms扫描此处

{

if((P3&0x07)!=0x07)//扫描按键是否有按下

{

Key_Con++; //有按下此值加1,值为1

}

break;

}

case 1: //10ms后二次进入中断后扫描此处(Key_Con为1)

{

if((P3&0x07)!=0x07)//第二次进入中断时,按键仍然是按下(起到按键延时去抖的作用)

{

Key_Con++; //变量加1,值为2

switch(P3&0x07) //判断是哪个按键按下

{

case 0x06:Key_Value=1;break; //判断好按键后将键值赋值给变量Key_Value

case 0x05:Key_Value=2;break;

case 0x03:Key_Value=3;break;

}

}

else //如果10ms时没有检测到按键按下(按下时间过短)

{

Key_Con=0; //变量清零,重新检测按键

}

break;

}

case 2: //20ms后检测按键

{

if((P3&0x07)==0x07) //检测按键是否还是按下状态

{

Key_Change=1; //有按键按下使能变量,(此变量为1时才会处理键值数据)

Key_Con=0; //变量清零,等待下次有按键按下

}

break;

}

}

switch (Xintiao_Con)//此处与上面按键的检测类似

{

case 0: //默认Xintiao_Con是为0的

{

if(!Xintiao)//每10ms(上面的定时器)检测一次脉搏是否有信号

{

Xintiao_Con++;//如果有信号,变量加一,程序就会往下走了

}

break;

}

case 1:

{

if(!Xintiao) //每过10ms检测一下信号是否还存在

{

Xintiao_Con++;//存在就加一

}

else

{

Xintiao_Con=0;//如果不存在了,检测时间很短,说明检测到的不是脉搏信号,可能是其他干扰,将变量清零,跳出此次检测

}

break;

}

case 2:

{

if(!Xintiao)

{

Xintiao_Con++;//存在就加一

}

else

{

Xintiao_Con=0;//如果不存在了,检测时间很短,说明检测到的不是脉搏信号,可能是其他干扰,将变量清零,跳出此次检测

}

break;

}

case 3:

{

if(!Xintiao)

{

Xintiao_Con++;//存在就加一

}

else

{

Xintiao_Con=0;//如果不存在了,检测时间很短,说明检测到的不是脉搏信号,可能是其他干扰,将变量清零,跳出此次检测

}

break;

}

case 4:

{

if(Xintiao)//超过30ms一直有信号,判定此次是脉搏信号,执行以下程序

{

if(Xintiao_Change==1)//心率计原理为检测两次脉冲间隔时间计算心率,变量Xintiao_Change第一次脉冲时为0的,所有走下面的else,第二次走这里

{

View_Data[0]=(60000/Xintiao_Jishu)/100+0x30;

View_Data[1]=(60000/Xintiao_Jishu)0/10+0x30;

View_Data[2]=(60000/Xintiao_Jishu)+0x30;

if(((60000/Xintiao_Jishu)>=Xintiao_H)||((60000/Xintiao_Jishu)

speaker=0; //蜂鸣器响

else

speaker=1; //不响

View_Change=1; //计算出心率后启动显示

Xintiao_Jishu=0; //心跳计数清零

Xintiao_Change=0; //计算出心率后该变量清零,准备下次检测心率

stop=0; //计算出心率后stop清零

}

else//第一次脉冲时Xintiao_Change为0

{

Xintiao_Jishu=0; //脉冲计时变量清零,开始计时

Xintiao_Change=1;//Xintiao_Change置1,准备第二次检测到脉冲时计算心率

}

Xintiao_Con=0; //清零,准备检测下一次脉冲

break;

}

}

}

}

void Time0() interrupt 1

{

TH0=0xfc; //1ms

TL0=0x18; //重新赋初值

Xintiao_Jishu++; //心跳计数加

if(Xintiao_Jishu==5000)//心跳计数大于5000

{

Xintiao_Jishu=0; //数据清零

View_Change=1; //显示位置1

Xintiao_Change=0; //置零,准备再次检测

stop=1; //心跳计数超过5000后说明心率不正常或者没有测出,stop置1

speaker=1; //关闭蜂鸣器

}

}

void Tim_Init()

{

EA=1; //打开中断总开关

ET0=1; //打开T0中断允许开关

ET1=1; //打开T1中断允许开关

TMOD=0x11; //设定定时器状态

TH0=0xfc; //1ms

TL0=0x18; //赋初值

TH1=0xd8; //10ms

TL1=0xf0; //赋初值

}

void lcd_1602_word(uchar Adress_Com,uchar Num_Adat,uchar *Adress_Data)

{

uchar a=0;

uchar Data_Word;

LCD_WriteCom(Adress_Com); //选中地址

for(a=0;a

{

Data_Word=*Adress_Data; //读取字符串数据

LCD_WriteData(Data_Word); //显示字符串

Adress_Data++; //显示地址加一

}

}

void LCD_WriteData(uchar LCD_1602_DATA)

{

delay5ms(); //操作前短暂延时,保证信号稳定

LCD_E=0;

LCD_RS=1;

LCD_RW=0;

_nop_();

LCD_E=1;

LCD_DATA=LCD_1602_DATA;

LCD_E=0;

LCD_RS=0;

}

void LCD_WriteCom(uchar LCD_1602_COM)

{

delay5ms();//操作前短暂延时,保证信号稳定

LCD_E=0;

LCD_RS=0;

LCD_RW=0;

_nop_();

LCD_E=1;

LCD_DATA=LCD_1602_COM;

LCD_E=0;

LCD_RS=0;

}

void InitLcd() //初始化液晶函数

{

delay5ms();

delay5ms();

LCD_WriteCom(0x38); //display mode

LCD_WriteCom(0x38); //display mode

LCD_WriteCom(0x38); //display mode

LCD_WriteCom(0x06); //显示光标移动位置

LCD_WriteCom(0x0c); //显示开及光标设置

LCD_WriteCom(0x01); //显示清屏

delay5ms();

delay5ms();

}

void delay5ms(void) //5ms延时函数

{

unsigned char a,b;

for(b=185;b>0;b--)

for(a=12;a>0;a--);

}

为了方便大家更好的学习,您还可以关注畅学电子和EDA的公众号,每天推送相关知识,希望能对你的学习有所帮助!

畅学单片机 以单片机为核心,带你全面了解和单片机相关的知识技巧,经验心得。关注我们,一起来学习吧!
评论
  • 在当前人工智能(AI)与物联网(IoT)的快速发展趋势下,各行各业的数字转型与自动化进程正以惊人的速度持续进行。如今企业在设计与营运技术系统时所面临的挑战不仅是技术本身,更包含硬件设施、第三方软件及配件等复杂的外部因素。然而这些系统往往讲究更精密的设计与高稳定性,哪怕是任何一个小小的问题,都可能对整体业务运作造成严重影响。 POS应用环境与客户需求以本次分享的客户个案为例,该客户是一家全球领先的信息技术服务与数字解决方案提供商,遭遇到一个由他们所开发的POS机(Point of Sal
    百佳泰测试实验室 2025-01-09 17:35 79浏览
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2025-01-09 09:58 63浏览
  • 1月7日-10日,2025年国际消费电子产品展览会(CES 2025)盛大举行,广和通发布Fibocom AI Stack,赋智千行百业端侧应用。Fibocom AI Stack提供集高性能模组、AI工具链、高性能推理引擎、海量模型、支持与服务一体化的端侧AI解决方案,帮助智能设备快速实现AI能力商用。为适应不同端侧场景的应用,AI Stack具备海量端侧AI模型及行业端侧模型,基于不同等级算力的芯片平台或模组,Fibocom AI Stack可将TensorFlow、PyTorch、ONNX、
    物吾悟小通 2025-01-08 18:17 72浏览
  • 故障现象一辆2017款东风风神AX7车,搭载DFMA14T发动机,累计行驶里程约为13.7万km。该车冷起动后怠速运转正常,热机后怠速运转不稳,组合仪表上的发动机转速表指针上下轻微抖动。 故障诊断 用故障检测仪检测,发动机控制单元中无故障代码存储;读取发动机数据流,发现进气歧管绝对压力波动明显,有时能达到69 kPa,明显偏高,推断可能的原因有:进气系统漏气;进气歧管绝对压力传感器信号失真;发动机机械故障。首先从节气门处打烟雾,没有发现进气管周围有漏气的地方;接着拔下进气管上的两个真空
    虹科Pico汽车示波器 2025-01-08 16:51 111浏览
  • 根据环洋市场咨询(Global Info Research)项目团队最新调研,预计2030年全球中空长航时无人机产值达到9009百万美元,2024-2030年期间年复合增长率CAGR为8.0%。 环洋市场咨询机构出版了的【全球中空长航时无人机行业总体规模、主要厂商及IPO上市调研报告,2025-2031】研究全球中空长航时无人机总体规模,包括产量、产值、消费量、主要生产地区、主要生产商及市场份额,同时分析中空长航时无人机市场主要驱动因素、阻碍因素、市场机遇、挑战、新产品发布等。报告从中空长航时
    GIRtina 2025-01-09 10:35 74浏览
  • 「他明明跟我同梯进来,为什么就是升得比我快?」许多人都有这样的疑问:明明就战绩也不比隔壁同事差,升迁之路却比别人苦。其实,之间的差异就在于「领导力」。並非必须当管理者才需要「领导力」,而是散发领导力特质的人,才更容易被晓明。许多领导力和特质,都可以通过努力和学习获得,因此就算不是天生的领导者,也能成为一个具备领导魅力的人,进而被老板看见,向你伸出升迁的橘子枝。领导力是什么?领导力是一种能力或特质,甚至可以说是一种「影响力」。好的领导者通常具备影响和鼓励他人的能力,并导引他们朝着共同的目标和愿景前
    优思学院 2025-01-08 14:54 93浏览
  • 在智能网联汽车中,各种通信技术如2G/3G/4G/5G、GNSS(全球导航卫星系统)、V2X(车联网通信)等在行业内被广泛使用。这些技术让汽车能够实现紧急呼叫、在线娱乐、导航等多种功能。EMC测试就是为了确保在复杂电磁环境下,汽车的通信系统仍然可以正常工作,保护驾乘者的安全。参考《QCT-基于LTE-V2X直连通信的车载信息交互系统技术要求及试验方法-1》标准10.5电磁兼容试验方法,下面将会从整车功能层面为大家解读V2X整车电磁兼容试验的过程。测试过程揭秘1. 设备准备为了进行电磁兼容试验,技
    北汇信息 2025-01-09 11:24 80浏览
  • 在过去十年中,自动驾驶和高级驾驶辅助系统(AD/ADAS)软件与硬件的快速发展对多传感器数据采集的设计需求提出了更高的要求。然而,目前仍缺乏能够高质量集成多传感器数据采集的解决方案。康谋ADTF正是应运而生,它提供了一个广受认可和广泛引用的软件框架,包含模块化的标准化应用程序和工具,旨在为ADAS功能的开发提供一站式体验。一、ADTF的关键之处!无论是奥迪、大众、宝马还是梅赛德斯-奔驰:他们都依赖我们不断发展的ADTF来开发智能驾驶辅助解决方案,直至实现自动驾驶的目标。从新功能的最初构思到批量生
    康谋 2025-01-09 10:04 75浏览
  • 一个真正的质量工程师(QE)必须将一件产品设计的“意图”与系统的可制造性、可服务性以及资源在现实中实现设计和产品的能力结合起来。所以,可以说,这确实是一种工程学科。我们常开玩笑说,质量工程师是工程领域里的「侦探」、「警察」或「律师」,守护神是"墨菲”,信奉的哲学就是「墨菲定律」。(注:墨菲定律是一种启发性原则,常被表述为:任何可能出错的事情最终都会出错。)做质量工程师的,有时会不受欢迎,也会被忽视,甚至可能遭遇主动或被动的阻碍,而一旦出了问题,责任往往就落在质量工程师的头上。虽然质量工程师并不负
    优思学院 2025-01-09 11:48 98浏览
  • 职场是人生的重要战场,既是谋生之地,也是实现个人价值的平台。然而,有些思维方式却会悄无声息地拖住你的后腿,让你原地踏步甚至退步。今天,我们就来聊聊职场中最忌讳的五种思维方式,看看自己有没有中招。1. 固步自封的思维在职场中,最可怕的事情莫过于自满于现状,拒绝学习和改变。世界在不断变化,行业的趋势、技术的革新都在要求我们与时俱进。如果你总觉得自己的方法最优,或者害怕尝试新事物,那就很容易被淘汰。与其等待机会找上门,不如主动出击,保持学习和探索的心态。加入优思学院,可以帮助你快速提升自己,与行业前沿
    优思学院 2025-01-09 15:48 69浏览
  •  在全球能源结构加速向清洁、可再生方向转型的今天,风力发电作为一种绿色能源,已成为各国新能源发展的重要组成部分。然而,风力发电系统在复杂的环境中长时间运行,对系统的安全性、稳定性和抗干扰能力提出了极高要求。光耦(光电耦合器)作为一种电气隔离与信号传输器件,凭借其优秀的隔离保护性能和信号传输能力,已成为风力发电系统中不可或缺的关键组件。 风力发电系统对隔离与控制的需求风力发电系统中,包括发电机、变流器、变压器和控制系统等多个部分,通常工作在高压、大功率的环境中。光耦在这里扮演了
    晶台光耦 2025-01-08 16:03 87浏览
  • HDMI 2.2 规格将至,开启视听新境界2025年1月6日,HDMI Forum, Inc. 宣布即将发布HDMI规范2.2版本。新HDMI规范为规模庞大的 HDMI 生态系统带来更多选择,为创建、分发和体验理想的终端用户效果提供更先进的解决方案。新技术为电视、电影和游戏工作室等内容制作商在当前和未来提供更高质量的选择,同时实现多种分发平台。96Gbps的更高带宽和新一代 HDMI 固定比率速率传输(Fixed Rate Link)技术为各种设备应用提供更优质的音频和视频。终端用户显示器能以最
    百佳泰测试实验室 2025-01-09 17:33 84浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦