找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8237|回复: 1
打印 上一主题 下一主题
收起左侧

单片机+酒精传感器检测实验源码+电路原理详解

[复制链接]
跳转到指定楼层
楼主
ID:418816 发表于 2018-10-31 22:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
实验1 酒精传感器实验
1.实验目的
学习酒精检测传感器MQ-3的使用方法;
2.实验设备
硬件:酒精传感器节点,串口线;
软件:Keil u Vision4编译软件,STC下载软件STC_ISP;
芯片手册:配套光盘\附件\芯片手册\酒精检测传感器
电路原理图路径:配套光盘\附件\电路原理图;
源码路径:配套光盘\源代码\传感器原理与应用\实验1 酒精传感器实验-V20161122
hex文件路径:配套光盘\源代码\传感器原理与应用\实验1 酒精传感器实验-V20161122\out
3.实验原理
3.1MQ-3的介绍
  MQ-3气体传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡(SnO2)。当传感器所处环境中存在酒精蒸汽时,传感器的电导率随空气中酒精气体浓度的增加而增大。使用简单的电路即可将电导率的变化转换为与该气体浓度相对应的输出信号。
MQ-3气体传感器对酒精的灵敏度高,可以抵抗汽油、烟雾、水蒸气的干扰。这种传感器可检测多种浓度酒精气氛,是一款适合多种应用的低成本传感器。
元器件结构外形如图3.1:

图3.1  酒精传感器形型
图3.2  酒精传感器基本测试电路

基本测试回路,图3.2是酒精传感器的基本测试电路。该传感器需要施加2个电压:加热器电压(VH)和测试电压(VC)。其中 VH用于为传感器提供特定的工作温度。VC 则是用于测定与传感器串联的负载电阻(RL)上的电压(VRL)。这种传感器具有轻微的极性,VC需用直流电源。在满足传感器电性能要求的前提下,VC和VH可以共用同一个电源电路。为更好利用传感器的 性能,需要选择恰当的RL值。酒精传感器的技术指标如表1。
表1  酒精传感器技术指
产品型号
MQ-3
产品类型
半导体气敏元件
标准封装
胶木(黑胶木)
检测气体
酒精蒸汽
检测浓度
0.04-4mg/L酒精
标准电路条件
回路电压
Vc
≤24V DC
加热电压
VH
5.0V±0.2V ACorDC
负载电阻
RL
可调
标准测试条件下气敏元件特性
加热电阻
RH
31Ω±3Ω(室温)
加热功耗
PH
≤900mW
敏感体表面电阻
Rs
2KΩ-20KΩ(in 0.4mg/L酒精)
灵敏度
S
Rs(in air)/Rs(0.4mg/L酒精)≥5
浓度斜率
α
≤0.6(R300ppm/R100ppm酒精)
标准测试条件
温度、湿度
20℃±2℃;65%±5%RH
标准测试电路
Vc:5.0V±0.1V;
VH: 5.0V±0.1V
预热时间
不少于48小时

酒精传感器灵敏度特性图3.3所示:
图3.3  酒精传感器灵敏度特性图

