具体实现功能
由STC15W4K32S4单片机+二氧化碳传感器+LCD1602液晶显示屏+舵机+小纸板组成。
具体实现功能:
(1) 二氧化碳传感器测得二氧化碳数据后经过单片机处理,由LCD1602实时显示;
(2)测得二氧化碳浓度超过设定阙值,会进行自动开窗设置。
设计介绍
15W单片机
51单片是一种低功耗、高性能CMOS-8位微控制器,拥有灵巧的8位CPU和可编程Flash,使得51单片机为众多嵌入式控制应用系统提供灵活、高效的解决方案。具有以下标准功能:8k字节Flash,512字节RAM,32 位I/O 口线,看门狗定时器,内置4KB EEPROM,MAX810复位电路,三个16 位 定时器/计数器,一个6向量2级中断结构,全双工串行口。另外 STC89X51 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。最高运作频率35Mhz,6T/12T可选。
MH-Z19B二氧化碳传感器
基本介绍
引脚说明
模拟电压输出
硬件连接
将传感器的Vin-Gnd-Vo分别接至用户的5V-Gnd-对应引脚
LCD1602
基本介绍
引脚说明
显示方式
采用自定义字符
简易自动开窗设置
通过占空比控制舵机转动角度实现纸板的拖拽,进而实现自动开窗
程序实现
主函数
#include <15w.h>
#include "1602.h"
#include <intrins.h>
#define nop _nop_()//延迟
#define ADC_START 0x08//AD转换启动控制
#define ADC_FLAG 0x10//AD转换结束标志
#define ADRJ 0X20 //ADRJ=1
int i=5,j,n;
#define VCC 4.98
#define ulong unsigned long
#define uchar unsigned char
#define uint unsigned int
sbit duoji =P1^2;
signed int ch=2000;
unsigned int t;
char b[4]={0};
char*p=&b[0];
void Delay500ms() //@12.000MHz
{
unsigned char i, j, k;
i = 23;
j = 205;
k = 120;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay500us(unsigned int m) //@12.000MHz
{
while(m--)
{
unsigned char i, j;
i = 6;
j = 211;
do
{
while (--j);
} while (--i);
}
}
void IO_init() //设置串口双向输入
{
P0M0 = 0x00; P0M1 = 0x00;
P2M0 = 0x00; P2M1 = 0x00;
P1M0 = 0x00; P1M1 = 0x00;
}
void delay (long t)
{
t*=147;
while(t--);
}
void adc_init(void)
{
P1ASF=0X01;//设置P1为模拟量输入
CLK_DIV=CLK_DIV|0X20;//ADRJ=1
ADC_CONTR = 0X80|0X40|0X00; //设置电源开启、转换速度设置、AD输入端口
nop;nop;nop;nop;//延时4个机械周期
}
unsigned int ADC_DAT()//读取AD值
{
unsigned int i,j;
ADC_CONTR=ADC_CONTR|0X08;//开始转换
while((ADC_CONTR&0X10)!=0X10);//等待转换标志位
i=ADC_RES;
j=ADC_RESL;
i=i<<8;
i=i|j;
ADC_CONTR=ADC_CONTR&~0X10;//清零转换标志位
ADC_RES=0;//数据清零
ADC_RESL=0;//数据清零
return(i);
}
void main()
{
float Vin;
unsigned int ADvalue;
unsigned long tmp;
IO_init();
adc_init();
lcd_init();
while(1)
{
Delay500ms();
ADvalue = ADC_DAT();
Vin = VCC*ADvalue/1023*1000;
tmp=(Vin-0.4)/(2.0-0.4);
b[0]=tmp/1000;
b[1]=tmp%1000/100;
b[2]=tmp%1000%100/10;
b[3]=tmp%1000%100%10;
LcdShowInit(p);
if (tmp>= ch)
{
//90¶È
duoji=1;
Delay500us(3);
duoji=0;
Delay500us(37);
}
}
}
LCD设置相关函数
#include "1602.h"
#include "math.h"
unsigned char code a[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
void delay1ms(uint time)
{
uint i,j;
for(i=0;i<time;i++)
for(j=0;j<112;j++);
}
//写命令 com就是要写入的命令
void lcd_write_com(unsigned char com)
{
RS=0;
RW=0;
E=0;
P0=com;
delay1ms(2);
E=1;
delay1ms(2);
E=0;
}
//写数据 dat就是要写入的数据
void lcd_write_dat(unsigned char dat)
{
RS=1;
RW=0;
E=0;
P0=dat;
delay1ms(2);
E=1;
delay1ms(2);
E=0;
}
//初始化
void lcd_init()
{
lcd_write_com(0x38);//设置显示模式
lcd_write_com(0x0c);//开显示,不显示光标
lcd_write_com(0x06);//地址+1,当写入数据后光标右移
lcd_write_com(0x01);//清屏
lcd_write_com(0xd0);
}
//液晶光标定位函数
void LcdGotoXY(uchar line,uchar column)
{
//第一行
if(line==0)
lcd_write_com(0x80+column);
//第二行
if(line==1)
lcd_write_com(0x80+0x40+column);
}
//液晶输出字符串函数
void LcdPrintStr(uchar *str)
{
while(*str!='\0')
lcd_write_dat(*str++);
}
//开LCD1602显示
void LcdOn() //开显示器,关光标与闪烁
lcd_write_com(0x0c);
}
//关闭LCD1602显示,但DDRAM中内容不丢失,重开后将恢复内容
void LcdOff()
{
lcd_write_com(0x08);
}
//液晶显示内容和初始化
void LcdShowInit(char* p)
{
unsigned int i;
LcdGotoXY(0,0); //定位到第0行第0列
//静态显示
LcdPrintStr("CO2 concentration"); //第0行显示“”
LcdGotoXY(1,0); //定位到第1行第0列
//静态显示
for(i=0;i<4;i++)
{
unsigned char c=a[*p++];
lcd_write_dat(c);
}
}
//判忙
void lcd_read_busy()
{
unsigned char he,a;
RS=0;
RW=1;
E=1;
he=P0;
while(1)
{
he=P0;
E=0;
if(!(he&0x80))//当he&0x80为0时跳出循环,表示不忙
break;
E=1;
a++;
if(a>=10)
break;
}
}
LCD头文件
#include <15w.h>
#define uchar unsigned char
#define uint unsigned int
//三个引脚参考资料
sbit E= P1^5; //1602使能引脚
sbit RW=P1^4; //1602读写引脚
sbit RS=P1^3; //1602数据/命令选择引脚uint
void delay1ms(uint );
void lcd_write_com(unsigned char );
void lcd_write_dat(unsigned char dat);
void lcd_init(void);
void LcdGotoXY(uchar ,uchar );
void LcdPrintStr(uchar );
void LcdOn(void);
void LcdOff(void);
void LcdShowInit(char* p);
void lcd_read_busy(void);
void lcd_write_data(uint );