壓力測量儀的設(shè)計(jì)與仿真 一、設(shè)計(jì)要求: 本課程設(shè)計(jì)用MPX4115傳感器來檢測壓力參數(shù),ADC0832進(jìn)行模數(shù)轉(zhuǎn)換后,利用單片機(jī)AT89C52進(jìn)行數(shù)據(jù)處理后,用四個(gè)八段數(shù)碼管顯示壓力值。壓力測量的量程在15.3KPA~114.9KPA,分度值位0.1kpa。 二、構(gòu)思 2.1 主控模塊的選型。 方案一: 采用MSP430系列單片機(jī),該單片機(jī)是TI公司1996年開始推向市場的一種16位超低功耗的混合信號處理器。其內(nèi)部集成了很多模擬電路、數(shù)字電路和微處理器,提供強(qiáng)大的功能。不過該芯片昂貴不適合一般的設(shè)計(jì)開發(fā)[3]。 方案二 采用51系列的單片機(jī),該單片機(jī)是一個(gè)高可靠性,超低價(jià),無法解密,高性能的8位單片機(jī),32個(gè)IO口,且STC系列的單片機(jī)可以在線編程、調(diào)試,方便地實(shí)現(xiàn)程序的下載與整機(jī)的調(diào)試。 因此選用方案二中的51系列單片機(jī)作為主控芯片 2.2 顯示模塊的選型 方案一: 采用點(diǎn)陣式數(shù)碼管顯示,點(diǎn)陣式數(shù)碼管是由八行八列的發(fā)光二極管組成,對于顯示文字比較合適,如采用在顯示數(shù)字顯得太浪費(fèi),且價(jià)格也相對較高,所以不用此種作為顯示。 方案二: 采用LED數(shù)碼管動態(tài)掃描,LED數(shù)碼管價(jià)格雖適中,對于顯示數(shù)字也最合適,而且采用動態(tài)掃描法與單片機(jī)連接時(shí),占用單片機(jī)口線少。 所以本設(shè)計(jì)中方案二中LED數(shù)碼管的作為顯示模塊 2.3 傳感器的選型。 壓力傳感器對于系統(tǒng)至關(guān)重要,需要綜合實(shí)際的需求和各類壓力傳感器的性 能參數(shù)加以選擇。一般要選用有溫度補(bǔ)償作用的壓力傳感器,因?yàn)闇囟妊a(bǔ)償特性 可以克服半導(dǎo)體壓力傳感器件存在的溫度漂移問題。 本設(shè)計(jì)要實(shí)現(xiàn)的數(shù)字氣壓計(jì)顯示的是絕對氣壓值,同時(shí)為了簡化電路,提高 穩(wěn)定性和抗干擾能力,要求使用具有溫度補(bǔ)償能力的壓力傳感器。MPX4115可以產(chǎn)生高精度模 擬輸出電壓,數(shù)據(jù)采集模塊由壓力傳感器MPX4115構(gòu)成。
三、設(shè)計(jì): 3.1 總體設(shè)計(jì)方案 本次設(shè)計(jì)是基于8051單片機(jī)的測量與顯示。利用傳感器將壓力轉(zhuǎn)換為電信號后,在經(jīng)過ADC0832的模數(shù)轉(zhuǎn)換器經(jīng)A/D轉(zhuǎn)換后由單片機(jī)進(jìn)行有效處理,然后用數(shù)碼管進(jìn)行顯示。 3.2 流程框圖
0.png (3.9 KB, 下載次數(shù): 113)
下載附件
2018-12-19 22:52 上傳
3.3 單片機(jī)最小系統(tǒng) 由AT89C52單片機(jī)、時(shí)鐘電路、復(fù)位 電路組成AT89C51是一種帶4K字節(jié)閃爍可編程可擦除只讀存儲器的低電壓,高性能CMOS8位微處理器,俗稱單片機(jī)。AT89C52是一種帶2K字節(jié)閃爍可編程可擦除只讀存儲器的單片機(jī)。單片機(jī)的可擦除只讀存儲器可以反復(fù)擦除100次。該器件采用ATMEL高密度非易失存儲器制造技術(shù)制造,與工業(yè)標(biāo)準(zhǔn)的于將多功能MCS-518指令集和輸出管腳相兼容。位CPU和閃爍存儲器組合在由單個(gè)芯片中,ATMEL 的AT89C51是一種高效微控制器,AT89C52是它的一種精簡版本。AT89C單片機(jī)為很多嵌入式控制系統(tǒng)提供了一種靈活性高且價(jià)廉的方案 
單片機(jī)系統(tǒng)電路 3.4 A/D轉(zhuǎn)換模塊 ADC0832是美國國家半導(dǎo)體公司生產(chǎn)的一種8位分辨率、雙通道A/D轉(zhuǎn)換芯片。由于它體積小,兼容性,性價(jià)比高而深受單片機(jī)愛好者及企業(yè)歡迎,其目前已經(jīng)有很高的普及率。學(xué)習(xí)并使用 ADC0832 可是使我們了解A/D轉(zhuǎn)換器的原理,有助于我們單片機(jī)技術(shù)水平的提高。8位分辨率雙通道A/D轉(zhuǎn)換輸入輸出電平與TTL/CMOS 相兼容5V電源供電時(shí)輸入電壓在0~5V之間工作頻率為250KHZ,轉(zhuǎn)換時(shí)間為32μS。 ADC0832為8位分辨率A/D轉(zhuǎn)換芯片,其最高分辨可達(dá)256級,可以適應(yīng)一般的模擬量轉(zhuǎn)換要求。其內(nèi)部電源輸入與參考電壓的復(fù)用,使得芯片的模擬電壓輸入在 0~5V 之間。 
ADC0832模數(shù)轉(zhuǎn)換電路 3.5 傳感器模塊 MPX4115系列壓電電阻傳感器是一個(gè)硅壓力傳感器。這個(gè)傳感器結(jié)合了高級微電機(jī)技術(shù),薄膜鍍金屬。還能為高水準(zhǔn)模擬輸出信號提供一個(gè)均衡壓力。在0℃-85℃的溫度下誤差不超過1.5%,溫度補(bǔ)償是-40℃-125℃。為了克服干擾,在MPX4115輸出電路中增加了RC濾波電路。如下圖所示:

