51hei.png (41.26 KB, 下載次數: 42)
下載附件
2020-1-7 21:33 上傳
單片機源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #include <stdio.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define ulong unsigned long //宏定義
- #define LCD_DATA P0 //定義P0口為LCD_DATA
- unsigned char getdata; //獲取ADC轉換回來的值
- unsigned char dispbuf[4];
- unsigned int OverCounter = 0;
- unsigned char ptemp;
- bit OverFlg = 0;
- unsigned int temp,ppress = 0;
- float press;
- char KEY_TIMES = 0;
- char KEY_Set_TIMES = 0;
- sbit LCD_RS =P2^5;
- sbit LCD_RW =P2^6;
- sbit LCD_E =P2^7; //定義LCD控制引腳
- #define R24C04ADD 0xA1
- #define W24C04ADD 0xA0
- //ADC0832的引腳
- sbit ADCS =P2^2; //ADC0832 chip seclect
- sbit ADDI =P2^4; //ADC0832 k in
- sbit ADDO =P2^4; //ADC0832 k out
- sbit ADCLK =P2^3; //ADC0832 clock signal
- sbit KEY =P1^7;
- sbit KEY_Set = P3^0;
- sbit KEY_ADD = P3^1;
- sbit KEY_DEC = P3^2;
- sbit speaker =P2^0; //蜂鳴器引腳定義
- sbit DQ=P3^7;
- void delay5ms(void); //誤差 0us
- void LCD_WriteData(uchar LCD_1602_DATA); /********LCD1602數據寫入***********/
- void LCD_WriteCom(uchar LCD_1602_COM); /********LCD1602命令寫入***********/
- void lcd_1602_word(uchar Adress_Com,uchar Num_Adat,uchar *Adress_Data); /*1602字符顯示函數,變量依次為字符顯示首地址,顯示字符長度,所顯示的字符*/
- void InitLcd();//液晶初始化函數
- unsigned int Adc0832(unsigned char channel);
- void LCD1602_Write_char( unsigned char *prointer );
- uchar Xintiao_H=110; //脈搏上限
- uint wendu=0;
- /*****延時子程序*****/
- void Delay_DS18B20(int num)
- {
- while(num--) ;
- }
- /*****初始化DS18B20*****/
- void Init_DS18B20(void)
- {
- unsigned char x=0;
- DQ = 1; //DQ復位
- Delay_DS18B20(8); //稍做延時
- DQ = 0; //單片機將DQ拉低
- Delay_DS18B20(80); //精確延時,大于480us
- DQ = 1; //拉高總線
- Delay_DS18B20(34);
- }
- /*****讀一個字節*****/
- unsigned char ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 給脈沖信號
- dat>>=1;
- DQ = 1; // 給脈沖信號
- if(DQ)
- dat|=0x80;
- Delay_DS18B20(4);
- }
- return(dat);
- }
- void WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- Delay_DS18B20(5);
- DQ = 1;
- dat>>=1;
- }
- }
- /*****讀取溫度*****/
- unsigned int ReadTemperature(void)
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned int t=0;
- float tt=0;
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0x44); //啟動溫度轉換
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0xBE); //讀取溫度寄存器
- a=ReadOneChar(); //讀低8位
- b=ReadOneChar(); //讀高8位
- t=b;
- t<<=8;
- t=t|a;
- tt=t*0.0625;
- t= tt*10+0.5; //放大10倍輸出并四舍五入
- return(t);
- }
- //按鍵掃描
- void KEY_SCAN( void )
- {
- if( KEY == 0 )
- {
- delay5ms();
- if( KEY == 0 )
- {
- delay5ms();
- while( !KEY );
- KEY_TIMES++;
- if( KEY_TIMES > 1 )
- {
- KEY_TIMES = 0;
- }
- LCD_WriteCom( 0x80 );
- LCD1602_Write_char(" ");
- LCD_WriteCom( 0x80+0x40 );
- LCD1602_Write_char(" ");
- }
- }
- if( KEY_Set == 0 )
- {
- delay5ms();
- if( KEY_Set == 0 )
- {
- delay5ms();
- while( !KEY_Set );
- KEY_Set_TIMES++;
- if( KEY_Set_TIMES > 1 )
- {
- KEY_Set_TIMES = 0;
- }
- LCD_WriteCom( 0x80 );
- LCD1602_Write_char(" ");
- LCD_WriteCom( 0x80+0x40 );
- LCD1602_Write_char(" ");
- }
- }
- }
- //設置心率告警值
- void KEY_Set_Rate( void )
- {
- if( KEY_ADD == 0 )
- {
- delay5ms();
- if( KEY_ADD == 0 )
- {
- delay5ms();
- while( !KEY_ADD );
- Xintiao_H++;
- if( Xintiao_H >= 160 )
- {
- Xintiao_H = 160;
- }
- }
- }
- if( KEY_DEC == 0 )
- {
- delay5ms();
- if( KEY_DEC == 0 )
- {
- delay5ms();
- while( !KEY_DEC );
- Xintiao_H--;
- if( Xintiao_H <= 60 )
- {
- Xintiao_H = 60;
- }
- }
- }
- }
- //=====================================================================================
- //=====================================================================================
- //=====================================================================================
- void main() //主函數
- {
- InitLcd();
- while(1) //進入循環
- {
- KEY_SCAN();
- getdata=Adc0832(0);
- temp=getdata/2-5;
- if( temp > Xintiao_H )
- {
- speaker = 0;
- }
- else
- {
- speaker = 1;
- }
- temp = 0;
- if( KEY_Set_TIMES == 0 )
- {
- if( KEY_TIMES == 1 )
- {
- getdata=Adc0832(0);
- if(14<getdata<243) //當壓力值介于15kpa到115kpa之間時,遵循線性變換
- {
- // int vary=getdata; //y=(115-15)/(243-13)*X+15kpa
- temp=getdata*10/2-50; //測試時補償值為9.3
- // temp=(int)(press*10); //放大10倍,便于后面的計算
- if(temp != ppress)
- {
- ppress = temp;
- OverFlg = 1;
- }
- dispbuf[3]=temp/1000; //取壓力值百位
- dispbuf[2]=(temp%1000)/100; //取壓力值十位
- dispbuf[1]=((temp%1000)%100)/10; //取壓力值個位
- dispbuf[0]=((temp%1000)%100)%10; //取壓力值十分位
- LCD_WriteCom( 0x80 );
- LCD1602_Write_char( " heart rate " );
- LCD_WriteCom( 0x80 + 0x40 );
- LCD1602_Write_char("Rate:");
- LCD_WriteData( 0x30 + dispbuf[3] );
- LCD_WriteData( 0x30 + dispbuf[2] );
- LCD_WriteData( 0x30 + dispbuf[1] );
- LCD_WriteData( '.' );
- LCD_WriteData( 0x30 + dispbuf[0] );
- }
- }
- if( KEY_TIMES == 0 )
- {
- lcd_1602_word(0x80,16," temperature "); //初始化顯示
- wendu=ReadTemperature();
- lcd_1602_word(0xc0,10," Temp: ");//顯示第二行數據
- LCD_WriteCom(0x80+0x40+10);
- LCD_WriteData(wendu/100+0x30);
- LCD_WriteData(wendu%100/10+0x30);
- LCD_WriteData('.');
- LCD_WriteData(wendu%100%10+0x30);
- LCD_WriteData(0xdf);
- LCD_WriteData('C');
- }
- }
- else
- {
- KEY_Set_Rate();
- dispbuf[3]=Xintiao_H/100; //取設置壓力值百位
- dispbuf[2]=Xintiao_H%100/10; //取設置壓力值十位
- dispbuf[1]=Xintiao_H%10; //取設置壓力值個位
- LCD_WriteCom( 0x80 );
- LCD1602_Write_char( " Set heart rate " );
- LCD_WriteCom( 0x80 + 0x40 );
- LCD1602_Write_char("warning:");
- LCD_WriteData( 0x30 + dispbuf[3] );
- LCD_WriteData( 0x30 + dispbuf[2] );
- LCD_WriteData( 0x30 + dispbuf[1] );
- }
- }
- }
- /**Adress_Com顯示地址,Num_Adat顯示字符數量,Adress_Data顯示字符串內容**/
- 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<Num_Adat;a++) //for循環決定顯示字符個數
- {
- Data_Word=*Adress_Data; //讀取字符串數據
- LCD_WriteData(Data_Word); //顯示字符串
- Adress_Data++; //顯示地址加一
- }
- }
- /***************1602函數*******************/
- void LCD_WriteData(uchar LCD_1602_DATA) /********LCD1602數據寫入***********/
- {
- 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;
- }
- /********LCD1602命令寫入***********/
- 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--);
- }
- /*=========================================
- //LCD1602寫字符串
- =========================================*/
- void LCD1602_Write_char( unsigned char *prointer ) //1602 字符串 處理
- {
- while( *prointer != '\0' )
- {
- LCD_WriteData( *prointer );
- prointer++;
- }
- }
- /************
- 讀ADC0832函數
- ************/
- //采集并返回
- unsigned int Adc0832(unsigned char channel) //AD轉換,返回結果
- {
- unsigned char i=0;
- unsigned char j;
- unsigned int dat=0;
- unsigned char ndat=0;
- if(channel==0)channel=2;
- if(channel==1)channel=3;
- ADDI=1;
- _nop_();
- _nop_();
- ADCS=0;//拉低CS端
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿1
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- ADDI=channel&0x1;
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿2
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- ADDI=(channel>>1)&0x1;
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿3
- ADDI=1;//控制命令結束
- _nop_();
- _nop_();
- dat=0;
- for(i=0;i<8;i++)
- {
- dat|=ADDO;//收數據
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次時鐘脈沖
- _nop_();
- _nop_();
- dat<<=1;
- if(i==7)dat|=ADDO;
- }
- for(i=0;i<8;i++)
- {
- j=0;
- j=j|ADDO;//收數據
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次時鐘脈沖
- _nop_();
- _nop_();
- j=j<<7;
- ndat=ndat|j;
- if(i<7)ndat>>=1;
- }
- ADCS=1;//拉低CS端
- ADCLK=0;//拉低CLK端
- ADDO=1;//拉高數據端,回到初始狀態
- dat<<=8;
- dat|=ndat;
- return(dat); //return ad k
- }
復制代碼
51hei.png (8.75 KB, 下載次數: 36)
下載附件
2020-1-7 21:32 上傳
所有資料51hei提供下載:
基于單片機的電子血壓計設計.zip
(1.03 MB, 下載次數: 163)
2020-1-7 17:05 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|