找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2416|回复: 0
收起左侧

单片机+MPX4115+MCP3204气压监测系统源程序(Proteus模拟仿真)

[复制链接]
ID:475148 发表于 2021-7-12 16:40 | 显示全部楼层 |阅读模式
做了Protues仿真的气压监测系统,通过对气压监测系统设计与仿真的学习与动手得出结论:通过以52单片机为主控芯片,MPX4115作为气压监测原件,以MCP3204作为AD数模转换芯片,并配以时钟芯片以及虚拟串口等,可成功实现气压监测系统设计与仿真,并实现以MPX4115为探测元件,结合单片机扩展电路组成气压监测系统,完成定时气压数据监测记录、显示远传等功能的硬件设计及软件编程。并配合上位机实现与PC机进行通信,对于实际工业生产具有实用价值。此种方式价格低廉其易于测试,实用价值大,经过技术升级和精度提升,可以用于实现气压监测报警。此系统有点延时,因为没用中断。中断一加上就不好使了,是自己技术问题。哈哈
需要学习的小伙伴可以下载学习。压缩包中第一个文件夹是KEIL工程,第2个文件是ISIS 7 Professional(Protues7.5工程文件),第3个是单片机上位机。虚拟串口软件可以百度下载
本系统还有很多不足,功能也较为简陋,有问题可以留言交流,
系统中有一个按键,可以切换时间显示还是气压显示,但需要摁多一点时间才能切换。
希望大家多多学习单片机知识,一起进步。

