当前位置:文档之家› 基于单片机模块STC89C52模块的酒精浓度测试

基于单片机模块STC89C52模块的酒精浓度测试

目录目录 01. 实验任务 (1)2.设计方案 (1)2.1硬件设计 (1)2.1.1 MCU微控制单元 (1)2.1.2 MQ-3酒精传感器 (3)2.1.3 TLC549模数转换 (4)2.1.4 LCD1602液晶显示 (5)2.2软件设计 (5)2.2.1 编译语言的选择 (5)2.2.2 主程序模块 (5)2.2.3 A/D转换模块 (6)2.2.4 按键输入模块 (7)2.2.5 液晶显示输出模块 (8)3.实验结果 (9)4.心得体会 (10)附录 (11)附录1 参考文献 (11)附录2 硬件电路原理图 (12)附录3 硬件电路PCB图 (14)附录4 程序清单 (16)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:图2 STC89C52引脚图•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输出固定的脉冲信号,因此它可对外输出时钟或用于定时目的。

•PSEN:程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当89C5X 单片机由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲。

在次期间,当访问外部数据存储器,将跳过两次信号。

• EA/VPP:外部访问允许。

欲使CPU仅访问外部程序存储器(地址为0000H-FFFH),端必须保持低电平(接地)。

•XTAL1:振荡器反相放大器及内部时钟发生器的输入端。

•XTAL2:振荡器反相放大器的输出端2.1.2 MQ-3酒精传感器MQ-3酒精传感器对乙醇蒸气有很高的灵敏度,并且响应和恢复快速。

另外,MQ-3酒精传感器简单的驱动回路和可靠的稳定性是相比较于其他型号传感器的优点。

MQ-3酒精传感器可用于机动车驾驶人员及其他严禁酒后作业人员的现场检测,也可用于其他场所乙醇蒸气的检测。

MQ-3酒精传感器有6只针状管脚,其中4个管脚(两个A和两个B)用于信号读取,两个H脚用于提供加热电流。

电路图如下图3:图3 MQ-3传感器电路原理图2.1.3 TLC549模数转换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:接地端。

CS:芯片选择输入端,要求输入高电平VIN≥2V,输入低电平VIN≤0.8V。

DATA OUT:转换结果数据串行输出端,与 TTL 电平兼容,输出时高位在前,低位在后。

ANALOGIN:模拟信号输入端,0≤ANALOGIN≤Vcc,当ANALOGIN≥REF+电压时,转换结果为全“1”(0FFH),ANALOGIN≤REF-电压时,转换结果为全“0”(00H)。

I/O CLOCK:外接输入/输出时钟输入端,同于同步芯片的输入输出操作,无需与芯片内部系统时钟同步。

在实际使用过程中,起时序图如图4所示。

图4 TLC549时序图2.1.4 LCD1602液晶显示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.3 A/D转换模块(1)模数转换模块的主要功能就是将经放大器放大的模拟电压信号转化为MCU能够处理的数字信号,并传送给MCU。

(2)TLC549转换的流程图见下图6图6 数转换流程图当CS变为低电平后,TLC549芯片被选中,同时前次转换结果的最高有效位MSB (A7)自DATA OUT 端输出,接着要求自I/O CLOCK 端输入8个外部时钟信号,前7个I/O CLOCK信号的作用,是配合TLC549 输出前次转换结果的A6-A0 位,并为本次转换做准备:在第4个I/O CLOCK 信号由高至低的跳变之后,片内采样/保持电路对输入模拟量采样开始,第8个I/O CLOCK 信号的下降沿使片内采样/保持电路进入保持状态并启动A/D开始转换。

转换时间为36 个系统时钟周期,最大为17us。

直到A/D转换完成前的这段时间内,TLC549 的控制逻辑要求:或者CS保持高电平,或者I/O CLOCK 时钟端保持36个系统时钟周期的低电平。

