找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机酒精浓度测试仪,代码,原理图

[复制链接]
跳转到指定楼层
楼主
文件共享,文件分享。

综合项目,花了很久时间精细研究得到的成果,可以完美运行。
       酒精测试仪以STC12C5A60S2单片机作为主控芯片,采用高精度MQ-3乙醇气体传感器对空气中的乙醇浓度进行检测,主控芯片对检测信号进行A/D转换和处理(不需要外接A/D转换,芯片自带该功能,),最后通过LCD1602液晶显示屏显示出来。酒精浓度测试仪具有醉酒阈值设定功能,可以根用户需要设定修改醉酒阈值。当检测到的酒精浓度超过设定阀值时会发出声光警报。
硬件电路十分简单,方便学习。
代码原理图数据手册见附件。


单片机源程序如下:
  1. #include "STC12C5A60S2.h"
  2. #include "intrins.h"

  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5.        
  6. sbit RS = P2^7;   
  7. sbit RW = P2^6;
  8. sbit EN = P2^5;
  9. sbit k0 = P3^3;
  10. sbit k1 = P3^4;
  11. sbit tm = P2^0;
  12. sbit in = P1^1;
  13. sbit led0= P1^5;
  14. sbit led1= P1^3;

  15. uchar shi=2,fen,miao;
  16. uchar num=0,n=0;
  17. uchar da1=0,add=0;
  18. double Data,c;
  19. char ac,bc,dc;
  20. char a[5]="";
  21. char b[4]="2.00";

  22. void key();
  23. void jian_ce();
  24. /************************************
  25.            延时函数
  26. *************************************/
  27. //一个机械周期
  28. void DelayUs2x(uchar t)
  29. {   
  30. while(--t);
  31. }
  32. //自定义延时,单位微秒us
  33. void DelayMs(uchar t)
  34. {     
  35.         while(t--)
  36.                 {     
  37.      DelayUs2x(245);
  38.      DelayUs2x(245);
  39.                 }
  40. }

  41. /************************************
  42.             判忙函数
  43. *************************************/
  44. bit LCD_Check_Busy(void)
  45. {
  46.                 P0= 0xFF;
  47.                 RS=0;
  48.                 RW=1;
  49.                 EN=0;
  50.                 _nop_();
  51.                 EN=1;
  52.                 return (bit)(P0 & 0x80);   
  53. }

  54. /************************************
  55.             写指令函数
  56. *************************************/
  57. void LCD_Write_Com(uchar com)
  58. {  
  59.                 while(LCD_Check_Busy()); //忙则等待
  60.                 RS=0;
  61.                 RW=0;
  62.                 EN=1;
  63.                 P0= com;         
  64.                 _nop_();
  65.                 EN=0;
  66. }

  67. /************************************
  68.             写数据函数
  69. *************************************/
  70. void LCD_Write_Data(uchar Data)
  71. {
  72.                 while(LCD_Check_Busy()); //忙则等待
  73.                 RS=1;
  74.                 RW=0;
  75.                 EN=1;
  76.                 P0= Data;
  77.                 _nop_();
  78.                 EN=0;
  79. }

  80. /************************************
  81.               清屏函数
  82. *************************************/
  83. void LCD_Clear(void)
  84. {
  85. LCD_Write_Com(0x01);
  86. DelayMs(5);
  87. }

  88. /************************************
  89.            写字符串函数
  90. *************************************/
  91. void LCD_Write_String(uchar x,uchar y,uchar *s)
  92. {     
  93. if (y == 0)
  94.      {     
  95.      LCD_Write_Com(0x80 + x);      //表示第一行
  96.      }
  97. else
  98.      {      
  99.      LCD_Write_Com(0xC0 + x);      //表示第二行
  100.      }        
  101. while (*s)
  102.      {     
  103. LCD_Write_Data( *s);     
  104.                         s ++;     
  105.      }
  106. }

  107. /************************************
  108.            LCD初始化函数
  109. *************************************/
  110. void LCD_Init(void)
  111. {
  112.    LCD_Write_Com(0x38);   
  113.    DelayMs(5);
  114.    LCD_Write_Com(0x38);
  115.    DelayMs(5);
  116.    LCD_Write_Com(0x38);
  117.    DelayMs(5);
  118.    LCD_Write_Com(0x38);  
  119.    LCD_Write_Com(0x08);     
  120.    LCD_Write_Com(0x01);   
  121.    LCD_Write_Com(0x06);   
  122.    DelayMs(5);
  123.    LCD_Write_Com(0x0C);   
  124. }
  125.    
  126. /************************************
  127.               ADC函数
  128. *************************************/
  129. void InitADC()                         //初始AD寄存器
  130. {
  131.           P1ASF=0X00;      //P1.0脚作为模拟量输入端
  132.                 ADC_RES=0X00;    //清除高8位缓冲数据
  133.                                                                                  //ADC_CONTR为ADC控制寄存器
  134.                 ADC_CONTR=0xF0;  //AD转换控制寄存器
  135.                 _nop_();                                 //低三位 000 为P1.0口作为A/D输入
  136.                 _nop_();
  137.                 _nop_();                                 //必须经过4个空操作延时后执行
  138.                 _nop_();
  139.                 ADC_CONTR=0xE8;  //1110.1000 第三位置一                                                                                                         
  140. }

  141. void timer0() interrupt 1    //定时器0
  142. {
  143.     TH0=(65536-20000)/256;      
  144.     TL0=(65536-20000)%256;      
  145.     InitADC();               
  146. }

  147. void adc_isr() interrupt 5   //ADC中断   
  148. {   
  149.          da1=ADC_RES;              //获取转换结果
  150.          c=((double)da1/256)*5;    //取八位计算基准电压      
  151.    
  152.    a[0]=((int)c%10+0x30);        //个位
  153.    a[1]='.';                     //小数点
  154.    a[2]=((int)(c*10)%10+0x30);   //十分位
  155.    a[3]=((int)(c*100)%10+0x30);  //百分位
  156.    a[4]='\0';                        
  157.          LCD_Write_String(8,0,a);                         //LCD显示测量值
  158.    ADC_CONTR&=0xEF;              //标志位清零
  159.    num++;
  160.    if(num==252)num=0;       
  161. }

  162. /************************************
  163.            LCD显示函数
  164. *************************************/
  165. void LCDXS()
  166. {
  167.     LCD_Init();
  168.     LCD_Clear();                     
  169.                 LCD_Write_String(0,0,"nong du:");
  170.                 LCD_Write_String(12,0,"mg/L");
  171.           LCD_Write_String(0,1,"fen jie:");       
  172.     LCD_Write_String(8,1,b);
  173.           LCD_Write_String(12,1,"mg/L");
  174. }

  175. /************************************
  176.            中断初始化函数
  177. *************************************/
  178. void Init_zd()
  179. {
  180.     TH0=(65536-20000)/256;           
  181.     TL0=(65536-20000)%256;
  182.                 IE=0xA2; //打开EA(总中断)
  183.                    //EADC(ADC中断允许位)
  184.                                                  //ET0(定时器0中断允许位)
  185.     TR0=1;
  186. }




  187. /************************************
  188.              按键控制
  189. *************************************/
  190. void key()
  191. {         
  192.          if(!k0)//按键选位
  193.          {
  194.            DelayMs(30);
  195.                  if(!k0)
  196.                  {add++;       
  197.                         while(!k0);       
  198.                         switch (add)
  199.                                 {
  200.                                 case 1:        EA=0;n=1;DelayMs(5);
  201.                                                                 LCD_Write_Com(0xc0+8);
  202.                                                                 LCD_Write_Com(0x0f);                                                               
  203.                                                                 break;
  204.                                        
  205.                                 case 2:        LCD_Write_Com(0xc0+10);                                                                                               
  206.                                                                 break;
  207.                                        
  208.                                 case 3:        LCD_Write_Com(0xc0+11);                                                                                                       
  209.                                                                 break;
  210.                                        
  211.                                 case 4:        LCD_Write_Com(0x0c);                                                               
  212.                                                                 add=0;DelayMs(5);n=0;EA=1;
  213.                                                                 break;               
  214.                                 } //switch(add)
  215.                         }
  216.          }//if(!k0);

  217. if(add!=0)//按键加
  218. {       
  219.         switch (add)
  220.                 {
  221.                 case 1:if(!k1)
  222.                                                 {
  223.                                                  DelayMs(30);
  224.                                                  if(!k1)
  225.                                                  {shi++;
  226.                                                         while(!k1);
  227.                                                         if(shi==5)shi=0;                                                                                                                                                  
  228.                                                  }
  229.                                                 }       
  230.                                                 LCD_Write_Com(0xc0+8);
  231.                                                 LCD_Write_Data(0x30+shi);
  232.                                                 LCD_Write_Com(0xc0+8);
  233.                                     break;

  234.                 case 2:if(!k1)
  235.                                                 {
  236.                                                  DelayMs(30);
  237.                                                  if(!k1)
  238.                                                  {fen++;
  239.                                                         while(!k1);                                                       
  240.                                                         if(fen==10)fen=0;                                                                                                                                                  
  241.                                                  }
  242.                                                 }
  243.                                                 LCD_Write_Com(0xc0+10);
  244.                                                 LCD_Write_Data(0x30+fen);
  245.                                                 LCD_Write_Com(0xc0+10);
  246.                                     break;


  247.                 case 3:if(!k1)
  248.                                                 {
  249.                                                  DelayMs(30);
  250.                                                  if(!k1)
  251.                                                  {miao++;
  252.                                                         while(!k1);                                                       
  253.                                                         if(miao==10)miao=0;                                                                                                                                                  
  254.                                                  }
  255.                                                 }       
  256.                                                 LCD_Write_Com(0xc0+11);
  257.                                                 LCD_Write_Data(0x30+miao);
  258.                                                 LCD_Write_Com(0xc0+11);
  259.                                     break;       
  260.                  }//switch()
  261. }//if(add!=0)         
  262. }//key()


  263. /************************************
  264.              主函数
  265. *************************************/
  266. void main()
  267. {
  268.                 LCDXS();       
  269.     DelayMs(255);       
  270.           Init_zd();       
  271.                
  272.     while(1)
  273.                 {       
  274.                         ac=(int)c%10;
  275. ……………………

  276. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
酒精测试仪—程序.rar (43.71 KB, 下载次数: 57)
AD原理图.rar (15.72 KB, 下载次数: 36)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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