仿真原理图如下(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"};   //定义字符数组显示数字
  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” 数据;“0” 指令
  26. sbit RW  = P2^6;        //读写选择    “1”读;“0” 写
  27. sbit EN  = P2^7;
  28. sbit button=P2^0;       //使能    给个下降沿时执行命令
  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芯片的接口,数据输出端定义在P1.1引脚
  35. sbit RST=P1^2;    //位定义1302芯片的接口,复位端口定义在P1.1引脚
  36. sbit SCLK=P1^0;   //位定义1302芯片的接口,时钟输出端口定义在P1.1引脚
  37. //sfr  DBPort  = 0xb0;    //数据端口   在此选P3

  38.                         float fun (float h )//注意区分C语言中double和float类型所占存储空间
  39. {
  40.     int t;  //存储中间变量
  41.         t = (int)(h*100+5);//h乘以10的保留位数加一次方,再加5,如果大于10会有进位产生 除以10确保保留2位小数
  42.         return h = (float)t/100.0;//注意 此处和前行代码 都运用了强制转化
  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. 函数功能:延时若干微秒
  64. 入口参数:n
  65. ***************************************************/
  66. void delaynus(unsigned char n)
  67. {
  68. unsigned char i;
  69. for(i=0;i<n;i++)
  70.       ;
  71. }

  72. /*****************************************************
  73. 函数功能:向1302写一个字节数据
  74. 入口参数:x
  75. ***************************************************/
  76. void Write1302(unsigned char dat)
  77. {
  78.   unsigned char i;
  79.   SCLK=0;            //拉低SCLK,为脉冲上升沿写入数据做好准备
  80.   delaynus(2);       //稍微等待,使硬件做好准备
  81.   for(i=0;i<8;i++)      //连续写8个二进制位数据
  82.     {
  83.             DATA=dat&0x01;    //取出dat的第0位数据写入1302
  84.                 delaynus(2);       //稍微等待,使硬件做好准备
  85.                  SCLK=1;           //上升沿写入数据
  86.                  delaynus(2);      //稍微等待,使硬件做好准备
  87.                  SCLK=0;           //重新拉低SCLK,形成脉冲
  88.                  dat>>=1;          //将dat的各数据位右移1位,准备写入下一个数据位
  89.           }
  90.         
  91. }
  92. /*****************************************************
  93. 函数功能:根据命令字,向1302写一个字节数据
  94. 入口参数:Cmd,储存命令字;dat,储存待写的数据
  95. ***************************************************/
  96. void WriteSet1302(unsigned char Cmd,unsigned char dat)
  97. {
  98.    RST=0;           //禁止数据传递
  99.    SCLK=0;          //确保写数居前SCLK被拉低
  100.         RST=1;           //启动数据传输
  101.         delaynus(2);     //稍微等待,使硬件做好准备
  102.         Write1302(Cmd);  //写入命令字
  103.         Write1302(dat);  //写数据
  104.         SCLK=1;          //将时钟电平置于已知状态
  105.         RST=0;           //禁止数据传递
  106. }
  107. /*****************************************************
  108. 函数功能:从1302读一个字节数据
  109. 入口参数:x
  110. ***************************************************/
  111. unsigned char Read1302(void)
  112. {
  113.    unsigned char i,dat;
  114.         delaynus(2);       //稍微等待,使硬件做好准备
  115.         for(i=0;i<8;i++)   //连续读8个二进制位数据
  116.          {
  117.            dat>>=1;       //将dat的各数据位右移1位,因为先读出的是字节的最低位
  118.                 if(DATA==1)    //如果读出的数据是1
  119.                  dat|=0x80;    //将1取出,写在dat的最高位
  120.                  SCLK=1;       //将SCLK置于高电平,为下降沿读出
  121.                  delaynus(2);  //稍微等待
  122.                  SCLK=0;       //拉低SCLK,形成脉冲下降沿
  123.                  delaynus(2);  //稍微等待
  124.           }         
  125.   return dat;        //将读出的数据返回
  126. }  
  127. /*****************************************************
  128. 函数功能:根据命令字,从1302读取一个字节数据
  129. 入口参数:Cmd
  130. ***************************************************/
  131. unsigned char  ReadSet1302(unsigned char Cmd)
  132. {
  133.   unsigned char dat;
  134.   RST=0;                 //拉低RST
  135.   SCLK=0;                //确保写数居前SCLK被拉低
  136.   RST=1;                 //启动数据传输
  137.   Write1302(Cmd);       //写入命令字
  138.   dat=Read1302();       //读出数据
  139.   SCLK=1;              //将时钟电平置于已知状态
  140.   RST=0;               //禁止数据传递
  141.   return dat;          //将读出的数据返回
  142. }
  143. /*****************************************************
  144. 函数功能: 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);                 //根据写状态寄存器命令字,写入不保护指令
  153.    WriteSet1302(0x80,((miao/10)<<4|(miao%10)));   //根据写秒寄存器命令字,写入秒的初始值
  154.         WriteSet1302(0x82,((fen/10)<<4|(fen%10)));   //根据写分寄存器命令字,写入分的初始值
  155.         WriteSet1302(0x84,((shi/10)<<4|(shi%10))); //根据写小时寄存器命令字,写入小时的初始值
  156.         WriteSet1302(0x86,((ri/10)<<4|(ri%10))); //根据写日寄存器命令字,写入日的初始值
  157.         WriteSet1302(0x88,((yue/10)<<4|(yue%10))); //根据写月寄存器命令字,写入月的初始值
  158.         WriteSet1302(0x8c,((21/10)<<4|(21%10)));   //根据写小时寄存器命令字,写入小时的初始值
  159. }


  160. //向LCD写入命令或数据*********************************************************

  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)//写数据
  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,当写入数据的时候光标右移
  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读取的数据
  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);   //从秒寄存器读数据
  336.      second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化
  337.           ReadValue = ReadSet1302(0x83);  //从分寄存器读
  338.      minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化     
  339.      ReadValue = ReadSet1302(0x85);  //从分寄存器读
  340.      hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化                     
  341.      ReadValue = ReadSet1302(0x87);  //从分寄存器读
  342.      day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  343.           ReadValue = ReadSet1302(0x89);  //从分寄存器读
  344.      month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  345.           ReadValue = ReadSet1302(0x8d);  //从分寄存器读
  346.      year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
  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, 下载次数: 73)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表