51单片机课程设计:基于MQ-3的酒精浓度报警器

发布者:advancement3最新更新时间:2021-06-29 来源: eefocus关键字:51单片机  MQ-3 手机看文章 扫描二维码
随时随地手机看文章

本程序用于将MQ-3上读取到的模拟信号转换为对应的数字信号,经51单片机处理后,在数码管显示,同时具有报警功能,当检测值高于预警值,蜂鸣器报警。除了可以检测MQ-3酒精浓度模块的AD值,也适用于MQ系列的其他模块,原理基本都相同,都是将读取到的AD值转换为数字信号,程序修改后,如果接线方法正确,可以在吉林农业大学51开发板上完美运行,相关工程文件以及开发板对应的电路图见最下方附件。


关于粘贴复制乱码的问题:如果程序复制到Keil编译器上出现注释乱码,可以先建一个.c文件,也就是说不在keil里面编辑,然后用记事本打开.c文件,将源码复制进去,再在keil中添加文件即可。


/*************************************说明***********************************

此程序只采集模块信号的大小 需要转换为对应的值 还需要转换公式   

连接方式见下方定义

关于接线  MQ7连接电源  然后AO接学校板子上A/D 模拟信号输入端

本例程可用于MQ系列模块,将对应的模拟信号转换为对应的数字信号显示出来

****************************************************************************/

#include              //头文件

#include  

#define uchar unsigned char   //宏定义无符号字符型

#define uint  unsigned  int   //宏定义无符号整型

#define GPIO_DIG P0//位选以及段选数据输出端口定义

unsigned char code DIG_CODE[10]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,

0x7f,0x6f}; //显示段码 数码管字跟

unsigned char DisplayData[8];

//用来存放要显示的8位数的值

sbit cs=P3^5;//分别接学校单片机的ADCS  ADRD  ADWR  

sbit rd=P3^6;

sbit wr=P3^7;

sbit CLK=P3^3;  //时钟脉冲  

sbit DUC=P2^2;//   DUC段选信号

sbit WEC=P2^3;//WEC    位选信号

sbit bell=P3^4;//连接蜂鸣器

sbit setwarn=P2^7;    //确定

sbit add=P2^6;//数值增加

sbit sub=P2^5;//数值减少

uint z,x,c,v,AD0809,date,ok;//定义数据类型

uint num;    //默认报警值

/*******************************************************************************

* 函 数 名         : Delay10ms

* 函数功能         : 延时函数,延时10ms

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/

void Delay10ms(unsigned int c)   //误差 0us

{

    unsigned char a, b;

//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//

    for (;c>0;c--)

    {

       for (b=38;b>0;b--)

       {

          for (a=130;a>0;a--);

       }

           

    }       

}


unsigned char Key_Scan()

{

    unsigned char keyValue = 0 , i; //保存键值

    //--检测按键1--//

    if (setwarn != 1)//检测按键K1是否按下

    {

        Delay10ms(1);//消除抖动

        if (setwarn != 1)//再次检测按键是否按下

        {

            keyValue = 3;

            i = 0;

            while ((i<50) && (setwarn != 1)) //检测按键是否松开

            {

                Delay10ms(1);

                i++;

            }

        }

    }

    //--检测按键1--//

    if (add != 1)//检测按键K1是否按下

    {

        Delay10ms(1);//消除抖动

        if (add!= 1)//再次检测按键是否按下

        {

            keyValue = 1;

            i = 0;

            while ((i<50) && (add != 1)) //检测按键是否松开

            {

                Delay10ms(1);

                i++;

            }

        }

    }

    //--检测按键1--//

    if (sub != 1)//检测按键K1是否按下

    {

        Delay10ms(1);//消除抖动

        if (sub!= 1)//再次检测按键是否按下

        {

            keyValue = 2;

            i = 0;

            while ((i<50) && (sub != 1)) //检测按键是否松开

            {

                Delay10ms(1);

                i++;

            }

        }

    }

    return keyValue;   //将读取到键值的值返回

}

/*******************************************************************************

* 函 数 名         : DigDisplay

* 函数功能         : 使用数码管显示

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/

void DigDisplay()

{

    unsigned char i;

    unsigned int j;

    for(i=0;i<8;i++)

    {

        WEC=1;DUC=0;

        switch(i) //位选,选择点亮的数码管,

        {

            case(0):

                GPIO_DIG=0x7F; break;//显示第0位

            case(1):

                GPIO_DIG=0xBF; break;//显示第1位

            case(2):

                GPIO_DIG=0xDF; break;//显示第2位

            case(3):

                GPIO_DIG=0xEF; break;//显示第3位

            case(4):

                GPIO_DIG=0xF7; break;//显示第4位

            case(5):

                GPIO_DIG=0xFB; break;//显示第5位

            case(6):

                GPIO_DIG=0xFD; break;//显示第6位

            case(7):

                GPIO_DIG=0xFE; break;//显示第7位

        }

        WEC=0;DUC=1;

        GPIO_DIG=DisplayData[i];//发送段码

        j=15; //扫描间隔时间设定

        while(j--);

            GPIO_DIG=0x00;//消隐

    }

}

/**********************************************************************

                数码管动态扫描

*********************************************************************/