3.2 MQ-3酒精传感器的电路原理图
MQ-3酒精传感器的电路原理如图3.4所示:
图3.4  酒精传感器电路
其中U1(MQ-3)的PIN5与PIN2为加热端,对应测试回路的H端;PIN1、PIN3、PIN4、PIN6为检测回路;MQ-3传感器的供电电压Vc和加热电压Vh都为5V,负载电阻R1为1K欧姆。从技术指标表中可知,在0.4mg/L酒精中,传感器电阻Rs为2K~20K,取Rs = 12K。假设检测到酒精浓度为10mg/L时报警,由灵敏度特性曲线可知灵敏度为0.12,MQ3电阻值为12K * 0.12 = 1.44K(Rs / Ro = 灵敏度,其中Ro为传感器在0.4mg/L酒精时的电阻值),ADC1(P1.1) = 5V * 1K / (1K + 1.44K) = 2.00V,AD读数为2.00 / 3.3 * 1024 = 620,当AD采集的数值大于620时表明检测到酒精。
4.实验步骤
4.1 编写实验源代码文件
4.1.1 取酒精传感器节点,打开Keil集成开发环境,打开配套光盘\源代码\传感器原理与应用\实验1 酒精传感器实验-V20161122的工程文件。
4.1.2点击左上角的Rebuild按键,编译整个工程,将生成jiujing.hex可执行文件,该可执行文件自动保存在配套光盘\源代码\传感器原理与应用\实验1 酒精传感器实验-V20161122\out目录下。(注意:请根据该目录下 jiujing.hex 文件的生成时间,判断该文件是否是自己刚刚编译完成的。)
4.1.3 使用串口线将电脑与酒精传感器节点的串口相连,将酒精传感器节点上的S1开关拨打到左边,让STC单片机和DB9相连。
4.1.4 根据 配套光盘\第三方应用软件\STC_ISP的STC-ISP软件使用说明书-甄鹏-V20160423,使用STC-ISP软件将4.1.2步中生成的可执行jiujing.hex文件通过STC_ISP串口下载软件下载进STC单片机中。
4.2  实验源代码解析
  1. /**********************************************************/
  2. //晶振频率:11.0592MHz
  3. //文件名  :Main.c
  4. //功能说明:酒精传感器读取实验
  5. //制作    :www.frotech.com
  6. //技术支持:020-22883196 QQ:
  7. //变更记录: 2016.11.22
  8. //变更内容: 新建造
  9. /**********************************************************/

  10. #include <STC12C5A60S2.h>


  11. #define                            BUF_LENTH              128                            //定义串口接收缓冲长度
  12. #define     uint unsigned int
  13. #define     uchar unsigned char
  14. unsigned char               uart1_wr;                            //写指针
  15. unsigned char               uart1_rd;                            //读指针
  16. unsigned char               xdata RX0_Buffer[BUF_LENTH];              //接收缓冲
  17. unsigned char flag;
  18. unsigned char i;
  19. unsigned char   xdata mbus_buffer[255];
  20. unsigned char   xdata mbus_Sendbuf[255];
  21. unsigned char   xdata Crc_buf[2];  //声明存储CRC校验值的高8位及低8位的缓存
  22. unsigned int  Crc_return_data;  //声明CRC校验值
  23. bit                            B_TI; //发送完成标志
  24. sbit  P1_0 = P1^0;//定义P1.0端口
  25. //                                                                                                                7       6      5       4         3      2    1    0   Reset Value
  26. //sfr ADC_CONTR = 0xBC;                            ADC_POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0 0000,0000              //AD 转换控制寄存器
  27. #define ADC_OFF()              ADC_CONTR = 0
  28. #define ADC_ON                            (1 << 7)
  29. #define ADC_90T                            (3 << 5)
  30. #define ADC_180T              (2 << 5)
  31. #define ADC_360T              (1 << 5)
  32. #define ADC_540T              0
  33. #define ADC_FLAG              (1 << 4)              //软件清0
  34. #define ADC_START              (1 << 3)              //自动清0
  35. #define ADC_CH0                            0
  36. #define ADC_CH1                            1
  37. #define ADC_CH2                            2
  38. #define ADC_CH3                            3
  39. #define ADC_CH4                            4
  40. #define ADC_CH5                            5
  41. #define ADC_CH6                            6
  42. #define ADC_CH7                            7

  43. uint adc10_start(uchar channel);
  44. void              uart1_init(void);
  45. void Uart1_TxByte(unsigned char dat);
  46. void Uart1_String(unsigned char code *puts);
  47. void delay_ms(unsigned char ms);
  48. unsigned int cal_crc(unsigned char *snd, unsigned char num);
  49. /*************** 用户定义参数 *****************************/

  50. #define MAIN_Fosc                            11059200UL            
  51. #define Baudrate0                            9600UL                           
  52.                                                                                                                              
  53. /**********************************************************/


  54. /****************** 编译器自动生成,用户请勿修改 ***********************/

  55. #define BRT_Reload                                          (256 - MAIN_Fosc / 16 / Baudrate0)                            //Calculate the timer1 reload value ar 1T mode


  56. /**********************************************************/

  57. //**********************************************************************
  58. //函数名:main(void)
  59. //输入  :无
  60. //输出  :无
  61. //功能描述:当单片机接收到酒精浓度读取指令,采集酒精浓度,再向串口返回
  62. //酒精浓度的指令         
  63. //**********************************************************************
  64. void              main(void)
  65. {
  66.               uint              j;
  67.               uart1_init();//初始化串口
  68.               P1ASF = (1 << ADC_CH1);              //STC12C5A16S2系列模拟输入(AD)选择ADC1(P1.1)
  69.               ADC_CONTR = ADC_360T | ADC_ON;
  70.               while(1)
  71.               {
  72.                
  73.               if(flag==1)
  74.                                           {                            delay_ms(5);
  75.                                                                                                                                                                                                                                                      
  76.                                                                       if(RX0_Buffer[0x03] == 0x30)
  77.                                                                       {
  78.                                                                                   j = adc10_start(1);              //(P1.1)ADC1转换
  79.                                                                                                      mbus_Sendbuf[3] = ((j>>8)&0xff);
  80.                                                                                                      mbus_Sendbuf[4] = j&0xff;
  81.                                                                                                      mbus_Sendbuf[2] = (((RX0_Buffer[0x04] * 16) + RX0_Buffer[0x05]) * 2);                                                                                                   
  82.                                                                                                      mbus_Sendbuf[0] = RX0_Buffer[0];
  83.                                                                                                      mbus_Sendbuf[1] = 0x03;
  84.                                                                                                       
  85.                                                                                                 
  86.                                                                                                      Crc_return_data=cal_crc(mbus_Sendbuf, 5);  //取得将要发送数据的CRC值
  87.                                                                                  Crc_buf[0]=((Crc_return_data >> 8)&0xff);  //取得CRC值的高8位
  88.                                                                                  Crc_buf[1]=(Crc_return_data & 0xff);   //取得CRC值的低8位
  89.                                                                                                      mbus_Sendbuf[5]=Crc_buf[1];  //CRC值低8位赋值给将要发送的数据的倒数第二个字节
  90.                                                                                                      mbus_Sendbuf[6]=Crc_buf[0];  //CRC值高8位赋值给将要发送的数据的最后一个
  91.                                                                                              for(i = 0; i < 7; i++)
  92.                                                                                                {            
  93.                                                                                                                         Uart1_TxByte(mbus_Sendbuf[i]);            
  94.                                                                                                }
  95.                                                                                                                 flag=0;                                            
  96.                                                                                                   uart1_wr=0;                             
  97.                                                                       }            
  98.                                             }
  99.               }
  100. }
  101. //**********************************************************************
  102. //函数名:adc10_start(uchar channel)
  103. //输入  :ADC转换的通道
  104. //输出  :ADC值
  105. //功能描述:ADC转换
  106. //**********************************************************************
  107. uint              adc10_start(uchar channel)              //channel = 0~7
  108. {
  109.               uint              adc;
  110.               uchar              i;

  111.               ADC_RES = 0;
  112.               ADC_RESL = 0;

  113.               ADC_CONTR = (ADC_CONTR & 0xe0) | ADC_START | channel;
  114.               i = 250;
  115.               do{
  116.                             if(ADC_CONTR & ADC_FLAG)
  117.                             {
  118.                                           ADC_CONTR &= ~ADC_FLAG;
  119.                                           adc = (uint)ADC_RES;
  120.                                           adc = (adc << 2) | (ADC_RESL & 3);
  121.                                           return              adc;
  122.                             }
  123.               }while(--i);
  124.               return              1024;
  125. }
  126. /*****************************CRC校验计算函数********************************/
  127. unsigned int cal_crc(unsigned char *snd, unsigned char num)

  128. {

  129.    unsigned char i, j;

  130.    unsigned int c,crc=0xFFFF;

  131.    for(i = 0; i < num; i ++)

  132.    {

  133.        c = snd[i] & 0x00FF;

  134.        crc ^= c;

  135.        for(j = 0;j < 8; j ++)

  136.        {

  137.            if (crc & 0x0001)

  138.            {

  139.                crc>>=1;

  140.                crc^=0xA001;

  141.            }

  142.            else crc>>=1;

  143.        }

  144.    }  

  145.    return(crc);
  146. }
  147. //**********************************************************************
  148. //函数名:uart1_init(void)
  149. //输入  :无
  150. //输出  :无
  151. //功能描述:串口初始化函数,通信参数为9600 8 N 1
  152. //**********************************************************************
  153. void              uart1_init(void)
  154. {
  155.               PCON |= 0x80;                            //UART0 Double Rate Enable
  156.               SCON = 0x50;                            //UART0 set as 10bit , UART0 RX enable
  157.               AUXR |=  0x01;                            //UART0 使用BRT
  158.               AUXR |=  0x04;                            //BRT set as 1T mode
  159.               BRT = BRT_Reload;
  160.               AUXR |=  0x10;                            //start BRT            

  161.               ES  = 1;
  162.               EA = 1;
  163. }
  164. //**********************************************************************
  165. //函数名:Uart1_TxByte(unsigned char dat)
  166. //输入  :需要发送的字节数据
  167. //输出  :无
  168. //功能描述:从串口发送单字节数据
  169. //**********************************************************************
  170. void Uart1_TxByte(unsigned char dat)
  171. {
  172.     B_TI = 0;
  173.               SBUF = dat;
  174.               while(!B_TI);
  175.               B_TI = 0;
  176. }
  177. //**********************************************************************
  178. //函数名:Uart1_String(unsigned char code *puts)
  179. //输入  :字符串首地址
  180. //输出  :无
  181. //功能描述:从串口发送字符串
  182. //**********************************************************************
  183. void Uart1_String(unsigned char code *puts)
  184. {
  185.     for(; *puts != 0; puts++)
  186.               {
  187.         Uart1_TxByte(*puts);

  188.               }
  189. }

  190. //**********************************************************************
  191. //函数名:UART1_RCV (void)
  192. //输入  :无
  193. //输出  :无
  194. //功能描述:串口中断接收函数
  195. //**********************************************************************
  196. void UART1_RCV (void) interrupt 4
  197. {
  198.               if(RI)
  199.               {
  200.                             RI = 0;
  201.                             RX0_Buffer[uart1_wr++] = SBUF;
  202.                             //if(++uart0_wr >= BUF_LENTH)              uart0_wr = 0;
  203.                             flag = 1;
  204.               }

  205.               if(TI)
  206.               {
  207.                             TI = 0;
  208.                             B_TI = 1;
  209.               }
  210. }

  211. void delay_ms(unsigned char ms)
  212. {
  213.     unsigned int i;
  214.               do{
  215.                   i = MAIN_Fosc /1400;
  216.                             while(--i);
  217.               }while(--ms);
  218. }
复制代码

4.3 实验运行效果
节点S1开关拨打到左边让STC单片机和DB9连接,打开串口调试助手,进入如图4.1所示界面,在串口参数设置选择正确的端口号以及9600-8-N-1串口配置,选择16进制发送,16进制接收,把酒精读取指令01 03 00 30 00 01 84 05复制到发送区,打开串口,
点击发送: 01 03 00 30 00 01 84 05
返回:01 03 02 00 04 B9 87
其中倒数三四字节00 04是酒精浓度的数值,尝试使用酒精棉蘸取少量酒精接近接近酒精传感器,观察数这两个字节的变化。
注意:不要把酒精洒在电路板或者传感器上,免得腐蚀相关电路,把酒精轻轻靠近即可。
图4.1

完整的Word格式文档51黑下载地址:
实验1 酒精传感器实验-V20161122.doc (445.5 KB, 下载次数: 41)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:500268 发表于 2019-3-30 22:33 | 只看该作者
请问你的hex文件怎么获取
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表