#基于STC89C52酒精浓度测试.docx
- 文档编号:4699803
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:21
- 大小:449.47KB
#基于STC89C52酒精浓度测试.docx
《#基于STC89C52酒精浓度测试.docx》由会员分享,可在线阅读,更多相关《#基于STC89C52酒精浓度测试.docx(21页珍藏版)》请在冰豆网上搜索。
#基于STC89C52酒精浓度测试
1.实验任务
设计一个基于单片机的酒精浓度检测系统,检测结果用LED或LCD显示器显示。
基于STC89C52单片机,MQ-3酒精浓度传感器,本设计设计一种具有检测及超限报警功能的酒精浓度测试系统。
2.设计方案
2.1硬件设计
由于本次设计需要用到单片机,来完成对酒精浓度的检测,分析了网上的相似课题,有很多是用酒精浓度传感器MQ-3来完成酒精浓度检测系统的设计。
鉴于本次时间限制,本次设计中采用的是STC89S52单片机来控制整个电路,电路中采用的是LCD1602来显示实验实时数据。
A/D芯片的选择中,用到的是TI公司生产的TLC549,主要是这块芯片的性能优良,时序操作简单,能很好的解决本次设计中对实时数据转换的要求。
系统结构框图如图1所示:
图1系统结构框图
2.1.1微控制单元STC89C52
基于本系统设计内容的需要,综合考虑后,我们选择STC89C52单片机为控制核心。
主要基于考虑STC89C52是低功耗,超低价,高速,高可靠,强抗静电,强抗干扰,功能强大的单片机。
STC89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,片内振荡器及时钟电路。
同时STC89C52可降至0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。
空闲方式停止CPU的工作,但允许RAM,定时/计数器,串行通信口及中断系统继续工作。
掉电方式保存RAM中的内容,但振荡器停止工作并禁止其他所有部件工作直到下一个硬件复位。
其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发本。
STC单片机有PDIP、PQFP/TQFP及PLCC等三种封装形式,以适应不同产品的需求。
STC89C52单片机引脚如图2:
图2STC89C52引脚图
•Vcc:
电源电压
•GND:
地
•P0口:
P0口是一组8位漏极开路型双向I/O口,也即地址/数据总线复用口。
•P1口:
P1是一个带内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。
•P2口:
P2是一个带有内部上拉电阻的8位双向I/O口,P2的输出缓冲级可驱(吸收或输出电流)4个TTL逻辑门电路。
•P3口:
P3口时一组带有内部上拉电阻的8位双向I/O口。
P3口输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。
•RST:
复位输入。
当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位。
•ALE:
当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。
一般情况下,ALE仍以时钟振荡频率的1/6输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。
•
:
程序储存允许(
)输出是外部程序存储器的读选通信号,当89C5X单片机由外部程序存储器取指令(或数据)时,每个机器周期两次
有效,即输出两个脉冲。
在次期间,当访问外部数据存储器,将跳过两次信号。
•
/VPP:
外部访问允许。
欲使CPU仅访问外部程序存储器(地址为0000H-FFFH),端必须保持低电平(接地)。
•XTAL1:
振荡器反相放大器及内部时钟发生器的输入端。
•XTAL2:
振荡器反相放大器的输出端
2.1.2MQ-3酒精传感器
MQ-3酒精传感器对乙醇蒸气有很高的灵敏度,并且响应和恢复快速。
另外,MQ-3酒精传感器简单的驱动回路和可靠的稳定性是相比较于其他型号传感器的优点。
MQ-3酒精传感器可用于机动车驾驶人员及其他严禁酒后作业人员的现场检测,也可用于其他场所乙醇蒸气的检测。
MQ-3酒精传感器有6只针状管脚,其中4个管脚(两个A和两个B)用于信号读取,两个H脚用于提供加热电流。
电路图如下图3:
图3MQ-3传感器电路原理图
2.1.3TLC549模数转换
TLC549是TI公司生产的一种低价位、高性能的8位A/D转换器,它以8位开关电容逐次逼近的方法实现A/D转换,其转换速度小于17us,最大转换速率为40000HZ,4MHZ典型内部系统时钟,电源为3V至6V。
它能方便地采用三线串行接口方式和各种微处理器连接,构成各种廉价的测控使用系统。
TLC549有8引脚,为双列直插是封装,起相应引脚功能如下:
REF+:
正基准电压输入2.5V≤REF+≤Vcc+0.1。
REF-:
负基准电压输入端,-0.1V≤REF-≤2.5V。
且要求:
(REF+)-(REF-)≥1V。
VCC:
系统电源3V≤Vcc≤6V。
GND:
接地端。
:
芯片选择输入端,要求输入高电平VIN≥2V,输入低电平VIN≤0.8V。
DATAOUT:
转换结果数据串行输出端,和TTL电平兼容,输出时高位在前,低位在后。
ANALOGIN:
模拟信号输入端,0≤ANALOGIN≤Vcc,当ANALOGIN≥REF+电压时,转换结果为全“1”(0FFH),ANALOGIN≤REF-电压时,转换结果为全“0”(00H)。
I/OCLOCK:
外接输入/输出时钟输入端,同于同步芯片的输入输出操作,无需和芯片内部系统时钟同步。
在实际使用过程中,起时序图如图4所示。
图4TLC549时序图
2.1.4LCD1602液晶显示
LCD1602字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16×1,16×2,20×2和40×2行等的液晶显示模块,模块组件内部主要由LCD显示屏、控制器、列驱动器和偏压产生电路构成。
2.2软件设计
2.2.1编译语言的选择
对于单片机的开发使用中,逐渐引入了高级语言,C语言就是其中的一种。
汇编语言的可控性较高级语言来说更具优越性。
程序编写语言比较常见的有C语言、汇编语言。
汇编语言的机器代码生成效率高,控制性好,但就是移植性不高。
C语言编写的程序比用汇编编写的程序更符合人们的思考习惯。
还有很多处理器都支持C编译器,这样意味着处理器也能很快上手。
且具有良好的模块化、容易阅读、维护等优点,且编写的模块程序易于移植。
基于C语言和汇编语言的优缺点,本系统采用C语言编写方法。
软件编写的主体思路是将系统按功能模块化划分,然后根据模块要实现的功能写各个子程序。
整个软件程序的编写采用查询式方式编写的。
2.2.2主程序模块
主程序实现的功能:
和硬件相结合实现酒精浓度检测系统的各个功能。
主要是检测和显示,门限调整和显示,检测数据显示功能子函数的调用。
见图5
图5主程序流程图
2.2.3A/D转换模块
(1)模数转换模块的主要功能就是将经放大器放大的模拟电压信号转化为MCU能够处理的数字信号,并传送给MCU。
(2)TLC549转换的流程图见下图6
图6数转换流程图
当
变为低电平后,TLC549芯片被选中,同时前次转换结果的最高有效位MSB(A7)自DATAOUT端输出,接着要求自I/OCLOCK端输入8个外部时钟信号,前7个I/OCLOCK信号的作用,是配合TLC549输出前次转换结果的A6-A0位,并为本次转换做准备:
在第4个I/OCLOCK信号由高至低的跳变之后,片内采样/保持电路对输入模拟量采样开始,第8个I/OCLOCK信号的下降沿使片内采样/保持电路进入保持状态并启动A/D开始转换。
转换时间为36个系统时钟周期,最大为17us。
直到A/D转换完成前的这段时间内,TLC549的控制逻辑要求:
或者
保持高电平,或者I/OCLOCK时钟端保持36个系统时钟周期的低电平。
由此可见,在自TLC549的I/OCLOCK端输入8个外部时钟信号期间需要完成以下工作:
读入前次A/D转换结果;对本次转换的输入模拟信号采样并保持;启动本次A/D转换开始。
2.2.4按键输入模块
(1)按键时显现人机对话的一个控制按钮,通过按键的操作,对系统进行发送操作指令,后经和MCU串行通信,然后在液晶上显示。
(2)按键查询式的流程图见下图7:
图7按键查询式的流程图
按键的四个键分别接P1.0,P1.1,P1.2,P1.3,由于P1口具有上拉电阻,所以不再需要加上拉电阻进行电压的放大。
2.2.5液晶显示输出模块
LCD1602模块在本系统中主要起着开界面数字显示,以及各控制效果的显示。
采用直接访问方式。
液晶显示的操作流程图见下图8:
图8液晶显示的操作流程图
液晶显示D0到D7口接P0.0到P0.7,单独使用一个口,为了避免数据的干扰,由于P0口没有上拉电阻,所以需要一个排阻进行电压的扩大.
3.实验结果
本次设计的酒精浓度检测系统,通过设计相关的硬件电路及进行相应的软件调试,最后实现了实时检测酒精浓度,并的在LCD1602上显示的目的。
设计出的电路,完全符合本次实验的设计要求,通过按键可以实现调整门限值,对于检测到的酒精浓度高于设定门限值时,会显示实时酒精浓度值,系统会自动实现灯光报警功能。
硬件成品图硬件上电开机界面
酒精浓度低红灯不报警酒精浓度高红灯报警
4.心得体会
通过本次课程设计,让我重新的系统的复习了微机原理和单片机方面的知识,收获颇丰。
首先,对于以前学习过的有关单片机方面的知识,在设计电路过程中又有了新的认识,对于各种概念的理解也有了提高。
在做板的过程中要非常小心。
硬件调试过程是相对繁锁的,要特别注意以下几点。
其一,通电之后看AT89S51晶振是否起振,晶振起振后是标准的正弦波,示波器测得其频率为11.0592MHz;其二,硬件电路的设计既要追求实际功能的实现,也要考虑元器件的购买方便。
在本次课设中学到的知识,我将它们发挥到其他的学习中去,也将在今后的学习中不断的提高和完善;而在此期间发现的不足,我将努力改善,通过学习实践等方式不断提高,克服那些知识障碍,以求在今后的学习过程中获得更大的进步!
附录
附录1参考文献
[1]《微机原理及使用》黄冰等编著重庆:
重庆大学出版社,2003
[2]李维提,郭强.《液晶显示使用技术》北京:
电子工业出版社,2000.
[3]《基于Proteus的电路及单片机系统设计和仿真》周润景等编著北京:
北京航空航天大学出版社,2006
[4]《单片机实验和实践教程》万光毅等编著北京:
北京航空航天大学出版社,2006
[5]《单片机人机接口实例集》公茂法等编著北京:
北京航空航天大学出版社,1997
[6]《单片机使用设计200例》张洪润等编著北京:
北京航空航天大学出版社,2006
[7]《单片机程序设计实例》先锋工作室编著北京:
清华大学出版社,2003
[8]《单片机C语言编程和实例》赵亮,侯国锐编著北京:
人民邮电出版社,2003
[9]《新编MCS-51单片机使用设计》张毅刚等编著哈尔滨:
哈尔滨工业大学出版社,2004
附录2硬件电路原理图
附录3硬件电路PCB图
附录4程序清单
主程序main.c
#include
#include
/*******************宏定义**********************/
#defineuintunsignedint
#defineucharunsignedchar
sbitk0=P1^0;//startthesystem
sbitk1=P1^1;//setupthestand_value
sbitk2=P1^2;//thestand_valueup
sbitk3=P1^3;//thestand_valuedown
sbitalarm=P2^0;//thealarmport
/*************************变量及字符串的定义*************************/
ucharLCD_Char[]="0123456789ABCDEF-.";
ucharLCD_string0[]="welcometoguet";
ucharLCD_string1[]="102021226";
ucharM_Time[]="2011--9--8";//showtime
ucharM_Detect[]="Detect:
";//检测
ucharM_Detect1[]="Alcohol:
";
ucharM_Detect2[]="set_val:
";
//ucharM_time1[]={"Time"};//时间
//ucharM_Storage[]={"Storage"};//memory
uintdata_temp=0;
uintflag=0;
/*******************函数声明**********************/
externvoidinitial_lcd1602(void);
externvoidDisplay_List_Char(ucharx,uchary,uchar*str);//theexternhavenomean,onlytoexplainthefunctionisintheotherfile
externvoidwrite_lcd_command(ucharwrite_data);//thefunctionofwritecommand
externvoidDisplay_One_Char(ucharx,uchary,uchardat);
externvoidwrite_lcd_command(ucharwrite_data);
externvoidxs_int(unsignedintshuju,bitt);
externunsignedcharADconv(void);
externvoiddisplay(unsignedintshuju,bitt);
/*******************子函数**********************/
voiddelay_ms(uintn)
{uinti,j;//delay10ms
for(i=n;i>0;i--)
{
for(j=1200;j>0;j--)
{
_nop_();
}
}
}
/******************主函数**********************/
voidmain()
{
uintset_value=200;//ismean20.0mg/ml;thebig_valueis800.0mg/mlmeanalcohol;alcoholdriveis20.0mg/100ml=0.2mg/ml
uchardata_char=0;
initial_lcd1602();
delay_ms(100);
Display_List_Char(0,0,LCD_string0);//welcome
delay_ms(100);//delay3s
Display_List_Char(1,0,LCD_string1);//welcome
delay_ms(300);
write_lcd_command(0x01);//cleanscreen
Display_List_Char(0,0,M_Time);//showtime
delay_ms(30);
Display_List_Char(0,0,M_Time);//showtime
delay_ms(100);
Display_List_Char(1,0,M_Detect);//showdetectinterface
delay_ms(100);
//Display_List_Char(1,0,M_Detect);//showdetectinterface
//delay_ms(300);
while
(1)
{
_nop_();
if(k0==0||k1==0||k2==0||k3==0)
{
if(k0==0)
{
flag=0;
Display_List_Char(1,0,M_Detect1);//showdetectinterface
delay_ms(50);
data_char=ADconv();
data_temp=data_char;
delay_ms(10);
xs_int(data_temp,1);
delay_ms(10);
if(data_temp>=set_value)
{
alarm=0;
}
else{alarm=1;}
}
if(k1==0)
{
Display_List_Char(1,0,M_Detect2);
xs_int(set_value,1);
flag=1;
}
if(k2==0&&flag==1)
{
delay_ms(10);
if(k2==0)
{
set_value=set_value+10;
xs_int(set_value,1);
}
delay_ms(50);
}
if(k3==0&&flag==1)
{
delay_ms(10);
if(k3==0)
{
set_value=set_value-10;
xs_int(set_value,1);
}
delay_ms(50);
}
}
}
}
显示程序LCD1602.c
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineLCDPORTP0
sbitRS=P2^5;//RS数据命令选择端,高电平数据,低电平命令
sbitRW=P2^6;//RW读写选择端,高电平读操作,低电平写操作
sbitEN=P2^7;//EN使能控制端,E高电平跳变为低电平时LCD执行命令
/******************************LCD1602驱动程序*************************************/
voidlcd_delay(uchardelaytime)
{
while(delaytime)delaytime--;
}
voidwrite_lcd_command(ucharwrite_command)
{
lcd_delay(40);
RS=0;
RW=0;
LCDPORT=write_command;
EN=1;
EN=0;
}
voidwrite_lcd_data(ucharwrite_data)
{
lcd_delay(40);
RS=1;
RW=0;
LCDPORT=write_data;
EN=1;
EN=0;
}
voidDisplay_One_Char(ucharx,uchary,uchardat)//x表示行,y表示列
{
switch(x)
{
case0:
write_lcd_command(0x80+y);
break;
case1:
write_lcd_command(0xc0+y);
break;
}
write_lcd_data(dat);
}
voidDisplay_List_Char(ucharx,uchary,uchar*str)
{
/*switch(x)
{
case0:
write_lcd_command(0x80+y);
break;
case1:
write_lcd_command(0xc0+y);
break;
}
while(*str!
='\0')
{
write_lcd_data(*str);
str++;
}
*/
while(*str!
='\0')
{
Display_One_Char(x,y,*str);
str++;
y++;
if(y==16)
{//若y等于16,进入if语句
y=0;x^=1;//y赋0,x和1按位异或取反
}
}
}
voidxs_int(unsignedintshuju,bitt)//显示一个数字
{unsignedinthuancun[6]={0};
unsignedcharbiaozhi=0,i;
if(shuju<10)biaozhi=1;
elseif(shuju<100)biaozhi=2;
elseif(shuju<1000)biaozhi=3;
elseif(shuju<10000)biaozhi=4;
elseif(shuju<=65535)biaozhi=5;
switch(biaozhi)
{case5:
huancun[0]=shuju/10000;
case4:
huancun[5]=shuju%10000/1000;
case3:
huancun[4]=shuju%1000/100;
case2:
huancun[3]=shuju%100/10;
case1:
huancun[1]=shuju%10;
break;
default:
break;
}
for(i=6;i>1;i--)
{if(i==3)Display_One_Char(t,12,'.');
elseDisplay_One_Char(t,15-i,0x30+huancun[i-1]);}
Display_One_Char(t,14,'m');
Display_One_Char(t,15,'g');
}
voiddisplay(unsignedintshuju,bitt)//显示一个数字
{unsignedinthuancun[6]={0};
unsignedcharbiaozhi=0,i;
if(shuju<10)biaozhi=1;
elseif(shuju<100)biaozhi=2;
elseif(shuju<1000)biaozhi=3;
elseif(shuju<10000)biaozhi=4;
elseif(shuju<=65535)biaozhi=5;
switch(biaozhi)
{case5:
huancun[5]=shuju/10000;
case4:
huancun[4]=shuju%10000/1000;
case3:
huancun[3]=shuju%1000/100;
case2:
huancun[2]=shuju%
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 STC89C52 酒精 浓度 测试