本系统主要实现的功能为:温度采集电路实时采集环境中的温度,气体监测电路实时监测环境中的可燃气体(如甲烷、丙烷等),监测到的温度数据和可燃气体数据通过相应的传感器转换为模拟电信号送到AD转换器中,AD转换器将模拟信号转换为数字信号送到MCU中进行处理,MCU根据AD转换器送来的数字信号计算出温度值和有害气体浓度等级并送到显示模块进行显示,当温度值超过设定值时,风扇电路启动风扇工作,当可燃气体浓度超过设定等级时,报警电路启动蜂鸣器报警。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- #include <math.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define LCD1602_IO P0
- #define GPIO_MOTOR P1
- sbit LCD1602_RS=P2^0;
- sbit LCD1602_RW=P2^1;
- sbit LCD1602_E=P2^2;
- sbit ADC0832_CS=P1^5;
- sbit ADC0832_CLK=P1^6;
- sbit ADC0832_DO=P1^7; //将CS置高电平禁用芯片
- sbit MOTOR_CS=P2^3;
- sbit BUZZER_CS=P3^2;
- void Delay1ms(uint c);
- void LcdInit();
- void LcdWriteCom(uchar com);
- void LcdWriteData(uchar dat);
- uchar Get_AD_Result(bit channel);
- void Motor_stepper();
- uchar line1[]={'C','H','0',' ','T','E','P',':',' ','0','0','.','0',' ',0xdf,'C'};
- uchar line2[]={'C','H','1',' ','L','E','V','E','L',':',' ','0',' ',' ',' ',' '};
-
- void main(void)
- {
- uint i;
- double ADCdata,NTCr,t;
- int t_temp;
- bit channel;
- LcdInit();
- for(i=0;i<16;i++)
- {
- LcdWriteData(line1[i]);
- }
- LcdWriteCom(0x80|0x40); //设置数据指针起点为第二行
- for(i=0;i<16;i++)
- {
- LcdWriteData(line2[i]);
- }
- MOTOR_CS=1;
- BUZZER_CS=0;
- while(1)
- {
- channel = 0;
- ADCdata = Get_AD_Result(channel)*5.0/256;
- NTCr= 10*ADCdata/(5-ADCdata);
- t=1/(log(NTCr/10)/3900+1/(25+273.15))-273.15; //B=3435
-
- if(t>=25)
- {
- MOTOR_CS=0; //开风扇
- }
- else
- {
- MOTOR_CS=1; //关风扇
- }
-
- if(t<0)
- {
- line1[8]='-';
- t=-t;
- }
- else
- {
- line1[8]=' ';
- }
-
- t_temp=t*10;
- line1[9]=t_temp/100+'0';
- line1[10]=t_temp/10%10+'0';
- line1[12]=t_temp%10+'0';
- LcdWriteCom(0x80);
- for(i=0;i<16;i++)
- {
- LcdWriteData(line1[i]);
- }
- channel = 1;
- ADCdata = Get_AD_Result(channel)*5.0/256;
- if(ADCdata<=0.5)
- line2[11]='0';
- else if(ADCdata>0.5&&ADCdata<=1)
- line2[11]='1';
- else if(ADCdata>1&&ADCdata<=2)
- line2[11]='2';
- else if(ADCdata>2&&ADCdata<=3)
- line2[11]='3';
- else if(ADCdata>3&&ADCdata<=4)
- line2[11]='4';
- else
- line2[11]='5';
- if(ADCdata>1)
- BUZZER_CS=1;
- else
- BUZZER_CS=0;
- LcdWriteCom(0x80|0x40);
- for(i=0;i<16;i++)
- {
- LcdWriteData(line2[i]);
- }
- }
-
- }
- void Delay1ms(uint c) //误差 0us
- {
- uint a,b;
- for (; c>0; c--)
- {
- for (b=199;b>0;b--)
- {
- for(a=1;a>0;a--);
- }
- }
-
- }
- void LcdInit() //LCD初始化子程序
- {
- LcdWriteCom(0x38); //开显示,8位数据端口、两行显示、5x7点阵字符
- LcdWriteCom(0x0c); //开显示不显示光标
- LcdWriteCom(0x06); //写一个指针加1
- LcdWriteCom(0x01); //清屏
- LcdWriteCom(0x80); //设置数据指针起点为第一行第一个字符
- }
- /*******************************************************************************
- * 函 数 名 : LcdWriteCom
- * 函数功能 : 向LCD写入一个字节的命令
- * 输 入 : com
- * 输 出 : 无
- *******************************************************************************/
- void LcdWriteCom(uchar com) //写入命令
- {
- LCD1602_E = 0; //使能
- LCD1602_RS = 0; //选择发送命令
- LCD1602_RW = 0; //选择写入
-
- LCD1602_IO = com; //放入命令
- Delay1ms(1); //等待数据稳定
- LCD1602_E = 1; //写入时序
- Delay1ms(5); //保持时间
- LCD1602_E = 0;
- }
- /*******************************************************************************
- * 函 数 名 : LcdWriteData
- * 函数功能 : 向LCD写入一个字节的数据
- * 输 入 : dat
- * 输 出 : 无
- *******************************************************************************/
- void LcdWriteData(uchar dat) //写入数据
- {
- LCD1602_E = 0; //使能清零
- LCD1602_RS = 1; //选择输入数据
- LCD1602_RW = 0; //选择写入
- LCD1602_IO = dat; //写入数据
- Delay1ms(1);
- LCD1602_E = 1; //写入时序
- Delay1ms(5); //保持时间
- LCD1602_E = 0;
- }
- uchar Get_AD_Result(bit channel)
- {
- uchar i;
- int data1=0x00,data2=0x00;
- ADC0832_CLK=0; //初始化
- ADC0832_DO=1;
- _nop_();
- ADC0832_CS=0;
- _nop_();
- ADC0832_CLK=1;
- _nop_();
- //在第2、3个脉冲下沉之前DI端应输入2位数据用于选择通道功能
- ADC0832_CLK=0; //通道第一位
- ADC0832_DO=1;
- _nop_();
- ADC0832_CLK=1;
- _nop_();
- ADC0832_CLK=0; //通道0的第二位
- ADC0832_DO=channel;
- _nop_();
- ADC0832_CLK=1;
- _nop_();
-
- ADC0832_CLK=0;
- ADC0832_DO=1;
- for(i=0;i<8;i++) //读取前8位的值 先高位后低位
- {
- _nop_();
- data1<<=1;
- ADC0832_CLK=1;
- _nop_();
- ADC0832_CLK=0;
- if(ADC0832_DO)
- data1|=0x01;
- else
- data1|=0x00;
- }
- for(i=0;i<8;i++) //读取后8位的值 先低位后高位
- {
- data2>>=1;
- if(ADC0832_DO)
- data2|=0x80;
- else
- data2|=0x00;
- _nop_();
- ADC0832_CLK=1;
- _nop_();
- ADC0832_CLK=0;
- }
- _nop_();
- ADC0832_CS=1; //将CS置高电平禁用芯片
- ADC0832_DO=1;
- ADC0832_CLK=1;
- return (data1 == data2) ? data1:0;
- }
复制代码
所有资料51hei提供下载:
信息采集与处理-温度和可燃气体浓度采集模型.rar
(102.83 KB, 下载次数: 189)
|