找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3224|回復: 0
收起左側(cè)

單片機+MPX4115+MCP3204氣壓監(jiān)測系統(tǒng)源程序(Proteus模擬仿真)

[復制鏈接]
ID:475148 發(fā)表于 2021-7-12 16:40 | 顯示全部樓層 |閱讀模式
做了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仿真工程文件可到本帖附件中下載)
6.png

單片機源程序如下:
  1. #include<reg52.h>
  2. #include<INTRINS.H>

  3. #define  uchar  unsigned char      //8bit  0~255
  4. #define  schar  signed char        //8bit  -128~127
  5. #define  uint   unsigned int       //16bit 0~65536
  6. #define  sint   signed int         //16bit -32768~32767
  7. #define  slong   signed long         //32bit -214783648~2147483647         

  8. #define  delay1us  _nop_();_nop_();_nop_();            // delay 1 us(for fos=12M)
  9. unsigned char dispbuf[]="0123456789";
  10. unsigned char code Pre[]="Pressure:";
  11. unsigned char code Dat[]="Date:20";
  12. unsigned char code Warml[]="Warm:Too Low";
  13. unsigned char code Warmh[]="Warm:Too High";
  14. unsigned char code Normal[]="Normal";
  15.   unsigned char code Time[]="Time:";
  16. unsigned int A[]={ 48,49,50,51,52,53,54,55,56,57 } ;
  17. unsigned char code digit[10]={"0123456789"};   //定義字符數(shù)組顯示數(shù)字
  18. int i, yue,ri;shi,fen, miao,zs;
  19.    unsigned char second,minute,hour,day,month,year;      //分別儲存苗、分、小時,日,月,年
  20.   unsigned char ReadValue;

  21. sbit clk = P1^4;   // clock signel
  22. sbit dout = P1^5;  // data get out
  23. sbit din = P1^6 ;   // data put in
  24. sbit cs = P1^7;    // cs selt
  25. sbit RS  = P2^5;        //寄存器選擇, “1” 數(shù)據(jù);“0” 指令
  26. sbit RW  = P2^6;        //讀寫選擇    “1”讀;“0” 寫
  27. sbit EN  = P2^7;
  28. sbit button=P2^0;       //使能    給個下降沿時執(zhí)行命令
  29. sbit Q=          P2^1;
  30. sbit blue=P2^2;
  31. sbit red=P2^3;
  32. sbit green=P2^4;

  33.                                          
  34. sbit DATA=P1^1;   //位定義1302芯片的接口,數(shù)據(jù)輸出端定義在P1.1引腳
  35. sbit RST=P1^2;    //位定義1302芯片的接口,復位端口定義在P1.1引腳
  36. sbit SCLK=P1^0;   //位定義1302芯片的接口,時鐘輸出端口定義在P1.1引腳
  37. //sfr  DBPort  = 0xb0;    //數(shù)據(jù)端口   在此選P3

  38.                         float fun (float h )//注意區(qū)分C語言中double和float類型所占存儲空間
  39. {
  40.     int t;  //存儲中間變量
  41.         t = (int)(h*100+5);//h乘以10的保留位數(shù)加一次方,再加5,如果大于10會有進位產(chǎn)生 除以10確保保留2位小數(shù)
  42.         return h = (float)t/100.0;//注意 此處和前行代碼 都運用了強制轉(zhuǎn)化
  43. }



  44.                 void delay_50us(unsigned int t)         
  45. {
  46. unsigned int j,k;
  47. for (;t>0;t--)
  48. {
  49.   for(j=10;j>0;j--)
  50.   {
  51.    for(k=1;k>0;k--);
  52.   }
  53. }
  54. }

  55.            void delay2s(void)   //誤差 -0.000000000455us
  56. {
  57.     unsigned char a,b,c;
  58.     for(c=23;c>0;c--)
  59.         for(b=216;b>0;b--)
  60.             for(a=184;a>0;a--);
  61. }
  62. /*****************************************************
  63. 函數(shù)功能:延時若干微秒
  64. 入口參數(shù):n
  65. ***************************************************/
  66. void delaynus(unsigned char n)
  67. {
  68. unsigned char i;
  69. for(i=0;i<n;i++)
  70.       ;
  71. }

  72. /*****************************************************
  73. 函數(shù)功能:向1302寫一個字節(jié)數(shù)據(jù)
  74. 入口參數(shù):x
  75. ***************************************************/
  76. void Write1302(unsigned char dat)
  77. {
  78.   unsigned char i;
  79.   SCLK=0;            //拉低SCLK,為脈沖上升沿寫入數(shù)據(jù)做好準備
  80.   delaynus(2);       //稍微等待,使硬件做好準備
  81.   for(i=0;i<8;i++)      //連續(xù)寫8個二進制位數(shù)據(jù)
  82.     {
  83.             DATA=dat&0x01;    //取出dat的第0位數(shù)據(jù)寫入1302
  84.                 delaynus(2);       //稍微等待,使硬件做好準備
  85.                  SCLK=1;           //上升沿寫入數(shù)據(jù)
  86.                  delaynus(2);      //稍微等待,使硬件做好準備
  87.                  SCLK=0;           //重新拉低SCLK,形成脈沖
  88.                  dat>>=1;          //將dat的各數(shù)據(jù)位右移1位,準備寫入下一個數(shù)據(jù)位
  89.           }
  90.         
  91. }
  92. /*****************************************************
  93. 函數(shù)功能:根據(jù)命令字,向1302寫一個字節(jié)數(shù)據(jù)
  94. 入口參數(shù):Cmd,儲存命令字;dat,儲存待寫的數(shù)據(jù)
  95. ***************************************************/
  96. void WriteSet1302(unsigned char Cmd,unsigned char dat)
  97. {
  98.    RST=0;           //禁止數(shù)據(jù)傳遞
  99.    SCLK=0;          //確保寫數(shù)居前SCLK被拉低
  100.         RST=1;           //啟動數(shù)據(jù)傳輸
  101.         delaynus(2);     //稍微等待,使硬件做好準備
  102.         Write1302(Cmd);  //寫入命令字
  103.         Write1302(dat);  //寫數(shù)據(jù)
  104.         SCLK=1;          //將時鐘電平置于已知狀態(tài)
  105.         RST=0;           //禁止數(shù)據(jù)傳遞
  106. }
  107. /*****************************************************
  108. 函數(shù)功能:從1302讀一個字節(jié)數(shù)據(jù)
  109. 入口參數(shù):x
  110. ***************************************************/
  111. unsigned char Read1302(void)
  112. {
  113.    unsigned char i,dat;
  114.         delaynus(2);       //稍微等待,使硬件做好準備
  115.         for(i=0;i<8;i++)   //連續(xù)讀8個二進制位數(shù)據(jù)
  116.          {
  117.            dat>>=1;       //將dat的各數(shù)據(jù)位右移1位,因為先讀出的是字節(jié)的最低位
  118.                 if(DATA==1)    //如果讀出的數(shù)據(jù)是1
  119.                  dat|=0x80;    //將1取出,寫在dat的最高位
  120.                  SCLK=1;       //將SCLK置于高電平,為下降沿讀出
  121.                  delaynus(2);  //稍微等待
  122.                  SCLK=0;       //拉低SCLK,形成脈沖下降沿
  123.                  delaynus(2);  //稍微等待
  124.           }         
  125.   return dat;        //將讀出的數(shù)據(jù)返回
  126. }  
  127. /*****************************************************
  128. 函數(shù)功能:根據(jù)命令字,從1302讀取一個字節(jié)數(shù)據(jù)
  129. 入口參數(shù):Cmd
  130. ***************************************************/
  131. unsigned char  ReadSet1302(unsigned char Cmd)
  132. {
  133.   unsigned char dat;
  134.   RST=0;                 //拉低RST
  135.   SCLK=0;                //確保寫數(shù)居前SCLK被拉低
  136.   RST=1;                 //啟動數(shù)據(jù)傳輸
  137.   Write1302(Cmd);       //寫入命令字
  138.   dat=Read1302();       //讀出數(shù)據(jù)
  139.   SCLK=1;              //將時鐘電平置于已知狀態(tài)
  140.   RST=0;               //禁止數(shù)據(jù)傳遞
  141.   return dat;          //將讀出的數(shù)據(jù)返回
  142. }
  143. /*****************************************************
  144. 函數(shù)功能: 1302進行初始化設置
  145. ***************************************************/
  146. void Init_DS1302(void)
  147. {        

  148.           yue=5;
  149.           ri=24;
  150.           shi=20;fen=15;
  151.           miao=26;
  152.    WriteSet1302(0x8E,0x00);                 //根據(jù)寫狀態(tài)寄存器命令字,寫入不保護指令
  153.    WriteSet1302(0x80,((miao/10)<<4|(miao%10)));   //根據(jù)寫秒寄存器命令字,寫入秒的初始值
  154.         WriteSet1302(0x82,((fen/10)<<4|(fen%10)));   //根據(jù)寫分寄存器命令字,寫入分的初始值
  155.         WriteSet1302(0x84,((shi/10)<<4|(shi%10))); //根據(jù)寫小時寄存器命令字,寫入小時的初始值
  156.         WriteSet1302(0x86,((ri/10)<<4|(ri%10))); //根據(jù)寫日寄存器命令字,寫入日的初始值
  157.         WriteSet1302(0x88,((yue/10)<<4|(yue%10))); //根據(jù)寫月寄存器命令字,寫入月的初始值
  158.         WriteSet1302(0x8c,((21/10)<<4|(21%10)));   //根據(jù)寫小時寄存器命令字,寫入小時的初始值
  159. }


  160. //向LCD寫入命令或數(shù)據(jù)*********************************************************

  161. void write_com(unsigned com)//寫操縱
  162. {
  163.    EN=0;
  164.    RS=0;
  165.    RW=0;
  166.    P0=com;
  167.    delay_50us(1);
  168.    EN=1;
  169.    delay_50us(5);
  170.    EN=0;
  171. }

  172.                   void write_data(unsigned char dat)//寫數(shù)據(jù)
  173. {
  174.    EN=0;
  175.    RS=1;
  176.    RW=0;
  177.    P0=dat;
  178.    delay_50us(1);
  179.    EN=1;
  180.    delay_50us(5);
  181.    EN=0;
  182. }


  183. //初始化LCD***************************************************************
  184. void init(void)//初始化
  185. {
  186.      delay_50us(5);
  187.          write_com(0x38);
  188.          delay_50us(1);
  189.          write_com(0x38);
  190.          delay_50us(1);
  191.          write_com(0x38);
  192.          write_com(0x38);
  193.          write_com(0x08); //只開顯示
  194.          write_com(0x01); //清屏
  195.          write_com(0x06);//地址加1,當寫入數(shù)據(jù)的時候光標右移
  196.          write_com(0x0C); //開顯示,不顯示光標
  197.                  TMOD=0x21; //定時器 T1 PCON &= 0xef;
  198. SCON=0x50;
  199.         //TMOD=0x01;
  200.     TH0 = 0x0F8;
  201.     TL0 = 0x30;
  202.         EA=1;
  203.         ET0=1;
  204.         TR0=1;
  205. TH1=0xfd; //波特率設置為 9600
  206. TL1=0xfd;
  207. TR1=1; //開定時器 T1 運行控制位
  208. }  
  209.           void qingkong(void)//初始化
  210.           {
  211.                               for(i=0;i<20;i++)
  212.                 {
  213.                          write_data(' ');
  214.                           delay_50us(15);
  215.                 }
  216.          
  217.          
  218.          
  219.           }

  220. //顯示定位*******************************************************************
  221. void delay50ms(uint t)
  222. {
  223.                 uint j;
  224.                 for(t;t>0;t--)
  225.                 for(j=6245;j>0;j--);
  226. }

  227. sint getdata(uchar ch)   //ch=0xe0 選擇通道CH0; ch=0xe8 選擇通道CH1;ch=0xf0 選擇通道CH2;ch=0xf8 選擇通道CH3;
  228. {
  229.     sint  hd=0x00,ld=0x00,dat=0x00,t;
  230.         
  231.     //uchar ch=0xF8; //1 11 0 ;0 000

  232.     cs=1;
  233.     cs=0;
  234.    
  235.     clk=1;
  236.     for(t=0;t<6;t++)
  237.     {
  238.                         clk=0;//delay1us;
  239.                         if((0x80&ch)==0x80)
  240.                                         din=1;//dIN=1
  241.                         else
  242.                                         din=0;//dIN=0
  243.                                 
  244.                         ch<<=1;
  245.                         clk=1;//delay1us;
  246.     }

  247.                 for(t=0;t<13;t++)
  248.     {
  249.                                 clk=0;
  250.                                 hd<<=1;
  251.                                 clk=1;
  252.         delay1us;delay1us;delay1us;
  253.                                 hd|=dout;   
  254.                           delay1us;delay1us;delay1us;
  255.     }
  256.     cs=1;  
  257.     return hd;   
  258. }
  259.   void xianshiTIME(void)
  260.   {                          write_com(0x80);
  261.                            for(i=0;i<7;i++)
  262.                 {
  263.                                        
  264.                          write_data(Dat[i]);
  265.                           delay_50us(15);
  266.                 }
  267.                   write_com(0x80+0x40);
  268.                    for(i=0;i<5;i++)
  269.                 {
  270.                                    
  271.                          write_data(Time[i]);
  272.                           delay_50us(15);
  273.                 }
  274.                      write_com(0x87);
  275.                                  write_data(dispbuf[year/10]);
  276.                                  delay_50us(15);
  277.                                         write_data(dispbuf[year%10]);
  278.                                                 delay_50us(15);
  279.                                                    write_data('-');
  280.                                                           delay_50us(15);
  281.                                                                    write_data(dispbuf[month/10]);
  282.                                                           delay_50us(15);
  283.                                                                                  write_data(dispbuf[month%10]);
  284.                                                           delay_50us(15);
  285.                                                                                  write_data('-');
  286.                                                           delay_50us(15);
  287.                                                                                  write_data(dispbuf[day/10]);
  288.                                                           delay_50us(15);
  289.                                                                                          write_data(dispbuf[day%10]);
  290.                                                           delay_50us(15);
  291.                                                                                  write_com(0x87+0x13);
  292.                                                                                  for(i=0;i<5;i++)
  293.                                                                                  {
  294.                                                                                                    write_data(' ');
  295.                                                                                                                                         }
  296.                                                                         write_com(0x80+0x45);
  297.                                  write_data(dispbuf[hour/10]);
  298.                                                         delay_50us(15);
  299.                                                                                          write_data(dispbuf[hour%10]);
  300.                                                                                            delay_50us(15);
  301.                                                                                                                    write_data(':');
  302.                                                           delay_50us(15);
  303.                                                                                          write_data(dispbuf[minute/10]);
  304.                                                                                                    delay_50us(15);
  305.                                                                                                                          write_data(dispbuf[minute%10]);
  306.                                                                                                                                                                 write_data(':');
  307.                                                           delay_50us(15);
  308.                                                                                                                                  write_data(dispbuf[second/10]);
  309.                                                                                                    delay_50us(15);
  310.                                                                                                                          write_data(dispbuf[second%10]);
  311.                                                                                                                          qingkong();
  312.                                                                                                                                                 write_com(0x80+0x58);
  313.                                                                                                                                                                                       for(i=0;i<5;i++)
  314.                                                                                  {
  315.                                                                                                    write_data(' ');
  316.                                                                                                                                         }
  317.   }

  318. void main(void)
  319. {
  320.    sint data_qiya;     
  321.          float outdat_qiya,old_qiya;
  322.          int zs,send,warml,warmh,normal;
  323.      //儲存從1302讀取的數(shù)據(jù)
  324.    init();
  325.                    Init_DS1302();  
  326.         
  327.    while(1)
  328.    {
  329.    if(button==0)
  330.    {
  331.                           // delay_50us(15);
  332.    Q=~Q;
  333.            while(!button);
  334.    }
  335.                    ReadValue = ReadSet1302(0x81);   //從秒寄存器讀數(shù)據(jù)
  336.      second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//將讀出數(shù)據(jù)轉(zhuǎn)化
  337.           ReadValue = ReadSet1302(0x83);  //從分寄存器讀
  338.      minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數(shù)據(jù)轉(zhuǎn)化     
  339.      ReadValue = ReadSet1302(0x85);  //從分寄存器讀
  340.      hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數(shù)據(jù)轉(zhuǎn)化                     
  341.      ReadValue = ReadSet1302(0x87);  //從分寄存器讀
  342.      day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數(shù)據(jù)轉(zhuǎn)化
  343.           ReadValue = ReadSet1302(0x89);  //從分寄存器讀
  344.      month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數(shù)據(jù)轉(zhuǎn)化
  345.           ReadValue = ReadSet1302(0x8d);  //從分寄存器讀
  346.      year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將讀出數(shù)據(jù)轉(zhuǎn)化
  347.                   



  348.                                          
  349.                 data_qiya=getdata(0xe0);  //ch=0xe0 選擇通道CH0; ch=0xe8 選擇通道CH1;ch=0xf0 選擇通道CH2;ch=0xf8 選擇通道CH3;
  350.    // outdat_wendu=((float)data_wendu/4095)*5;

  351.                                               outdat_qiya=(10.0/23.0)*((float)data_qiya/16)+9.2;
  352.                                                  if(outdat_qiya!=old_qiya)
  353.                                                  {
  354.                                                  send=1        ;
  355.                                                  }           else
  356.                                                  {
  357.                                                  send=0;
  358.                                                  }
  359.                                                 old_qiya=outdat_qiya;                  
  360.                                                 
  361.                                                 
  362.                                                 // zs=(fun(outdat_qiya))*10;
  363.                                                                                                                     

  364.                          // press=((10.0/23.0)*(data_qiya/16))+9.3;
  365.     delay50ms(1);
  366.                                                  if(outdat_qiya<100)
  367.                                                 {        
  368.                                                          
  369.                                                  {
  370.                                                                                  if(outdat_qiya>90)

  371. ……………………

  372. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
7.5版本的仿真工程與程序資料51hei提供下載:
仿真程序.7z (455.35 KB, 下載次數(shù): 74)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表