void xianshi() //显示函数

    if(AD0809>250)

    AD0809=250;

    date=AD0809;

/******************************

    data为读取到的AD值,通过转换公式,可以将data转换为对应的酒精浓度显示出来

    需要自己查资料修改

**************************************/

    if(date>num)

    {

        bell=0;

    }

    else

    {

        bell=1;

    }

    //uint z,x,c,v;

    z=date/1000; //求千位

    x=date%1000/100; //求百位

    c=date%100/10; //求十位

    v=date%10; //求个位

    DisplayData[6]=DIG_CODE[z];

    DisplayData[5]=DIG_CODE[x];

    DisplayData[4]=DIG_CODE[c];

    DisplayData[3]=DIG_CODE[v];

    DigDisplay();

}

/*************************************************************************

                                CLK振荡信号

**************************************************************************/

void timer0( ) interrupt 1 //定时器0工作方式1

{

    TH0=(65536-2)/256;  //重装计数初值

    TL0=(65536-2)%256;  //重装计数初值

    CLK=!CLK;  //取反

}

/*************************************************************************

                                主函数

**************************************************************************/

void main()

    uint xx=0;

    num=100; 

    TMOD=0X01;  //定时器中断0

    bell=1;

    CLK=0;  //脉冲信号初始值为0

    TH0=(65536-2)/256;  //定时时间高八位初值

    TL0=(65536-2)%256;  //定时时间低八位初值

    EA=1;  //开CPU中断

    ET0=1;  //开T/C0中断

    TR0=1;

    cs=0;ok=0;

    while(1)

    {

        if(ok==1)   //无限循环

        {

            if(xx==20)

            {

                wr=0;      

                _nop_();

                wr=1;          

                _nop_();

                _nop_();

                rd=0;          

                _nop_();

                AD0809=P1;    //读取数据

                rd=1;         

                xx=0;

            }

            else

            {

                xx++;

            }

            xianshi();//数码管显示函数

        }

        else//以下为设置报警值代码

        {

            switch(Key_Scan())

            {

                case 3:

                    ok=1;

                break;

[1] [2]
关键字:51单片机  MQ-3 引用地址:51单片机课程设计:基于MQ-3的酒精浓度报警器

上一篇:单片机IO口模拟串口程序(发送+接收)
下一篇:单片机最小零碎[配图][超具体]

推荐阅读最新更新时间:2024-11-09 03:44

51单片机启动过程
STC8G2K64S4-48PIN 系列、STC8G2K64S2-48PIN 系列单片内部集成了 64K 字节【0000H-FFFFH】的 Flash 程序存储器(ROM)。 1:单片机复位后,程序计数器(PC)的内容为 0000H,从 flash的0000H 单元开始执行程序。【PC是一个16位的计数器。用于存放和指示下一条要执行的指令的地址。寻址范围达64KB。PC有自动加1功能,以实现程序的顺序执行。PC没有地址,是不可寻址的,无法用指令对它进行读写。但在执行转移、调用、返回等指令时能自动改变其内容,以改变程序的执行顺序。】 2:另外中断服务程序的入口地址(又称中断向量)也位于程序存储器单元。在程序存储器中,每个中断
[单片机]
基于51单片机的电子存包柜的设计
Small RTOS 对RAM 需求小,非常适合单片机这类资源比较少的系统上。RTOS 具有多任务处理,较强的实时性,可裁减的内核,使得实时应用程序的设计、扩展和维护变得更容易。RTOS 思想的引入,一改传统单片机软件设计方法,使其不再是单一线程结构方式,通过应用程序分割为若干独立的任务,RTOS 使得应用程序的设计过程大为简化。本文结合基于单片机的电子存包柜的软件设计,简要分析了Small RTOS 的设计思想及消息队列通信机制的应用。 1. Small RTOS51 的基本原理 Small RTOS51是一个很小的内核,完全集成在KEIL C51编译器中,仅占用较少的程序存储空间,可以在没有外挂数据存储器的51单片机系统中
[单片机]
基于<font color='red'>51单片机</font>的电子存包柜的设计
51单片机编程开发(一)之C语言基础一
C51编译器 51单片机开发编译有很多,现在比较有名的是IAR for 8051编译器和KEIL for C51编译器,但这两个软件都不是免费的,官网提高的免费版是有使用限制的。另外还有一些编译器是免费的,但需要一定基础,初学者就不推荐使用了,等你翅膀硬了之后在自己配置编译环境吧。 简单介绍两个免费编译器:可跨平台使用的开源编译器sdcc,有空可以自己查资料搭建一下,后期如果有时间我再做个教程吧。另外微软公司提供的Visual Studio Code这个免费又强大的代码编辑器配合一些三方插件工具也可以实现各种单片机编译功能,效果也不错,这个也以后再另说吧。IAR for 8051编译器和KEIL for C51编译器在官网都可
[单片机]
<font color='red'>51单片机</font>编程开发(一)之C语言基础一
如何使用8051单片机控制双向直流电机
如何将直流电机连接到8051单片机?在本文中,主要有8051单片机+DC电机系统两个部分。首先是带有控制电机所需程序的8051单片机,其次是合适的驱动电路。 大多数直流电机的功率要求远远超出了单片机的范围,而且在反转旋转方向时产生的电压尖峰更容易损坏单片机。因此将直流电机直接连接到单片机是不明智的,完美的解决方案是在单片机和直流电机之间使用电机驱动电路。 一、L293电机驱动芯片 L293是一款专用的H桥电机驱动器IC,采用16引脚封装。L293的电流容量为600mA/通道,电源电压范围为4.5至36VDC。它们配有内部高速钳位二极管,用于电感尖峰保护。L293的其他优点包括高抗噪性、内部ESD保护、热关断、每个通道的独立
[单片机]
如何使用80<font color='red'>51单片机</font>控制双向直流电机
51单片机STC89C52点亮多个LED(IO口的字节操作)
程序源码 /*-----------------------包含头文件区域-------------------------*/ #include reg52.h //单片机头文件 /*-----------------------主函数区域-----------------------------*/ void main() { P2=0x0F; //P2端口高四位输出低电平,低四位输出高电平,即D5~D8亮,D1~D4灭 while(1); //死循环,主程序停留在此不再往下执行 } 运行结果
[单片机]
<font color='red'>51单片机</font>STC89C52点亮多个LED(IO口的字节操作)
STC89C51单片机对LCD显示的串口调试关照强度程序设计
最近在调试传感器的那块程序,这里总结一下自己的心得。 调试程序的方法 方法1:led显示法,在程序中调用这一句函数led = 0;可以知道程序运行到哪里,为什么会出错,到什么地方陷入了死循环。 方法二:串口打印法,串口打印法可以知道函数输出的东西是什么,程序中只需要使用串口中断就可以了,关于串口怎么样使用,我觉得等一下我需要总结一下最近编程的问题。 现在这里要好好总结一下串口调试法,天祥哥在他的书上总结了串口调试的方法,开始的时候虽然开了一下,了解了他是什么情况,会用串口之外,其他的什么都不懂,到现在才真正明白串口中断的真正含义是什么,串口中断可以打断单片机的执行,让单片机在执行主函数的时候去执行别的函数。 // BH
[单片机]
AT89C51单片机与74LS164动态显示接口
AT89C51介绍 AT89C51是一种带4K字节FLASH存储器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压、高性能CMOS 8位微处理器,俗称单片机。 AT89C2051是一种带2K字节闪存可编程可擦除只读存储器的单片机。 单片机的可擦除只读存储器可以反复擦除1000次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪速存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C051是它的一种精简版本。AT89C51单片机为很多嵌入式控制系统提供了
[单片机]
AT89C<font color='red'>51单片机</font>与74LS164动态显示接口
51单片机学习笔记———6.中断法配置定时器
#include reg52.h sbit LED P0^4; void main() { EA = 1;//打开总中断 TMOD&=0xFC; TMOD|=0x01; TH0 = (65535-2000)/256;//定时2ms TL0 = (65535-2000)/%256; ET0 = 1; TR0 = 1; while(1) { ... } void interruptTime() interrupt 1 { static unsigned int n = 0; TH0 = (65535-2000)/256; TL0 = (65535-200
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved