做了Protues仿真的氣壓監(jiān)測系統(tǒng),通過對氣壓監(jiān)測系統(tǒng)設計與仿真的學習與動手得出結(jié)論:通過以52單片機為主控芯片,MPX4115作為氣壓監(jiān)測原件,以MCP3204作為AD數(shù)模轉(zhuǎn)換芯片,并配以時鐘芯片以及虛擬串口等,可成功實現(xiàn)氣壓監(jiān)測系統(tǒng)設計與仿真,并實現(xiàn)以MPX4115為探測元件,結(jié)合單片機擴展電路組成氣壓監(jiān)測系統(tǒng),完成定時氣壓數(shù)據(jù)監(jiān)測記錄、顯示遠傳等功能的硬件設計及軟件編程。并配合上位機實現(xiàn)與PC機進行通信,對于實際工業(yè)生產(chǎn)具有實用價值。此種方式價格低廉其易于測試,實用價值大,經(jīng)過技術(shù)升級和精度提升,可以用于實現(xiàn)氣壓監(jiān)測報警。此系統(tǒng)有點延時,因為沒用中斷。中斷一加上就不好使了,是自己技術(shù)問題。哈哈
需要學習的小伙伴可以下載學習。壓縮包中第一個文件夾是KEIL工程,第2個文件是ISIS 7 Professional(Protues7.5工程文件),第3個是單片機上位機。虛擬串口軟件可以百度下載
本系統(tǒng)還有很多不足,功能也較為簡陋,有問題可以留言交流,
系統(tǒng)中有一個按鍵,可以切換時間顯示還是氣壓顯示,但需要摁多一點時間才能切換。
希望大家多多學習單片機知識,一起進步。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #include<reg52.h>
- #include<INTRINS.H>
- #define uchar unsigned char //8bit 0~255
- #define schar signed char //8bit -128~127
- #define uint unsigned int //16bit 0~65536
- #define sint signed int //16bit -32768~32767
- #define slong signed long //32bit -214783648~2147483647
- #define delay1us _nop_();_nop_();_nop_(); // delay 1 us(for fos=12M)
- unsigned char dispbuf[]="0123456789";
- unsigned char code Pre[]="Pressure:";
- unsigned char code Dat[]="Date:20";
- unsigned char code Warml[]="Warm:Too Low";
- unsigned char code Warmh[]="Warm:Too High";
- unsigned char code Normal[]="Normal";
- unsigned char code Time[]="Time:";
- unsigned int A[]={ 48,49,50,51,52,53,54,55,56,57 } ;
- unsigned char code digit[10]={"0123456789"}; //定義字符數(shù)組顯示數(shù)字
- int i, yue,ri;shi,fen, miao,zs;
- unsigned char second,minute,hour,day,month,year; //分別儲存苗、分、小時,日,月,年
- unsigned char ReadValue;
- sbit clk = P1^4; // clock signel
- sbit dout = P1^5; // data get out
- sbit din = P1^6 ; // data put in
- sbit cs = P1^7; // cs selt
- sbit RS = P2^5; //寄存器選擇, “1” 數(shù)據(jù);“0” 指令
- sbit RW = P2^6; //讀寫選擇 “1”讀;“0” 寫
- sbit EN = P2^7;
- sbit button=P2^0; //使能 給個下降沿時執(zhí)行命令
- sbit Q= P2^1;
- sbit blue=P2^2;
- sbit red=P2^3;
- sbit green=P2^4;
-
- sbit DATA=P1^1; //位定義1302芯片的接口,數(shù)據(jù)輸出端定義在P1.1引腳
- sbit RST=P1^2; //位定義1302芯片的接口,復位端口定義在P1.1引腳
- sbit SCLK=P1^0; //位定義1302芯片的接口,時鐘輸出端口定義在P1.1引腳
- //sfr DBPort = 0xb0; //數(shù)據(jù)端口 在此選P3
- float fun (float h )//注意區(qū)分C語言中double和float類型所占存儲空間
- {
- int t; //存儲中間變量
- t = (int)(h*100+5);//h乘以10的保留位數(shù)加一次方,再加5,如果大于10會有進位產(chǎn)生 除以10確保保留2位小數(shù)
- return h = (float)t/100.0;//注意 此處和前行代碼 都運用了強制轉(zhuǎn)化
- }
- void delay_50us(unsigned int t)
- {
- unsigned int j,k;
- for (;t>0;t--)
- {
- for(j=10;j>0;j--)
- {
- for(k=1;k>0;k--);
- }
- }
- }
- void delay2s(void) //誤差 -0.000000000455us
- {
- unsigned char a,b,c;
- for(c=23;c>0;c--)
- for(b=216;b>0;b--)
- for(a=184;a>0;a--);
- }
- /*****************************************************
- 函數(shù)功能:延時若干微秒
- 入口參數(shù):n
- ***************************************************/
- void delaynus(unsigned char n)
- {
- unsigned char i;
- for(i=0;i<n;i++)
- ;
- }
- /*****************************************************
- 函數(shù)功能:向1302寫一個字節(jié)數(shù)據(jù)
- 入口參數(shù):x
- ***************************************************/
- void Write1302(unsigned char dat)
- {
- unsigned char i;
- SCLK=0; //拉低SCLK,為脈沖上升沿寫入數(shù)據(jù)做好準備
- delaynus(2); //稍微等待,使硬件做好準備
- for(i=0;i<8;i++) //連續(xù)寫8個二進制位數(shù)據(jù)
- {
- DATA=dat&0x01; //取出dat的第0位數(shù)據(jù)寫入1302
- delaynus(2); //稍微等待,使硬件做好準備
- SCLK=1; //上升沿寫入數(shù)據(jù)
- delaynus(2); //稍微等待,使硬件做好準備
- SCLK=0; //重新拉低SCLK,形成脈沖
- dat>>=1; //將dat的各數(shù)據(jù)位右移1位,準備寫入下一個數(shù)據(jù)位
- }
-
- }
- /*****************************************************
- 函數(shù)功能:根據(jù)命令字,向1302寫一個字節(jié)數(shù)據(jù)
- 入口參數(shù):Cmd,儲存命令字;dat,儲存待寫的數(shù)據(jù)
- ***************************************************/
- void WriteSet1302(unsigned char Cmd,unsigned char dat)
- {
- RST=0; //禁止數(shù)據(jù)傳遞
- SCLK=0; //確保寫數(shù)居前SCLK被拉低
- RST=1; //啟動數(shù)據(jù)傳輸
- delaynus(2); //稍微等待,使硬件做好準備
- Write1302(Cmd); //寫入命令字
- Write1302(dat); //寫數(shù)據(jù)
- SCLK=1; //將時鐘電平置于已知狀態(tài)
- RST=0; //禁止數(shù)據(jù)傳遞
- }
- /*****************************************************
- 函數(shù)功能:從1302讀一個字節(jié)數(shù)據(jù)
- 入口參數(shù):x
- ***************************************************/
- unsigned char Read1302(void)
- {
- unsigned char i,dat;
- delaynus(2); //稍微等待,使硬件做好準備
- for(i=0;i<8;i++) //連續(xù)讀8個二進制位數(shù)據(jù)
- {
- dat>>=1; //將dat的各數(shù)據(jù)位右移1位,因為先讀出的是字節(jié)的最低位
- if(DATA==1) //如果讀出的數(shù)據(jù)是1
- dat|=0x80; //將1取出,寫在dat的最高位
- SCLK=1; //將SCLK置于高電平,為下降沿讀出
- delaynus(2); //稍微等待
- SCLK=0; //拉低SCLK,形成脈沖下降沿
- delaynus(2); //稍微等待
- }
- return dat; //將讀出的數(shù)據(jù)返回
- }
- /*****************************************************
- 函數(shù)功能:根據(jù)命令字,從1302讀取一個字節(jié)數(shù)據(jù)
- 入口參數(shù):Cmd
- ***************************************************/
- unsigned char ReadSet1302(unsigned char Cmd)
- {
- unsigned char dat;
- RST=0; //拉低RST
- SCLK=0; //確保寫數(shù)居前SCLK被拉低
- RST=1; //啟動數(shù)據(jù)傳輸
- Write1302(Cmd); //寫入命令字
- dat=Read1302(); //讀出數(shù)據(jù)
- SCLK=1; //將時鐘電平置于已知狀態(tài)
- RST=0; //禁止數(shù)據(jù)傳遞
- return dat; //將讀出的數(shù)據(jù)返回
- }
- /*****************************************************
- 函數(shù)功能: 1302進行初始化設置
- ***************************************************/
- void Init_DS1302(void)
- {
- yue=5;
- ri=24;
- shi=20;fen=15;
- miao=26;
- WriteSet1302(0x8E,0x00); //根據(jù)寫狀態(tài)寄存器命令字,寫入不保護指令
- WriteSet1302(0x80,((miao/10)<<4|(miao%10))); //根據(jù)寫秒寄存器命令字,寫入秒的初始值
- WriteSet1302(0x82,((fen/10)<<4|(fen%10))); //根據(jù)寫分寄存器命令字,寫入分的初始值
- WriteSet1302(0x84,((shi/10)<<4|(shi%10))); //根據(jù)寫小時寄存器命令字,寫入小時的初始值
- WriteSet1302(0x86,((ri/10)<<4|(ri%10))); //根據(jù)寫日寄存器命令字,寫入日的初始值
- WriteSet1302(0x88,((yue/10)<<4|(yue%10))); //根據(jù)寫月寄存器命令字,寫入月的初始值
- WriteSet1302(0x8c,((21/10)<<4|(21%10))); //根據(jù)寫小時寄存器命令字,寫入小時的初始值
- }
- //向LCD寫入命令或數(shù)據(jù)*********************************************************
- void write_com(unsigned com)//寫操縱
- {
- EN=0;
- RS=0;
- RW=0;
- P0=com;
- delay_50us(1);
- EN=1;
- delay_50us(5);
- EN=0;
- }
- void write_data(unsigned char dat)//寫數(shù)據(jù)
- {
- EN=0;
- RS=1;
- RW=0;
- P0=dat;
- delay_50us(1);
- EN=1;
- delay_50us(5);
- EN=0;
- }
- //初始化LCD***************************************************************
- void init(void)//初始化
- {
- delay_50us(5);
- write_com(0x38);
- delay_50us(1);
- write_com(0x38);
- delay_50us(1);
- write_com(0x38);
- write_com(0x38);
- write_com(0x08); //只開顯示
- write_com(0x01); //清屏
- write_com(0x06);//地址加1,當寫入數(shù)據(jù)的時候光標右移
- write_com(0x0C); //開顯示,不顯示光標
- TMOD=0x21; //定時器 T1 PCON &= 0xef;
- SCON=0x50;
- //TMOD=0x01;
- TH0 = 0x0F8;
- TL0 = 0x30;
- EA=1;
- ET0=1;
- TR0=1;
- TH1=0xfd; //波特率設置為 9600
- TL1=0xfd;
- TR1=1; //開定時器 T1 運行控制位
- }
- void qingkong(void)//初始化
- {
- for(i=0;i<20;i++)
- {
- write_data(' ');
- delay_50us(15);
- }
-
-
-
- }
- //顯示定位*******************************************************************
- void delay50ms(uint t)
- {
- uint j;
- for(t;t>0;t--)
- for(j=6245;j>0;j--);
- }
- sint getdata(uchar ch) //ch=0xe0 選擇通道CH0; ch=0xe8 選擇通道CH1;ch=0xf0 選擇通道CH2;ch=0xf8 選擇通道CH3;
- {
- sint hd=0x00,ld=0x00,dat=0x00,t;
-
- //uchar ch=0xF8; //1 11 0 ;0 000
- cs=1;
- cs=0;
-
- clk=1;
- for(t=0;t<6;t++)
- {
- clk=0;//delay1us;
- if((0x80&ch)==0x80)
- din=1;//dIN=1
- else
- din=0;//dIN=0
-
- ch<<=1;
- clk=1;//delay1us;
- }
- for(t=0;t<13;t++)
- {
- clk=0;
- hd<<=1;
- clk=1;
- delay1us;delay1us;delay1us;
- hd|=dout;
- delay1us;delay1us;delay1us;
- }
- cs=1;
- return hd;
- }
- void xianshiTIME(void)
- { write_com(0x80);
- for(i=0;i<7;i++)
- {
-
- write_data(Dat[i]);
- delay_50us(15);
- }
- write_com(0x80+0x40);
- for(i=0;i<5;i++)
- {
-
- write_data(Time[i]);
- delay_50us(15);
- }
- write_com(0x87);
- write_data(dispbuf[year/10]);
- delay_50us(15);
- write_data(dispbuf[year%10]);
- delay_50us(15);
- write_data('-');
- delay_50us(15);
- write_data(dispbuf[month/10]);
- delay_50us(15);
- write_data(dispbuf[month%10]);
- delay_50us(15);
- write_data('-');
- delay_50us(15);
- write_data(dispbuf[day/10]);
- delay_50us(15);
- write_data(dispbuf[day%10]);
- delay_50us(15);
- write_com(0x87+0x13);
- for(i=0;i<5;i++)
- {
- write_data(' ');
- }
- write_com(0x80+0x45);
- write_data(dispbuf[hour/10]);
- delay_50us(15);
- write_data(dispbuf[hour%10]);
- delay_50us(15);
- write_data(':');
- delay_50us(15);
- write_data(dispbuf[minute/10]);
- delay_50us(15);
- write_data(dispbuf[minute%10]);
- write_data(':');
- delay_50us(15);
- write_data(dispbuf[second/10]);
- delay_50us(15);
- write_data(dispbuf[second%10]);
- qingkong();
- write_com(0x80+0x58);
- for(i=0;i<5;i++)
- {
- write_data(' ');
- }
- }
- void main(void)
- {
- sint data_qiya;
- float outdat_qiya,old_qiya;
- int zs,send,warml,warmh,normal;
- //儲存從1302讀取的數(shù)據(jù)
- init();
- Init_DS1302();
-
- while(1)
- {
- if(button==0)
- {
- // delay_50us(15);
- Q=~Q;
- while(!button);
- }
- ReadValue = ReadSet1302(0x81); //從秒寄存器讀數(shù)據(jù)
- second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//將讀出數(shù)據(jù)轉(zhuǎn)化
- ReadValue = ReadSet1302(0x83); //從分寄存器讀
- minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數(shù)據(jù)轉(zhuǎn)化
- ReadValue = ReadSet1302(0x85); //從分寄存器讀
- hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數(shù)據(jù)轉(zhuǎn)化
- ReadValue = ReadSet1302(0x87); //從分寄存器讀
- day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數(shù)據(jù)轉(zhuǎn)化
- ReadValue = ReadSet1302(0x89); //從分寄存器讀
- month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數(shù)據(jù)轉(zhuǎn)化
- ReadValue = ReadSet1302(0x8d); //從分寄存器讀
- year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數(shù)據(jù)轉(zhuǎn)化
-
-
- data_qiya=getdata(0xe0); //ch=0xe0 選擇通道CH0; ch=0xe8 選擇通道CH1;ch=0xf0 選擇通道CH2;ch=0xf8 選擇通道CH3;
- // outdat_wendu=((float)data_wendu/4095)*5;
- outdat_qiya=(10.0/23.0)*((float)data_qiya/16)+9.2;
- if(outdat_qiya!=old_qiya)
- {
- send=1 ;
- } else
- {
- send=0;
- }
- old_qiya=outdat_qiya;
-
-
- // zs=(fun(outdat_qiya))*10;
-
- // press=((10.0/23.0)*(data_qiya/16))+9.3;
- delay50ms(1);
- if(outdat_qiya<100)
- {
-
- {
- if(outdat_qiya>90)
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼7.5版本的仿真工程與程序資料51hei提供下載:
仿真程序.7z
(455.35 KB, 下載次數(shù): 74)
2021-7-12 17:40 上傳
點擊文件名下載附件
|