仿真原版本:proteus 7.8
程序編譯器:keil 4/keil 5
編程語言:C語言
設(shè)計編號:S0018
功能描述
本課程設(shè)計用MPX4115傳感器來檢測壓力參數(shù),ADC0832進行模數(shù)轉(zhuǎn)換后,利用單片機AT89C52進行數(shù)據(jù)處理后,用四個八段數(shù)碼管顯示壓力值。壓力測量的量程在15.3KPA~114.9KPA,分度值位0.1kpa。
講解視頻
51單片機胎壓氣壓監(jiān)測
仿真電路
總體設(shè)計方案
本次設(shè)計是基于8051單片機的測量與顯示。利用傳感器將壓力轉(zhuǎn)換為電信號后,在經(jīng)過ADC0832的模數(shù)轉(zhuǎn)換器經(jīng)A/D轉(zhuǎn)換后由單片機進行有效處理,然后用數(shù)碼管進行顯示。
單片機最小系統(tǒng)
由AT89C52單片機、時鐘電路、復位 電路組成AT89C51是一種帶4K字節(jié)閃爍可編程可擦除只讀存儲器的低電壓,高性能CMOS8位微處理器,俗稱單片機。AT89C52是一種帶2K字節(jié)閃爍可編程可擦除只讀存儲器的單片機。單片機的可擦除只讀存儲器可以反復擦除100次。該器件采用ATMEL高密度非易失存儲器制造技術(shù)制造,與工業(yè)標準的于將多功能MCS-518指令集和輸出管腳相兼容。位CPU和閃爍存儲器組合在由單個芯片中,ATMEL 的AT89C51是一種高效微控制器,AT89C52是它的一種精簡版本。AT89C單片機為很多嵌入式控制系統(tǒng)提供了一種靈活性高且價廉的方案。
A/D轉(zhuǎn)換模塊
ADC0832是美國國家半導體公司生產(chǎn)的一種8位分辨率、雙通道A/D轉(zhuǎn)換芯片。由于它體積小,兼容性,性價比高而深受單片機愛好者及企業(yè)歡迎,其目前已經(jīng)有很高的普及率。學習并使用 ADC0832 可是使我們了解A/D轉(zhuǎn)換器的原理,有助于我們單片機技術(shù)水平的提高。8位分辨率雙通道A/D轉(zhuǎn)換輸入輸出電平與TTL/CMOS 相兼容5V電源供電時輸入電壓在0~5V之間工作頻率為250KHZ,轉(zhuǎn)換時間為32μS。 ADC0832為8位分辨率A/D轉(zhuǎn)換芯片,其最高分辨可達256級,可以適應(yīng)一般的模擬量轉(zhuǎn)換要求。其內(nèi)部電源輸入與參考電壓的復用,使得芯片的模擬電壓輸入在 0~5V 之間。
傳感器模塊
MPX4115系列壓電電阻傳感器是一個硅壓力傳感器。這個傳感器結(jié)合了高級微電機技術(shù),薄膜鍍金屬。還能為高水準模擬輸出信號提供一個均衡壓力。在0℃-85℃的溫度下誤差不超過1.5%,溫度補償是-40℃-125℃。為了克服干擾,在MPX4115輸出電路中增加了RC濾波電路。如下圖所示:
程序
讀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;//形成一次時鐘脈沖
_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;//形成一次時鐘脈沖
_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_(); //起始建立時間大于4.7us
_nop_();
_nop_();
_nop_();
_nop_();
SDA = 0; //發(fā)送起始信號
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 0; //時鐘操作
_nop_();
_nop_();
}
//結(jié)束I2C總線,即發(fā)送I2C結(jié)束條件
void StopI2C()
{
SDA = 0; //發(fā)送結(jié)束條件的數(shù)據(jù)信號
_nop_(); //發(fā)送結(jié)束條件的時鐘信號
SCL = 1; //結(jié)束條件建立時間大于4us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA = 1; //發(fā)送I2C總線結(jié)束命令
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
//發(fā)送一個字節(jié)的數(shù)據(jù)
void SendByte(unsigned char c)
{
unsigned char BitCnt;
for(BitCnt = 0;BitCnt < 8;BitCnt++) //一個字節(jié)
{
if((c << BitCnt)& 0x80) SDA = 1; //判斷發(fā)送位
else SDA = 0;
_nop_();
SCL = 1; //時鐘線為高,通知從機開始接收數(shù)據(jù)
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 0;
}
_nop_();
_nop_();
SDA = 1; //釋放數(shù)據(jù)線,準備接受應(yīng)答位
_nop_();
_nop_();
SCL = 1;
_nop_();
_nop_();
_nop_();
if(SDA == 1) bAck =0;
else bAck = 1; //判斷是否收到應(yīng)答信號
SCL = 0;
_nop_();
_nop_();
}
//接收一個字節(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; //置時鐘線為低,準備接收
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 1; //置時鐘線為高使得數(shù)據(jù)有效
_nop_();
_nop_();
retc = retc << 1; //左移補零
if (SDA == 1)
retc = retc + 1; //當數(shù)據(jù)為1則收到的數(shù)據(jù)+1
_nop_();
_nop_();
}
SCL = 0;
_nop_();
_nop_();
return(retc); //返回收到的數(shù)據(jù)
}
主函數(shù)
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) //當壓力值介于15kpa到115kpa之間時,遵循線性變換
{
int vary=getdata; //yq= ( get_AD_result()*5.0/255.0/5.1-0.04 )/0.00369-3.45;
press = (vary*5.0/255.0/5.1+0.04)/0.004-3.45; //細調(diào)0.004數(shù)值
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; //取壓力值十分位
display();
if (temp > 100)
{
if(OverFlg == 1)
{
OverCounter++;
WIICByte(W24C04ADD,0x01,(OverCounter/0xff)); //低位
WIICByte(W24C04ADD,0x02,(OverCounter%0xff)); //高位
OverFlg = 0; //清除標志
}
}
}
}
}
設(shè)計報告
資料清單&&下載鏈接
網(wǎng)盤下載鏈接
- 常見使用問題及解決方法–必讀?。。。?/li>
- 源程序
- proteus仿真
- 開題報告
- 講解視頻
- 設(shè)計報告
Altium Designer 安裝破解
KEIL+proteus 單片機仿真設(shè)計教程
KEIL安裝破解
Proteus元器件查找
Proteus安裝
Proteus簡易使用教程
單片機學習資料
相關(guān)數(shù)據(jù)手冊
答辯技巧
設(shè)計報告常用描述
鼠標雙擊打開嘉盛單片機51 STM32單片機課程畢業(yè)設(shè)計.url