单片机源程序如下:
- #include <reg52.h> //调用单片机头文件
- #define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
- #define uint unsigned int //无符号整型 宏定义 变量范围0~65535
- uchar menu_1; //设置不同报警参数的变量
- uchar flag_200ms ; //200毫秒的变量
-
- unsigned char i=0,rate=0,timecount=0;
- unsigned int time[6]={0};
- uchar rate_l=2,rate_h=200; //脉搏上下限报警值
- sbit rs=P1^0; //寄存器选择信号 H:数据寄存器 L:指令寄存器
- sbit rw=P1^1; //寄存器选择信号 H:数据寄存器 L:指令寄存器
- sbit e =P1^2; //片选信号 下降沿触发
- sbit beep = P3^7; //蜂鸣器IO口定义,仿真
- sbit key1 = P3^6; //按键IO口定义,仿真
- sbit key2 = P3^5; //按键IO口定义,仿真
- sbit key3 = P3^4; //按键IO口定义,仿真
- /***********************1ms延时函数*****************************/
- void delay_1ms(uint q)
- {
- uint i,j;
- for(i=0;i<q;i++)
- for(j=0;j<120;j++);
- }
-
- /********************************************************************
- * 名称 : delay_uint()
- * 功能 : 小延时。
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void delay_uint(uint q)
- {
- while(q--);
- }
- /********************************************************************
- * 名称 : write_com(uchar com)
- * 功能 : 1602指令函数
- * 输入 : 输入的指令值
- * 输出 : 无
- ***********************************************************************/
- void write_com(uchar com)
- {
- rs=0; //写指令
- rw=0; //对1602写操作
- P0=com; //P0口对1602写指令
- delay_uint(25);
- e=1; //e=1使能信号
- delay_uint(100); //延时一下等1602完成操作
- e=0;
- }
- /********************************************************************
- * 名称 : write_data(uchar dat)
- * 功能 : 1602写数据函数
- * 输入 : 需要写入1602的数据
- * 输出 : 无
- ***********************************************************************/
- void write_data(uchar dat)
- {
- rs=1; //写数据
- rw=0; //对1602写操作
- P0=dat; //P0口对1602写数据
- delay_uint(25);
- e=1; //e=1使能信号
- delay_uint(100); //延时一下等1602完成操作
- e=0;
- }
- /********************************************************************
- * 名称 : write_string(uchar hang,uchar add,uchar *p)
- * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
- write_string(1,5,"ab cd ef;")
- * 输入 : 行,列,需要输入1602的数据
- * 输出 : 无
- ***********************************************************************/
- void write_string(uchar hang,uchar add,uchar *p)
- {
- if(hang==1)
- write_com(0x80+add); //写1602第一行的地址
- else
- write_com(0x80+0x40+add); //写1602第二行的地址
- while(1)
- {
- if(*p == '\0') break; //\0字符串的结尾标志 break结束while循环 结束写字符
- write_data(*p); //写数据
- p++; //指针地址加1
- }
- }
-
- /*****************控制光标函数********************/
- void write_guanbiao(uchar hang,uchar add,uchar date)
- {
- if(hang==1)
- write_com(0x80+add);
- else
- write_com(0x80+0x40+add);
- if(date == 1)
- write_com(0x0f); //显示光标并且闪烁
- else
- write_com(0x0c); //关闭光标
- }
-
- /***********************lcd1602上显示3位十进制数************************/
- void write_lcd3(uchar hang,uchar add,uint date)
- {
- if(hang==1)
- write_com(0x80+add); //写1602第一行的地址
- else
- write_com(0x80+0x40+add); //写1602第二行的地址
- write_data(0x30+date/100%10); //显示百位数,加0x30转换为ASCII字符
- write_data(0x30+date/10%10); //显示十位数
- write_data(0x30+date%10); //显示个位数
- }
- /***********************lcd1602初始化设置************************/
- void init_1602()
- {
- write_com(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口 不检测忙信号
- write_com(0x0c); //开显示 不显示光标
- write_com(0x06); //当写一个字符是,地址指针加 1
- write_string(1,0," 000/min "); //初始化1602显示
- write_string(2,0," H:000 L:000 "); //初始化1602显示
- write_lcd3(2,4,rate_h);
- write_lcd3(2,11,rate_l);
- }
- /*************定时器0初始化程序***************/
- void time_init()
- {
- EA = 1; //开总中断
- TMOD = 0X01; //定时器0工作方式1
- ET0 = 1; //开定时器0中断
- TR0 = 1; //允许定时器0定时
- }
- /***********外部中断0初始化程序****************/
- void init_int0() //外部中断0初始化程序
- {
- EX0=1; //允许外部中断0中断
- EA=1; //开总中断
- IT0 = 1; //外部中断0负跳变中断
- }
-
- /********************独立按键程序*****************/
- uchar key_can; //按键值
- void key() //独立按键程序
- {
- static uchar key_new; //key_new 这个变量的功能是做按键松手检测的
- key_can = 0; //按键值还原成0
- if(key1 == 0 || key2 == 0 || key3 == 0) //有按键按下
- {
- delay_1ms(1); //按键延时消抖动
- if(key_new == 1)
- {
- key_new = 0; //key_new = 0 说明按键已按下
- if(key1 == 0) //确认是按键按下
- key_can = 1; //得到按键值
- if(key2 == 0) //确认是按键按下
- key_can = 2; //得到按键值
- if(key3 == 0) //确认是按键按下
- key_can = 3; //得到按键值
- }
- }
- else
- key_new = 1; //key_new = 1 说明按键已经松开了
- }
- /**********************设置函数************************/
- void key_with()
- {
- if(key_can == 1) //设置键
- {
- menu_1++;
- if(menu_1 > 2)
- {
- menu_1 = 0; //menu_1 = 0 退出设置了,在正常显示界面下
- init_1602(); //初始化液晶显示
-
- }
- }
- /***************设置*********************/
- if(menu_1 != 0)
- {
- if(menu_1 == 1) //设置脉搏上限报警值
- {
- if(key_can == 2) //加键
- {
- rate_h ++; //设置脉搏上限报警值 加1
- if(rate_h >= 255)
- rate_h = 0;
- }
- if(key_can == 3) //减键
- {
- rate_h -- ; //设置脉搏上限报警值 减1
- if(rate_h <= rate_l)
- rate_h = rate_l + 1; //限制脉搏上限不能低于脉搏下限
- }
- }
- if(menu_1 == 2) //设置脉搏下限报警值
- {
- if(key_can == 2) //加键
- {
- rate_l ++; //设置脉搏下限报警值 加1
- if(rate_l >= rate_h)
- rate_l = rate_h - 1; //限制脉搏下限不能高于脉搏上限
- }
- if(key_can == 3) //减键
- {
- if(rate_l == 0)
- rate_l = 1;
- rate_l -- ; //设置脉搏下限报警值 减1
- }
- }
- write_lcd3(2,4,rate_h); //显示上限报警值
- write_lcd3(2,11,rate_l); //显示下限报警值
- delay_1ms(10);
- }
- }
- /****************报警函数***************/
- void clock_h_l()
- {
- if(rate != 0)
- {
- if((rate <= rate_l) || (rate >= rate_h))
- {
- beep = ~beep; //蜂鸣器报警
- }
- else
- {
- beep = 1; //取消报警
- }
- }else
- {
- beep = 1; //取消报警
- }
-
- }
- /****************主函数***************/
- void main()
- {
- init_1602(); //1602初始化
- time_init(); //初始化定时器
- init_int0(); //外部中断0初始化程序
- while(1)
- {
- key(); //按键函数
- key_with(); //按键设置函数
- rate=60000/(time[1]+time[2]+time[3]+time[4]+time[5])/5; //计算脉搏次数
- write_lcd3(1,5,rate); //显示脉搏
- clock_h_l(); //报警函数
- delay_1ms(1); //延时1毫秒
- }
- }
- void int0() interrupt 0 //外部中断0,由P3.2端口引入,低电平或下降沿引起
- {
- if(timecount<8) //当连续两次检测时间间隔小于8*50ms=400ms不处理
- {
- TR0=1;//开定时器
- }
- else
- {
- time[i]=timecount*50+TH0+TL0;//算出间隔时间,timecount是50ms计数,每隔50ms timecount加1
- // time[i]=timecount*50+TH0*0.256+TL0/1000;
- // time[i]=TH0*256+TL0;
- TH0 = 0x3c;
- TL0 = 0xb0; // 50ms 12M
- timecount=0;//50ms计数清零
- i++;
- if(i==6)//记录到超过等于6次时间
- {
- i=1;//计数从1开始
- }
- }
- }
- void time0_int() interrupt 1
- {
- TH0 = 0x3c;
- TL0 = 0xb0; // 50ms 12M
- timecount++;//每50ms一次计数
- if(timecount>25) //当超过25*50ms=1.5s没有检测到信号停止显示
- {
- i=0;//数据个数清零
- timecount=0;//50ms计数清零
- TR0=0;//定时器关
- TH0 = 0x3c;
- TL0 = 0xb0; // 50ms 12M
- }
- }
-
复制代码 |