#include # 宏定义 # 定义P0口为LCD_DATA sbit LCD_RS =P2^5; sbit LCD_RW =P2^6; sbit LCD_E =P2^7; 定义LCD控制引脚 sbit Xintiao =P3^2 ; 脉搏检测输入端定义 sbit speaker =P2^4; 蜂鸣器引脚定义 v误差 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); /*1602字符显示函数,变量依次为字符显示首地址,显示字符长度,所显示的字符*/ 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() 主函数 { 初始化显示 打开定时器 进入循环 有按键按下并已经得出键值 将按键使能变量清零,等待下次按键按下 判断键值 设置键按下 设置的位加 都设置好后将此变量清零 跳出,下同 加键按下 判断是设置上限 上限数值小于150 上限+ 如果是设置下限 下限值小于上限-1(下限值不能超过上限) 下限值加 减键按下 设置上限 上限数据大于下限+1(同样上限值不能小于下限) 上限数据减 设置下限 下限数据大于30时 下限数据减 显示变量 变量清零 心率正常时 最高位为0时不显示 心率不正常(计数超过5000,也就是两次信号时间超过5s)不显示数据 正常显示 显示一行数据 显示第二行数据 第二行显示心率 设置下限时显示 第一行显示心率 将下限数据拆字 最高位为0时,不显示 第二行显示下限数据 设置上限时显示(同上) } void Time1() interrupt 3 定时器1服务函数 { 重新赋初值 无按键按下时此值为0 每10ms扫描此处 扫描按键是否有按下 有按下此值加1,值为1 后二次进入中断后扫描此处(Key_Con为1) 第二次进入中断时,按键仍然是按下(起到按键延时去抖的作用) 变量加1,值为2 判断是哪个按键按下 判断好按键后将键值赋值给变量Key_Value 如果10ms时没有检测到按键按下(按下时间过短) 变量清零,重新检测按键 后检测按键 检测按键是否还是按下状态 有按键按下使能变量,(此变量为1时才会处理键值数据) 变量清零,等待下次有按键按下 此处与上面按键的检测类似 默认Xintiao_Con是为0的 每10ms(上面的定时器)检测一次脉搏是否有信号 如果有信号,变量加一,程序就会往下走了 每过10ms检测一下信号是否还存在 存在就加一 如果不存在了,检测时间很短,说明检测到的不是脉搏信号,可能是其他干扰,将变量清零,跳出此次检测 存在就加一 如果不存在了,检测时间很短,说明检测到的不是脉搏信号,可能是其他干扰,将变量清零,跳出此次检测 存在就加一 如果不存在了,检测时间很短,说明检测到的不是脉搏信号,可能是其他干扰,将变量清零,跳出此次检测 超过30ms一直有信号,判定此次是脉搏信号,执行以下程序 心率计原理为检测两次脉冲间隔时间计算心率,变量Xintiao_Change第一次脉冲时为0的,所有走下面的else,第二次走这里 不响 计算心跳并拆字显示:心跳计时是以10ms为单位,两次心跳中间计数如果是100次,也就是100*10ms=1000ms=1s 那么计算出的一分钟(60s)心跳数就是:60*1000/(100*10ms)=60次 其中60是一分钟60s,1000是一秒有1000ms,100是计数值,10是一次计数对应 的时间是10ms 计算出的心跳数/100得到心跳的百位,%100是取余的,就是除以100的余数,再除以10就得到十位了,以此类推 的目的是得到对应数字的液晶显示码,数字0对应的液晶显示码是0x30,1是0x30+1,以此类推 心率不在范围内报警 蜂鸣器响 不响 计算出心率后启动显示 心跳计数清零 计算出心率后该变量清零,准备下次检测心率 计算出心率后stop邈 第一次脉冲时Xintiao_Change为0 脉冲计时变量清零,开始计时 置1,准备第二次检测到脉冲时计算心率 清零,准备检测下一次脉冲 } /**定时器T0工作函数**/ void Time0() interrupt 1 { 重新赋初值 心跳计数加 心跳计数大于5000 数据清零 显示位置1 置零,准备再次检测 心跳计数超过5000后说明心率不正常或者没有测出,stop置1 关闭蜂鸣器 } /**定时器初始化函数**/ void Tim_Init() { 打开中断总开关 打开T0中断允许开关 打开T1中断允许开关 设定定时器状态 赋初值 赋初值 } /**在指定地址显示指定数量的指定字符**/ /**Adress_Com显示地址,Num_Adat显示字符数量,Adress_Data显示字符串内容**/ void lcd_1602_word(uchar Adress_Com,uchar Num_Adat,uchar *Adress_Data) { 选中地址 循环决定显示字符个数 读取字符串数据 显示字符串 显示地址加一 } /***************1602函数*******************/ void LCD_WriteData(uchar LCD_1602_DATA) 数据写入***********/ { 操作前短暂延时,保证信号稳定 } /********LCD1602命令写入***********/ void LCD_WriteCom(uchar LCD_1602_COM) { 操作前短暂延时,保证信号稳定 } void InitLcd() 初始化液晶函数 { 显示光标移动位置 显示开及光标设置 显示清屏 } v延时函数 { }下载本文