找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1729|回复: 0
收起左侧

单片机酒精检测代码

[复制链接]
ID:639814 发表于 2019-11-13 17:33 | 显示全部楼层 |阅读模式
  1. #include<reg52.h>
  2. #include<string.h>
  3. #include <stdio.h>
  4. #include"intrins.h"
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. uchar code table[]={'0','1','2','3','4','5','6','7','8','9'};
  8. uchar code table1[]="ALC warn=90mg/L";                 //初始显示
  9. uchar code table2[]="current=";                                //报警浓度和实测浓度表示
  10. uchar code table3[]="mg/L";
  11. sbit led=P2^2;
  12. sbit beep=P1^5;
  13. sbit lcdrs=P2^5;               //1602液晶的RS脚接在P2.3口上
  14. sbit lcdrw=P2^6;               //1602液晶的RW脚接在P2.4口上
  15. sbit lcden=P2^7;               //1602液晶的E脚接在P2.5口上
  16. sbit SDA=P2^1;                                                         
  17. sbit SCL=P2^3;
  18. int count,t,num;
  19. uchar cur1,cur2,cur3;                                
  20. uint cur_bj=90;                         //CO报警值
  21. unsigned char ADbuf;//设置8位的寄存器用来暂存A/D转换结果
  22. void delay(unsigned int z)
  23. {
  24.         uint i,j;
  25.         for(i=z;i>0;i--)
  26.           for(j=110;j>0;j--);
  27. }

  28. /*******************************延时函数*********************************/
  29. void delayms(unsigned int ms)
  30. {
  31.         unsigned char i=100,j;
  32.         for(;ms;ms--)
  33.         {
  34.                 while(--i)
  35.                 {
  36.                         j=10;
  37.                         while(--j);
  38.                 }
  39.         }
  40. }





  41. /*******************************报警函数*********************************/
  42. void led_warn()                                                
  43. {
  44.         led=~led;
  45.         delay(200);
  46. }
  47. void beep_warn()

  48. {
  49.         beep=~beep;
  50.         delay(200);
  51. }





  52.    /******************************写命令函数********************************/
  53. void write_com(uchar com)
  54. {
  55.          lcdrs=0;
  56.          P0=com;                                //读命令
  57.          delay(1);
  58.          lcden=1;                                //启动脉冲
  59.          delay(1);
  60.          lcden=0;
  61. }
  62. /******************************写数据函数********************************/
  63. void write_data(uchar date)
  64. {
  65.          lcdrs=1;
  66.          P0=date;                                //写命令
  67.          delay(1);
  68.          lcden=1;                                //启动脉冲
  69.          delay(1);
  70.          lcden=0;
  71. }
  72. /******************************LCD初始化*********************************/
  73. void init_1602()
  74. {
  75.          lcden=0;
  76.          write_com(0x38);                        //设置16*2显示;5*7点阵;8位数据接口
  77.          write_com(0x0c);                        //设置开显示,不显示光标
  78.          write_com(0x06);                        //写一个字符后地址指针自动加1
  79.          write_com(0x01);                        //设置清0,数据指针清零
  80. }





  81. void IICstart(void)
  82. {
  83.      SDA=1;                //先将SDA=1,以准备在SCL=1时,将SDA=0
  84.      SCL=1;                //时钟总线拉高
  85.      _nop_();                          //略做延时
  86.      _nop_();                          //略做延时
  87.      SDA=0;                //SCL=1时,将SDA拉低即产生启动信号
  88.      _nop_();                          //略做延时
  89.      _nop_();                          //略做延时
  90.      SCL=0;                //将SCL=0,完成启动信号操作      
  91. }


  92. /*****************************IIC停止信号函数***********************************/
  93. void IICstop(void)
  94. {
  95.      SDA=0;                //先将SDA=0,以准备在SCL=1时,将SDA=1
  96.      SCL=1;                //时钟总线拉高
  97.      _nop_();                          //略做延时
  98.      _nop_();                          //略做延时
  99.      SDA=1;                //SCL=1时,将SDA拉高即产生停止信号
  100.      _nop_();                          //略做延时
  101.      _nop_();                          //略做延时
  102.      SCL=0;                //将SCL=0,完成启动信号操作      
  103. }

  104. /*****************************向IIC总线写入1个字节函数**************************/
  105. void Write1Byte(unsigned char Buf1)
  106. {
  107.      unsigned char k;      //1个字节要分8次写入,需要定义一个寄存器用来计数
  108.      for(k=0;k<8;k++)      //做一个8次的循环,每次写入1位,需要写8次
  109.      {
  110.          if(Buf1&0x80)     //从最高位开始写
  111.          {
  112.              SDA=1;        //如果欲写入数据为1,就将数据线置1
  113.          }
  114.          else
  115.          {
  116.              SDA=0;        //如果欲写入数据为0,就将数据线写0
  117.          }
  118.          _nop_();          //略做延时
  119.          _nop_();          //略做延时
  120.          SCL=1;            //时钟线做一个上升沿,将一位数据写入
  121.          Buf1=Buf1<<1;     //数据左移一位,将下次要写入的位数据移到最高位
  122.          _nop_();          //略做延时
  123.          SCL=0;            //将SCL=0,以准备通过上升沿将数据写入
  124.          _nop_();          //略做延时
  125.      }
  126.      SDA=1;                //将SDA=1,准备读应答信号
  127.      _nop_();              //略做延时
  128.      SCL=1;                //将SCL=1,做个上升沿准备读应答信号
  129.      _nop_();              //略做延时
  130.      _nop_();              //略做延时
  131.      SCL=0;                //将SCL=0,结束应答信号读操作
  132. }

  133. /****************************从IIC总线读入1个字节函数******************************/
  134. unsigned char Read1Byte(void)
  135. {
  136.      unsigned char k;      //1个字节要分8次读出,需要定义一个寄存器用来计数
  137.      unsigned char t=0;    //定义一个寄存器用保存读出数据
  138.      for(k=0;k<8;k++)      //做一个8次的循环,每次读入1位,需要读8次
  139.      {
  140.          t=t<<1;           //数据左移一位,空出最低位以准备保存读入的一位数据
  141.          SDA=1;            //将SDA写1准备读
  142.          SCL=1;            //将SCL=1,做个上升沿准备读一位数据
  143.          _nop_();          //略做延时
  144.          _nop_();          //略做延时
  145.          if(SDA==1)        //读一位数据,并判断
  146.          {
  147.              t=t|0x01;     //如果读入数据为1,就将接收缓冲区最低一位置1
  148.          }
  149.          else
  150.          {
  151.              t=t&0xfe;     //如果读入数据为0,就将接收缓冲区最低一位写0
  152.          }
  153.          SCL=0;            //SCL恢复为0,结束一位数据读操作
  154.          _nop_();          //略做延时
  155.          _nop_();          //略做延时
  156.      }
  157.      return t;             //将读入的一个字节返回
  158. }

  159. /******************************软件模拟IIC向PCF8591指定地址写一个字节函数********************************/
  160. void WritePCF8591(unsigned char Databuf)
  161. {                          //直接调用本函数即可启动PCF8591的D/A转换
  162.     IICstart();            //IIC启动信号

  163.     Write1Byte(0x90);      //发送PCF8591的器件地址和写信号

  164.     Write1Byte(0x40);      //发送器件子地址

  165.     Write1Byte(Databuf);   //发送数据

  166.     IICstop();             //产生IIC停止信号
  167. }


  168. /******************************软件模拟IIC从PCF8563指定地址读一个字节函数************************************/
  169. unsigned char ReadPCF8591(unsigned char Ch)
  170. {                          //直接调用本函数即可从PCF8591的Ch通道读出数据返回
  171.     unsigned char buf;     //定义一个寄存器用来暂存读出的数据
  172.     IICstart();            //IIC启动信号

  173.     Write1Byte(0x90);      //发送PCF8591的器件地址和写信号

  174.     Write1Byte(0x40|Ch);   //发送器件通道参数Ch=0-3

  175.     IICstart();            //IIC启动信号

  176.     Write1Byte(0x91);      //发送PCF8591的器件地址和读信号

  177.     buf=Read1Byte();//读一个字节数据

  178.     IICstop();             //产生IIC停止信号

  179.     return(buf);           //将读出数据返回
  180. }


  181. /******************************显示初始值函数**********************************/
  182. void dis_init()
  183. {
  184.         uchar a,b,c;
  185.         write_com(0x80+0x00);        //初始化显示
  186.          for(a=0;a<15;a++)
  187.          {
  188.                   write_data(table1[a]);
  189.                   delay(1);
  190.          }
  191.         delay(200);
  192.         write_com(0x80+0x40);        //第二行显示酒精浓度表示单位        
  193.          for(b=0;b<8;b++)
  194.          {
  195.                   write_data(table2[b]);
  196.                   delay(1);
  197.          }
  198.                  write_com(0x80+0x4B);        //第二行显示酒精浓度表示单位        
  199.          for(c=0;c<4;c++)
  200.          {
  201.                   write_data(table3[c]);
  202.                   delay(1);
  203.          }

  204. }



  205. /*********************************1602显示浓度数据h和酒精报警程序**************************/
  206. void dis_cur(uint t)
  207. {
  208.   uchar i;
  209.      t=t*100/255;
  210.    i=t/100;
  211.    write_com(0x80+0x48);           //显示浓度百位
  212.    write_data(table[i]);
  213.    cur1=table[i];
  214.   i=t%100/10;

  215.     write_com(0x80+0x49);
  216.         write_data(table[i]);
  217.          cur2=table[i];
  218.   i=t%100%10;
  219.           write_com(0x80+0x4A);           //显示浓度个位
  220.          write_data(table[i]);

  221.          cur3=table[i];


  222.          if(t>cur_bj)
  223.           {         
  224.                 led_warn();
  225.             beep_warn();
  226.           }

  227.     else
  228.           {
  229.                 led=1;
  230.                 beep=1;
  231.           }

  232. }

  233. /*******************************串口初始化********************************/
  234. void  UARTinit()
  235. {
  236. //   TMOD=0X21;
  237. //   SCON=0X40;
  238.   TMOD=0x20;
  239.   PCON=0x00;
  240.   SCON=0x50;
  241.    TH1=0XFF;
  242.    TL1=0XFD;
  243.    TH0=(65536-45872)/256;
  244.    TL0=(65536-45872)%256;
  245.    TR1=1;
  246.    TR0=1;
  247.    EA=1;
  248.    ES=1;
  249.    TI=0;
  250.    ET0=1;
  251. }
  252. /*******************************发送一个字节************************************/
  253. void UART_Send_Byte(unsigned char mydata)        
  254. {
  255.          ES=0;
  256.          TI=0;
  257.          SBUF=mydata;
  258.          while(!TI);
  259.          TI=0;
  260.          ES=1;
  261. }
  262. /****************************发送文本串****************************************/
  263. void UART_Send_Str(char *s)         
  264. {
  265.          int i=0;
  266.          while(s[i]!=0)
  267.          {
  268.                  UART_Send_Byte(s[i]);
  269.                  i++;
  270.          }

  271. }

  272. void T0_time() interrupt 1
  273. {
  274.    count++;
  275.    TH0=(65536-45872)/256;
  276.    TL0=(65536-45872)%256;
  277.            if(count==400)
  278.                 {
  279.                  count=0;
  280.                  num=1;
  281.                 }

  282. }


  283. main()
  284. {
  285. uchar g,s,b;

  286. //        uchar i = 0;
  287. //          uchar code Buffer[]="0" ;  //所要发送的数据
  288. //          uchar *p;

  289.         led=1;
  290.         beep=1;
  291.         lcdrw=0;                           //确定读操作
  292.         init_1602();                   //初始化LCD1602
  293.         delay(5);
  294.         dis_init();                                //1602显示初始化  
  295.         delay(2000);
  296.         UARTinit();                           //串口初始化



  297. //          Com_Init();
  298. //          p = Buffer;
  299.         while(1)        
  300.         {
  301.                    ADbuf=ReadPCF8591(0);     //将AIN0通道A/D转换结果暂存在ADbuf
  302.                     dis_cur(ADbuf);        //浓度显示
  303.                   b=ADbuf/100;
  304.                 s=ADbuf%100/10;
  305.                 g=ADbuf%100%10;
  306.                 if(num==1)
  307.                 {
  308.                         UART_Send_Byte(g);
  309.                         UART_Send_Byte(s);
  310.                         UART_Send_Byte(b);
  311.                 //        UART_Send_Str("hello");
  312. //                UART_Send_Str("ADbuf/100");
  313. //                UART_Send_Str("ADbuf%100/10");
  314. //                UART_Send_Str("ADbuf%100%10");

  315.                 }
  316.    /*
  317.                  SBUF = *p ;
  318.             while(!TI){  ;//如果发送完毕,硬件会置位TI
  319.               _nop_();   //此句似乎可以去掉
  320.             }
  321.             TI = 0;  //TI清零
  322.             p++;
  323.             if(*p == '\0')
  324.               break;  */
  325.         }  
  326. }
复制代码
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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