屏幕截圖 2023-05-12 165440.jpg (81.1 KB, 下載次數(shù): 24)
下載附件
2023-5-12 16:54 上傳
單片機源程序如下:
- #include <reg52.h> //調(diào)用單片機頭文件
- #define uchar unsigned char //無符號字符型 宏定義 變量范圍0~255
- #define uint unsigned int //無符號整型 宏定義 變量范圍0~65535
- uchar menu_1; //設置不同報警參數(shù)的變量
- 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:數(shù)據(jù)寄存器 L:指令寄存器
- sbit rw=P1^1; //寄存器選擇信號 H:數(shù)據(jù)寄存器 L:指令寄存器
- sbit e =P1^2; //片選信號 下降沿觸發(fā)
- sbit beep = P3^7; //蜂鳴器IO口定義,仿真
- sbit key1 = P3^6; //按鍵IO口定義,仿真
- sbit key2 = P3^5; //按鍵IO口定義,仿真
- sbit key3 = P3^4; //按鍵IO口定義,仿真
- /***********************1ms延時函數(shù)*****************************/
- 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指令函數(shù)
- * 輸入 : 輸入的指令值
- * 輸出 : 無
- ***********************************************************************/
- 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寫數(shù)據(jù)函數(shù)
- * 輸入 : 需要寫入1602的數(shù)據(jù)
- * 輸出 : 無
- ***********************************************************************/
- void write_data(uchar dat)
- {
- rs=1; //寫數(shù)據(jù)
- rw=0; //對1602寫操作
- P0=dat; //P0口對1602寫數(shù)據(jù)
- delay_uint(25);
- e=1; //e=1使能信號
- delay_uint(100); //延時一下等1602完成操作
- e=0;
- }
- /********************************************************************
- * 名稱 : write_string(uchar hang,uchar add,uchar *p)
- * 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調(diào)用該函數(shù)如下
- write_string(1,5,"ab cd ef;")
- * 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
- * 輸出 : 無
- ***********************************************************************/
- 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字符串的結(jié)尾標志 break結(jié)束while循環(huán) 結(jié)束寫字符
- write_data(*p); //寫數(shù)據(jù)
- p++; //指針地址加1
- }
- }
-
- /*****************控制光標函數(shù)********************/
- 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); //關(guān)閉光標
- }
-
- /***********************lcd1602上顯示3位十進制數(shù)************************/
- 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); //顯示百位數(shù),加0x30轉(zhuǎn)換為ASCII字符
- write_data(0x30+date/10%10); //顯示十位數(shù)
- write_data(0x30+date%10); //顯示個位數(shù)
- }
- /***********************lcd1602初始化設置************************/
- void init_1602()
- {
- write_com(0x38); //顯示模式設置:16×2顯示,5×7點陣,8位數(shù)據(jù)接口 不檢測忙信號
- 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 說明按鍵已經(jīng)松開了
- }
- /**********************設置函數(shù)************************/
- 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);
- }
- }
- /****************報警函數(shù)***************/
- void clock_h_l()
- {
- if(rate != 0)
- {
- if((rate <= rate_l) || (rate >= rate_h))
- {
- beep = ~beep; //蜂鳴器報警
- }
- else
- {
- beep = 1; //取消報警
- }
- }else
- {
- beep = 1; //取消報警
- }
-
- }
- /****************主函數(shù)***************/
- void main()
- {
- init_1602(); //1602初始化
- time_init(); //初始化定時器
- init_int0(); //外部中斷0初始化程序
- while(1)
- {
- key(); //按鍵函數(shù)
- key_with(); //按鍵設置函數(shù)
- rate=60000/(time[1]+time[2]+time[3]+time[4]+time[5])/5; //計算脈搏次數(shù)
- write_lcd3(1,5,rate); //顯示脈搏
- clock_h_l(); //報警函數(shù)
- delay_1ms(1); //延時1毫秒
- }
- }
- void int0() interrupt 0 //外部中斷0,由P3.2端口引入,低電平或下降沿引起
- {
- if(timecount<8) //當連續(xù)兩次檢測時間間隔小于8*50ms=400ms不處理
- {
- TR0=1;//開定時器
- }
- else
- {
- time[i]=timecount*50+TH0+TL0;//算出間隔時間,timecount是50ms計數(shù),每隔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計數(shù)清零
- i++;
- if(i==6)//記錄到超過等于6次時間
- {
- i=1;//計數(shù)從1開始
- }
- }
- }
- void time0_int() interrupt 1
- {
- TH0 = 0x3c;
- TL0 = 0xb0; // 50ms 12M
- timecount++;//每50ms一次計數(shù)
- if(timecount>25) //當超過25*50ms=1.5s沒有檢測到信號停止顯示
- {
- i=0;//數(shù)據(jù)個數(shù)清零
- timecount=0;//50ms計數(shù)清零
- TR0=0;//定時器關(guān)
- TH0 = 0x3c;
- TL0 = 0xb0; // 50ms 12M
- }
- }
-
復制代碼 |