由此可见,在自TLC549的I/O CLOCK 端输入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<reg52.h>#include<intrins.h>/*******************宏定义**********************/#define uint unsigned int#define uchar unsigned charsbit k0=P1^0; //start the systemsbit k1=P1^1; //setup the stand_valuesbit k2=P1^2; //the stand_value upsbit k3=P1^3; //the stand_value downsbit alarm=P2^0; //the alarm port/*************************变量及字符串的定义*************************/ uchar LCD_Char[]="0123456789ABCDEF-.";uchar LCD_string0[]="welcome to guet";uchar LCD_string1[]="102021226";uchar M_Time[]="2011--9--8";// show timeuchar M_Detect[]="Detect:"; //检测uchar M_Detect1[]="Alcohol:";uchar M_Detect2[]="set_val:";//uchar M_time1[]={"Time"}; //时间//uchar M_Storage[]={"Storage"}; //memoryuint data_temp=0;uint flag=0;/*******************函数声明**********************/extern void initial_lcd1602(void);extern void Display_List_Char(uchar x,uchar y,uchar *str); //the extern have no mean ,only to explain the function is in the other fileextern void write_lcd_command( uchar write_data); //the function of write commandextern void Display_One_Char(uchar x,uchar y,uchar dat);extern void write_lcd_command( uchar write_data);extern void xs_int(unsigned int shuju,bit t);extern unsigned char ADconv(void);extern void display(unsigned int shuju,bit t);/*******************子函数**********************/void delay_ms(uint n){ uint i,j; //delay 10msfor(i=n;i>0;i--){for(j=1200;j>0;j--){_nop_();}}}/******************主函数**********************/void main()uint set_value=200; //is mean 20.0mg/ml ; the big_value is 800.0mg/ml mean alcohol; alcohol drive is 20.0mg/100ml=0.2mg/mluchar data_char=0;initial_lcd1602();delay_ms(100);Display_List_Char(0,0,LCD_string0); //welcomedelay_ms(100); //delay 3sDisplay_List_Char(1,0,LCD_string1); //welcomedelay_ms(300);write_lcd_command(0x01); //clean screenDisplay_List_Char(0,0,M_Time); //show timedelay_ms(30);Display_List_Char(0,0,M_Time); //show timedelay_ms(100);Display_List_Char(1,0,M_Detect); //show detect interfacedelay_ms(100);// Display_List_Char(1,0,M_Detect); //show detect interface// 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); //show detect interface 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<reg52.h>#include<string.h>#define uchar unsigned char#define uint unsigned int#define LCDPORT P0sbit RS=P2^5; //RS数据命令选择端,高电平数据,低电平命令sbit RW=P2^6; //RW读写选择端,高电平读操作,低电平写操作sbit EN=P2^7; //EN使能控制端,E高电平跳变为低电平时LCD执行命令/******************************LCD1602驱动程序*************************************/void lcd_delay(uchar delaytime){while(delaytime)delaytime--;}void write_lcd_command(uchar write_command){lcd_delay(40);RS=0;RW=0;LCDPORT=write_command;EN=1;EN=0;}void write_lcd_data(uchar write_data){lcd_delay(40);RS=1;RW=0;LCDPORT=write_data;EN=1;EN=0;}void Display_One_Char( uchar x,uchar y,uchar dat) //x表示行,y表示列{switch(x){case 0:write_lcd_command(0x80+y);break;case 1:write_lcd_command(0xc0+y);break;}write_lcd_data(dat);}void Display_List_Char(uchar x,uchar y,uchar *str){/* switch(x){case 0:write_lcd_command(0x80+y);break;case 1: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按位异或取反}}}void xs_int(unsigned int shuju,bit t) //显示一个数字{unsigned int huancun[6]={0};unsigned char biaozhi=0,i;if (shuju < 10) biaozhi = 1;else if(shuju < 100) biaozhi = 2;else if(shuju < 1000) biaozhi = 3;else if(shuju < 10000) biaozhi = 4;else if(shuju <=65535) biaozhi = 5;switch(biaozhi){case 5:huancun[0] = shuju/10000;case 4:huancun[5] = shuju%10000/1000;case 3:huancun[4] = shuju%1000/100;case 2:huancun[3] = shuju%100/10;case 1:huancun[1] = shuju%10;break;default:break;}for(i=6;i>1;i--){if(i==3)Display_One_Char(t,12,'.');else Display_One_Char(t,15-i,0x30+huancun[i-1]); } Display_One_Char(t,14,'m');Display_One_Char(t,15,'g');}void display(unsigned int shuju,bit t) //显示一个数字{unsigned int huancun[6]={0};unsigned char biaozhi=0,i;if (shuju < 10) biaozhi = 1;else if(shuju < 100) biaozhi = 2;else if(shuju < 1000) biaozhi = 3;else if(shuju < 10000) biaozhi = 4;else if(shuju <=65535) biaozhi = 5;switch(biaozhi){case 5:huancun[5] = shuju/10000;case 4:huancun[4] = shuju%10000/1000;case 3:huancun[3] = shuju%1000/100;case 2:huancun[2] = shuju%100/10;case 1:huancun[1] = shuju%10;break;default:break;}for(i=6;i>1;i--){Display_One_Char(t,15-i,0x30+huancun[i-1]);}Display_One_Char(t,14,'*');Display_One_Char(t,15,'g');}void initial_lcd1602(void) //初始化LCD1602{uchar i;EN=0;for(i=200;i>0;i--)lcd_delay(248);write_lcd_command(0x38); //0x38命令,双行显示,显示5x7的点阵字符for(i=4;i>0;i--)lcd_delay(248);write_lcd_command(0x38); //再写一次0x38命令,双行显示,显示5x7的点阵字符for(i=4;i>0;i--)lcd_delay(248);write_lcd_command(0x0c); //无光标,不闪烁for(i=4;i>0;i--)lcd_delay(248);write_lcd_command(0x06); //光标右移,文字不移动for(i=4;i>0;i--)lcd_delay(248);write_lcd_command(0x01); //清屏for(i=4;i>0;i--)lcd_delay(248);}A/D转换程序Tlc549.c#include<reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit CLK = P3^4; /* AD时钟信号*/ sbit CS = P3^5; /* AD片选信号*/ sbit DOUT = P3^3; /* 数据输出*/uchar adc_result = 0; /* AD计算结果*/void delay(uchar us){while(us--);}/* 读取AD输出的8bit数据*/uchar ADconv(void){uchar data_out=0;uchar i;CS = 1;_nop_();CS = 0;for (i=0; i<8; i++) /* 读取8位数据*/{CLK = 0;data_out = (data_out<<1)|DOUT;CLK = 1;_nop_();}CLK = 0;CS = 1;delay(2); /*转换间隔延时21us以上*/ return(data_out);}。

相关主题