做了Protues仿真的气压监测系统,通过对气压监测系统设计与仿真的学习与动手得出结论:通过以52单片机为主控芯片,MPX4115作为气压监测原件,以MCP3204作为AD数模转换芯片,并配以时钟芯片以及虚拟串口等,可成功实现气压监测系统设计与仿真,并实现以MPX4115为探测元件,结合单片机扩展电路组成气压监测系统,完成定时气压数据监测记录、显示远传等功能的硬件设计及软件编程。并配合上位机实现与PC机进行通信,对于实际工业生产具有实用价值。此种方式价格低廉其易于测试,实用价值大,经过技术升级和精度提升,可以用于实现气压监测报警。此系统有点延时,因为没用中断。中断一加上就不好使了,是自己技术问题。哈哈
需要学习的小伙伴可以下载学习。压缩包中第一个文件夹是KEIL工程,第2个文件是ISIS 7 Professional(Protues7.5工程文件),第3个是单片机上位机。虚拟串口软件可以百度下载
本系统还有很多不足,功能也较为简陋,有问题可以留言交流,
系统中有一个按键,可以切换时间显示还是气压显示,但需要摁多一点时间才能切换。
希望大家多多学习单片机知识,一起进步。
仿真原理图如下(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"}; //定义字符数组显示数字
- 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” 数据;“0” 指令
- sbit RW = P2^6; //读写选择 “1”读;“0” 写
- sbit EN = P2^7;
- sbit button=P2^0; //使能 给个下降沿时执行命令
- sbit Q= P2^1;
- sbit blue=P2^2;
- sbit red=P2^3;
- sbit green=P2^4;
-
- sbit DATA=P1^1; //位定义1302芯片的接口,数据输出端定义在P1.1引脚
- sbit RST=P1^2; //位定义1302芯片的接口,复位端口定义在P1.1引脚
- sbit SCLK=P1^0; //位定义1302芯片的接口,时钟输出端口定义在P1.1引脚
- //sfr DBPort = 0xb0; //数据端口 在此选P3
- float fun (float h )//注意区分C语言中double和float类型所占存储空间
- {
- int t; //存储中间变量
- t = (int)(h*100+5);//h乘以10的保留位数加一次方,再加5,如果大于10会有进位产生 除以10确保保留2位小数
- return h = (float)t/100.0;//注意 此处和前行代码 都运用了强制转化
- }
- 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--);
- }
- /*****************************************************
- 函数功能:延时若干微秒
- 入口参数:n
- ***************************************************/
- void delaynus(unsigned char n)
- {
- unsigned char i;
- for(i=0;i<n;i++)
- ;
- }
- /*****************************************************
- 函数功能:向1302写一个字节数据
- 入口参数:x
- ***************************************************/
- void Write1302(unsigned char dat)
- {
- unsigned char i;
- SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
- delaynus(2); //稍微等待,使硬件做好准备
- for(i=0;i<8;i++) //连续写8个二进制位数据
- {
- DATA=dat&0x01; //取出dat的第0位数据写入1302
- delaynus(2); //稍微等待,使硬件做好准备
- SCLK=1; //上升沿写入数据
- delaynus(2); //稍微等待,使硬件做好准备
- SCLK=0; //重新拉低SCLK,形成脉冲
- dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位
- }
-
- }
- /*****************************************************
- 函数功能:根据命令字,向1302写一个字节数据
- 入口参数:Cmd,储存命令字;dat,储存待写的数据
- ***************************************************/
- void WriteSet1302(unsigned char Cmd,unsigned char dat)
- {
- RST=0; //禁止数据传递
- SCLK=0; //确保写数居前SCLK被拉低
- RST=1; //启动数据传输
- delaynus(2); //稍微等待,使硬件做好准备
- Write1302(Cmd); //写入命令字
- Write1302(dat); //写数据
- SCLK=1; //将时钟电平置于已知状态
- RST=0; //禁止数据传递
- }
- /*****************************************************
- 函数功能:从1302读一个字节数据
- 入口参数:x
- ***************************************************/
- unsigned char Read1302(void)
- {
- unsigned char i,dat;
- delaynus(2); //稍微等待,使硬件做好准备
- for(i=0;i<8;i++) //连续读8个二进制位数据
- {
- dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位
- if(DATA==1) //如果读出的数据是1
- dat|=0x80; //将1取出,写在dat的最高位
- SCLK=1; //将SCLK置于高电平,为下降沿读出
- delaynus(2); //稍微等待
- SCLK=0; //拉低SCLK,形成脉冲下降沿
- delaynus(2); //稍微等待
- }
- return dat; //将读出的数据返回
- }
- /*****************************************************
- 函数功能:根据命令字,从1302读取一个字节数据
- 入口参数:Cmd
- ***************************************************/
- unsigned char ReadSet1302(unsigned char Cmd)
- {
- unsigned char dat;
- RST=0; //拉低RST
- SCLK=0; //确保写数居前SCLK被拉低
- RST=1; //启动数据传输
- Write1302(Cmd); //写入命令字
- dat=Read1302(); //读出数据
- SCLK=1; //将时钟电平置于已知状态
- RST=0; //禁止数据传递
- return dat; //将读出的数据返回
- }
- /*****************************************************
- 函数功能: 1302进行初始化设置
- ***************************************************/
- void Init_DS1302(void)
- {
- yue=5;
- ri=24;
- shi=20;fen=15;
- miao=26;
- WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
- WriteSet1302(0x80,((miao/10)<<4|(miao%10))); //根据写秒寄存器命令字,写入秒的初始值
- WriteSet1302(0x82,((fen/10)<<4|(fen%10))); //根据写分寄存器命令字,写入分的初始值
- WriteSet1302(0x84,((shi/10)<<4|(shi%10))); //根据写小时寄存器命令字,写入小时的初始值
- WriteSet1302(0x86,((ri/10)<<4|(ri%10))); //根据写日寄存器命令字,写入日的初始值
- WriteSet1302(0x88,((yue/10)<<4|(yue%10))); //根据写月寄存器命令字,写入月的初始值
- WriteSet1302(0x8c,((21/10)<<4|(21%10))); //根据写小时寄存器命令字,写入小时的初始值
- }
- //向LCD写入命令或数据*********************************************************
- 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)//写数据
- {
- 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,当写入数据的时候光标右移
- 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读取的数据
- init();
- Init_DS1302();
-
- while(1)
- {
- if(button==0)
- {
- // delay_50us(15);
- Q=~Q;
- while(!button);
- }
- ReadValue = ReadSet1302(0x81); //从秒寄存器读数据
- second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化
- ReadValue = ReadSet1302(0x83); //从分寄存器读
- minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
- ReadValue = ReadSet1302(0x85); //从分寄存器读
- hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
- ReadValue = ReadSet1302(0x87); //从分寄存器读
- day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
- ReadValue = ReadSet1302(0x89); //从分寄存器读
- month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
- ReadValue = ReadSet1302(0x8d); //从分寄存器读
- year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
-
-
- 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, 下载次数: 74)
|