MPX4115信號處理電路 3.6系統(tǒng)總體電路圖 
四、仿真 

通過仿真,調(diào)節(jié)傳感器的+和-,可以觀察到數(shù)碼管數(shù)值的變化,壓力測量的范圍在15.3KPA~114.9KPA之間,基本可以達(dá)到要求。 五、心得體會: 傳感器課程設(shè)計(jì)結(jié)束了,我的收獲很多,我做的是基于AT89C52單片機(jī)的壓力測量儀的設(shè)計(jì),用到的主要芯片是 AT89C52和ADC0808,實(shí)現(xiàn)的功能是將傳感器采集到的模擬信號轉(zhuǎn)換成單片機(jī)可以識別的數(shù)字信號,再經(jīng)單片機(jī)轉(zhuǎn)換成數(shù)碼管可以識別的信息,最后顯示輸出。通過這些我的硬件和軟件開發(fā)能力都獲得了提高。首先硬件方面,基本了解了電子產(chǎn)品的開發(fā)流程和所要做的工作�;菊莆樟薖roteus原理圖的方法,從網(wǎng)上搜索的資料對我?guī)椭艽�,遇到不懂的問題自己解決不了,就和大家一起討論。通過發(fā)現(xiàn)問題、分析問題、解決問題,我又學(xué)到了許多新的知識,在工程實(shí)際應(yīng)用才能有切身的體會,實(shí)踐出真知,自己親自動手去做,才知道知識的匱乏。
單片機(jī)源碼:
- //線性區(qū)間標(biāo)度變換公式: y=(115-15)/(243-13)*X+15kpa
- #include <AT89X52.h>
- #include <intrins.h>
- #include <stdio.h>
- #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 SDA = P2 ^ 1; //數(shù)據(jù)線
- sbit SCL = P2 ^ 0; //時(shí)鐘線
- bit bAck; //應(yīng)答標(biāo)志 當(dāng)bbAck=1是為正確的應(yīng)答
- unsigned char dispbitcode[8]={0xf7,0xfb,0xfd,0xfe,0xef,0xdf,0xbf,0x7f}; //位掃描
- unsigned char dispcode[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff}; //共陽數(shù)碼管字段碼
- unsigned char dispbuf[4];
- unsigned int temp;
- unsigned char getdata; //獲取ADC轉(zhuǎn)換回來的值
- void delay_1ms(void) //12mhz delay 1.01ms
- {
- unsigned char x,y;
- x=3;
- while(x--)
- {
- y=40;
- while(y--);
- }
- }
- void display(void) //數(shù)碼管顯示函數(shù)
- {
- char k;
- for(k=0;k<4;k++)
- {
- P1 = dispbitcode[k];
- P0 = dispcode[dispbuf[k]];
- if(k==1) //加上數(shù)碼管的dp小數(shù)點(diǎn)
- P0&=0x7f;
- delay_1ms();
- }
- }
- /************
- 讀ADC0832函數(shù)
- ************/
- //采集并返回
- unsigned int Adc0832(unsigned char channel) //AD轉(zhuǎn)換,返回結(jié)果
- {
- 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;//控制命令結(jié)束
- _nop_();
- _nop_();
- dat=0;
- for(i=0;i<8;i++)
- {
- dat|=ADDO;//收數(shù)據(jù)
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次時(shí)鐘脈沖
- _nop_();
- _nop_();
- dat<<=1;
- if(i==7)dat|=ADDO;
- }
- for(i=0;i<8;i++)
- {
- j=0;
- j=j|ADDO;//收數(shù)據(jù)
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次時(shí)鐘脈沖
- _nop_();
- _nop_();
- j=j<<7;
- ndat=ndat|j;
- if(i<7)ndat>>=1;
- }
- ADCS=1;//拉低CS端
- ADCLK=0;//拉低CLK端
- ADDO=1;//拉高數(shù)據(jù)端,回到初始狀態(tài)
- dat<<=8;
- dat|=ndat;
- return(dat); //return ad k
- }
- //啟動I2C總線,即發(fā)送起始條件
- void StartI2C()
- {
- SDA = 1; //發(fā)送起始條件數(shù)據(jù)信號
- _nop_();
- SCL = 1;
- _nop_(); //起始建立時(shí)間大于4.7us
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SDA = 0; //發(fā)送起始信號
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SCL = 0; //時(shí)鐘操作
- _nop_();
- _nop_();
- }
- //結(jié)束I2C總線,即發(fā)送I2C結(jié)束條件
- void StopI2C()
- {
- SDA = 0; //發(fā)送結(jié)束條件的數(shù)據(jù)信號
- _nop_(); //發(fā)送結(jié)束條件的時(shí)鐘信號
- SCL = 1; //結(jié)束條件建立時(shí)間大于4us
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SDA = 1; //發(fā)送I2C總線結(jié)束命令
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- //發(fā)送一個(gè)字節(jié)的數(shù)據(jù)
- void SendByte(unsigned char c)
- {
- unsigned char BitCnt;
- for(BitCnt = 0;BitCnt < 8;BitCnt++) //一個(gè)字節(jié)
- {
- if((c << BitCnt)& 0x80) SDA = 1; //判斷發(fā)送位
- else SDA = 0;
- _nop_();
- SCL = 1; //時(shí)鐘線為高,通知從機(jī)開始接收數(shù)據(jù)
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SCL = 0;
- }
- _nop_();
- _nop_();
- SDA = 1; //釋放數(shù)據(jù)線,準(zhǔn)備接受應(yīng)答位
- _nop_();
- _nop_();
- SCL = 1;
- _nop_();
- _nop_();
- _nop_();
- if(SDA == 1) bAck =0;
- else bAck = 1; //判斷是否收到應(yīng)答信號
- SCL = 0;
- _nop_();
- _nop_();
- }
- //接收一個(gè)字節(jié)的數(shù)據(jù)
- unsigned char RevByte()
- {
- unsigned char retc;
- unsigned char BitCnt;
- retc = 0;
- SDA = 1;
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- _nop_();
- SCL = 0; //置時(shí)鐘線為低,準(zhǔn)備接收
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SCL = 1; //置時(shí)鐘線為高使得數(shù)據(jù)有效
- _nop_();
- _nop_();
- retc = retc << 1; //左移補(bǔ)零
- if (SDA == 1)
- retc = retc + 1; //當(dāng)數(shù)據(jù)為1則收到的數(shù)據(jù)+1
- _nop_();
- _nop_();
- }
- SCL = 0;
- _nop_();
- _nop_();
- return(retc); //返回收到的數(shù)據(jù)
- }
- unsigned char WIICByte(unsigned char WChipAdd,unsigned char InterAdd,unsigned char WIICData)
- {
- StartI2C(); //啟動總線
- SendByte(WChipAdd); //發(fā)送器件地址以及命令
- if (bAck==1) //收到應(yīng)答
- {
- SendByte(InterAdd); //發(fā)送內(nèi)部子地址
- if (bAck ==1)
- {
- SendByte(WIICData); //發(fā)送數(shù)據(jù)
- if(bAck == 1)
- {
- StopI2C(); //停止總線
- return(0xff);
- }
- else
- {
- return(0x03);
- }
- }
- else
- {
- return(0x02);
- }
- }
- return(0x01);
- }
- //讀取指定器件的內(nèi)部指定地址一個(gè)字節(jié)數(shù)據(jù)
- unsigned char RIICByte(unsigned char WChipAdd,unsigned char RChipAdd,unsigned char InterDataAdd)
- {
- unsigned char TempData;
- TempData = 0;
- StartI2C(); //啟動
- SendByte(WChipAdd); //發(fā)送器件地址以及讀命令
- if (bAck==1) //收到應(yīng)答
- {
- SendByte(InterDataAdd); //發(fā)送內(nèi)部子地址
- if (bAck ==1)
- {
- StartI2C();
- SendByte(RChipAdd);
- if(bAck == 1)
- {
- TempData = RevByte(); //接收數(shù)據(jù)
- StopI2C(); //停止I2C總線
- return(TempData); //返回?cái)?shù)據(jù)
- }
- else
- {
- return(0x03);
- }
- }
- else
- {
- return(0x02);
- }
- }
- else
- {
- return(0x01);
- }
- }
- void main(void)
- {
- unsigned int OverCounter = 0;
- unsigned char ptemp;
- bit OverFlg = 0;
- unsigned int temp,ppress = 0;
- float press;
- while(1)
- {
-
- getdata=Adc0832(0);
- if(14<getdata<243) //當(dāng)壓力值介于15kpa到115kpa之間時(shí),遵循線性變換
- {
- int vary=getdata; //y=(115-15)/(243-13)*X+15kpa
- press=((10.0/23.0)*vary)+9.3; //測試時(shí)補(bǔ)償值為9.3
- temp=(int)(press*10); //放大10倍,便于后面的計(jì)算
- if(temp != ppress)
- {
- ppress = temp;
- OverFlg = 1;
- }
- dispbuf[3]=temp/1000; //取壓力值百位
- dispbuf[2]=(temp%1000)/100; //取壓力值十位
- dispbuf[1]=((temp%1000)%100)/10; //取壓力值個(gè)位
- dispbuf[0]=((temp%1000)%100)%10; //取壓力值十分位
- display();
- if (temp > 100)
- {
- if(OverFlg == 1)
- {
- OverCounter++;
- WIICByte(W24C04ADD,0x01,(OverCounter/0xff)); //低位
- WIICByte(W24C04ADD,0x02,(OverCounter%0xff)); //高位
- OverFlg = 0; //清除標(biāo)志
- }
- }
- }
- }
- }
復(fù)制代碼
0.png (16.19 KB, 下載次數(shù): 119)
下載附件
2018-12-19 22:50 上傳
全部資料51hei下載地址:
電工1611壓力測量儀的設(shè)計(jì)與仿真.zip
(652.37 KB, 下載次數(shù): 652)
2018-12-19 22:05 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|