久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 931|回復: 0
打印 上一主題 下一主題
收起左側

基于51單片機酒精濃度測試儀程序

[復制鏈接]
跳轉到指定樓層
樓主




  1. /*
  2. 基于51單片機的酒精濃度檢測報警系統
  3. */
  4. //程序頭函數
  5. #include <reg52.h>
  6. #include <intrins.h>        //包含頭文件
  7. //顯示函數  
  8. #include <display.h>
  9. #include "eeprom52.h"

  10. //宏定義
  11. #define uint unsigned int
  12. #define uchar unsigned char

  13. //管腳聲明
  14. sbit LED_R= P2^2;                          //紅色指示燈
  15. sbit LED_G= P2^0;                          //綠色指示燈
  16. sbit FENG = P2^5;                          //蜂鳴器
  17. sbit CS   = P1^4;
  18. sbit Clk = P1^2;
  19. sbit DATI = P1^3;
  20. sbit DATO = P1^3;                        //ADC0832引腳
  21. //按鍵
  22. sbit Key1=P2^6;
  23. sbit Key2=P2^7;
  24. sbit Key3=P3^7;
  25. /*******************************定義全局變量********************************/
  26. unsigned char dat = 0;      //AD值
  27. unsigned char CH=0;       //通道變量
  28. unsigned int sum=0;                         //平均值計算時的總數
  29. unsigned char m=0;
  30. bit bdata flag;                                  //定義位變量
  31. uchar set;                                          //設置變量
  32. uchar   K_ZERO=40;       //傳感器零點漂移,約130mV


  33. //函數聲明
  34. extern void Key();
  35. /*
  36. void delay(uint z)
  37. {
  38.         uint i,j;
  39.         for(i=0;i<z;i++)
  40.         for(j=0;j<121;j++);
  41. }
  42. */

  43. //酒精含量變量
  44. uchar temp=0;

  45. //指示燈變量

  46. uchar WARNING=25;                //報警值變量

  47. /******************把數據保存到單片機內部eeprom中******************/
  48. void write_eeprom()
  49. {
  50.         SectorErase(0x2000);
  51.         byte_write(0x2000, WARNING);
  52.         byte_write(0x2060, a_a);        
  53. }

  54. /******************把數據從單片機內部eeprom中讀出來*****************/
  55. void read_eeprom()
  56. {
  57.         WARNING   = byte_read(0x2000);
  58.         a_a      = byte_read(0x2060);
  59. }

  60. /**************開機自檢eeprom初始化*****************/
  61. void init_eeprom()
  62. {
  63.         read_eeprom();                //先讀
  64.         if(a_a != 1)                //新的單片機初始單片機內問eeprom
  65.         {
  66.                 WARNING  = 25;
  67.                 a_a = 1;
  68.                 write_eeprom();           //保存數據
  69.         }        
  70. }

  71. /****************************************************************************
  72. 函數功能:AD轉換子程序
  73. 入口參數:CH
  74. 出口參數:dat
  75. ****************************************************************************/
  76. unsigned char adc0832(unsigned char CH)
  77. {
  78.         unsigned char i,test,adval;
  79.         adval = 0x00;
  80.         test = 0x00;
  81.         Clk = 0;       //初始化
  82.         DATI = 1;
  83.         _nop_();
  84.         CS = 0;
  85.         _nop_();
  86.         Clk = 1;
  87.         _nop_();
  88.         
  89.         
  90.         if ( CH == 0x00 )      //通道選擇
  91.         {
  92.                 Clk = 0;
  93.                 DATI = 1;      //通道0的第一位
  94.                 _nop_();
  95.                 Clk = 1;
  96.                 _nop_();
  97.                 Clk = 0;
  98.                 DATI = 0;      //通道0的第二位
  99.                 _nop_();
  100.                 Clk = 1;
  101.                 _nop_();
  102.         }
  103.         else
  104.         {
  105.                 Clk = 0;
  106.                 DATI = 1;      //通道1的第一位
  107.                 _nop_();
  108.                 Clk = 1;
  109.                 _nop_();
  110.                 Clk = 0;
  111.                 DATI = 1;      //通道1的第二位
  112.                 _nop_();
  113.                 Clk = 1;
  114.                 _nop_();
  115.         }
  116.         
  117.         Clk = 0;
  118.         DATI = 1;
  119.         for( i = 0;i < 8;i++ )      //讀取前8位的值
  120.         {
  121.                 _nop_();
  122.                 adval <<= 1;
  123.                 Clk = 1;
  124.                 _nop_();
  125.                 Clk = 0;
  126.                 if (DATO)
  127.                 adval |= 0x01;
  128.                 else
  129.                 adval |= 0x00;
  130.         }
  131.         for (i = 0; i < 8; i++)      //讀取后8位的值
  132.         {
  133.                 test >>= 1;
  134.                 if (DATO)
  135.                 test |= 0x80;
  136.                 else
  137.                 test |= 0x00;
  138.                 _nop_();
  139.                 Clk = 1;
  140.                 _nop_();
  141.                 Clk = 0;
  142.         }
  143.         if (adval == test)      //比較前8位與后8位的值,如果不相同舍去。若一直出現顯示為零,請將該行去掉
  144.         dat = test;
  145.         nop_();
  146.         CS = 1;        //釋放ADC0832
  147.         DATO = 1;
  148.         Clk = 1;
  149.         return dat;
  150. }

  151. void init()                                //定時器初始化函數
  152. {
  153.         TMOD=0x01;                        //定時器工作方式
  154.          TL0=0xb0;
  155.          TH0=0x3c;                        //賦初值50ms
  156.          EA=1;                                //打開中斷總開關
  157.         ET0=1;                                //打開定時器0中斷允許開關
  158.          TR0=1;                                //打開定時器0定時開關
  159. }

  160. void AlcoholCalibration(void)     //酒精初始化校準函數
  161. {
  162.         sum = 0;
  163.         for(m=0;m<50;m++)                        //讀50次AD值
  164.         {
  165.                                 sum = adc0832(0)+sum;                //讀到的AD值,將讀到的數據累加到sum
  166.         }
  167.         temp=sum/50;                                //跳出上面的for循環后,將累加的總數除以50得到平均值temp
  168.         K_ZERO = 500 * temp / 256;        //8位ADC,首先得到電壓值,單位10毫伏
  169.         Display_1602(0,WARNING);         //顯示AD數值和報警值
  170. }

  171. void main()                                //主函數
  172. {
  173.         Init1602();                                                 //初始化液晶函數
  174.         init();                                                         //初始化定時器
  175.         init_eeprom();  //開始初始化保存的數據
  176.         while(1)                                                 //進入循環
  177.         {
  178.                 for(m=0;m<50;m++)                        //讀50次AD值
  179.                 sum = adc0832(0)+sum;                //讀到的AD值,將讀到的數據累加到sum
  180.                 temp=sum/50;                                //跳出上面的for循環后,將累加的總數除以50得到平均值temp
  181.                 if (temp > K_ZERO)
  182.                                 temp = temp - K_ZERO;              //首先減去零點漂移,一般是130mV
  183.                 else
  184.                                 temp= 0;
  185.                 sum=0;                                                 //平均值計算完成后,將總數清零
  186.                 if(set==0)                                         //set為0,說明現在不是設置狀態
  187.                 Display_1602(temp,WARNING);         //顯示AD數值和報警值
  188.                 if(temp<WARNING&&set==0)         //AD數值小于報警值
  189.                 {
  190.                         flag=0;                                         //關閉報警
  191.                 }
  192.                 else if(temp>WARNING&&set==0)//AD值大于報警值
  193.                 {
  194.                         flag=1;                                         //打開報警
  195.                 }
  196.                 Key();                                                 //調用按鍵函數
  197.         }
  198. }

  199. void Key()                                          //按鍵函數
  200. {
  201.         if(Key1==0)                                  //設置鍵按下
  202.         {
  203.                 while(Key1==0);                  //按鍵松開
  204.                 FENG=0;                                  //蜂鳴器響
  205.                 set++;                                  //設置變量加
  206.                 flag=0;                                  //關閉報警
  207.                 TR0=0;                                  //關閉定時器
  208.         }
  209.         if(set==1)                                  //設置報警值時
  210.         {
  211.                 write_com(0x38);//屏幕初始化
  212.                 write_com(0x80+0x40+7);//位置
  213.                    write_com(0x0f);//打開顯示 無光標 光標閃爍
  214.                    write_com(0x06);//當讀或寫一個字符是指針后一一位
  215.                 FENG=1;                                //關閉蜂鳴器

  216.         }
  217.         else if(set>=2)                //設置完成時
  218.         {
  219.                 set=0;                        //變量清零
  220.                 write_com(0x38);//屏幕初始化
  221.                 write_com(0x0c);//打開顯示 無光標 無光標閃爍
  222.                 FENG=1;                        //關閉蜂鳴器
  223.                 flag=1;                        //打開報警
  224.                 TR0=1;                        //打開定時器
  225.         }
  226.         if(Key2==0&&set!=0)                        //設置報警值時加鍵按下
  227.         {
  228.                 while(Key2==0);                        //按鍵松開
  229.                 FENG=0;                                        //打開蜂鳴器
  230.                 WARNING++;                                //報警值加
  231.                 if(WARNING>=255)                //最大加到255
  232.                 WARNING=0;                                //清零
  233.                 write_com(0x80+0x40+5);           //選中液晶屏上的第二行第十一列
  234.                 write_data('0'+WARNING/100);   //開始顯示報警值。例如報警值是123,123除以100的商是1,加上‘0’是為了得到液晶中對應1的顯示碼
  235.                 write_data('0'+WARNING%100/10);//123除以100的余數是23,23再除以10得到的商是2
  236.                 write_data('0'+WARNING%100%10);//23除以10的余數是3
  237.                 write_com(0x80+0x40+7);//位置
  238.                 FENG=1;                                                //關閉蜂鳴器
  239.                 write_eeprom();                           //保存數據
  240.         }
  241.         else if(Key2==0&&set==0)
  242.         {
  243.                 AlcoholCalibration();  //酒精初始化校準
  244.         }
  245.         if(Key3==0&&set!=0)                                //注釋同加按鍵
  246.         {
  247.                 while(Key3==0);
  248.                 FENG=0;
  249.                 WARNING--;
  250.                 if(WARNING<=0)
  251.                 WARNING=255;
  252.                 write_com(0x80+0x40+5);
  253.                 write_data('0'+WARNING/100);
  254.                 write_data('0'+WARNING/10%10);
  255.                 write_data('0'+WARNING%10);
  256.                 write_com(0x80+0x40+7);//位置
  257.                 FENG=1;
  258.                 write_eeprom();                           //保存數據
  259.         }
  260. }

  261. void  time1_int(void) interrupt 1                  //定時器工作函數
  262. {
  263.         uchar count;                                                  //定義計時變量
  264.         TL0=0xb0;
  265.          TH0=0x3c;                                                          //重新賦初值50ms
  266.           count++;                                                          //變量加一次就是50ms
  267.         if(count==10)                                                  //加到10次就是500ms
  268.         {
  269.                 if(flag==0)                                                  //flag=0時,也就是不開啟報警
  270.                 {
  271.                         LED_G=0;                                          //綠燈點亮
  272.                         LED_R=1;                                          //紅燈熄滅
  273.                         FENG=1;                                                  //關閉蜂鳴器
  274.                 }
  275.                 if(flag==1)                                                  //flag為1時,也就是打開報警
  276.                 {
  277.                         LED_G=1;                                          //綠燈熄滅
  278.                         LED_R=0;                                          //紅燈點亮
  279.                         FENG=0;                                                  //打開蜂鳴器
  280.                 }
  281.         }

  282.            if(count==20)                                                  //計數20次,就是1s
  283.            {                                                                          //在1s時,紅綠燈都是熄滅狀態,蜂鳴器也是關閉狀態,裝可以達到閃爍的目的
  284.                 count=0;                                                  //變量清零
  285.                 if(flag==0)                                                  //不是報警狀態時
  286.                 {
  287.                         LED_G=1;
  288.                         LED_R=1;
  289.                         FENG=1;
  290.                 }
  291.                 if(flag==1)                                                  //報警狀態時
  292.                 {
  293.                         LED_G=1;
  294.                         LED_R=1;
  295.                         FENG=1;
  296.                 }
  297.         }
  298. }
復制代碼




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一级片免费在线观看 | 欧美黄在线观看 | 国产精品一区二 | 91精品久久久久久久久久 | 亚洲69p| 日韩av高清在线 | 日韩在线视频观看 | 成人教育av | 亚洲视频在线观看 | 欧美一区二区三区在线看 | 国产性网 | 日本大香伊一区二区三区 | 韩日免费视频 | 四虎在线观看 | 东方伊人免费在线观看 | 亚洲高清视频在线观看 | 日韩伦理一区二区 | 亚洲在线久久 | 草草视频在线观看 | 亚洲视频在线观看 | av免费成人 | www4虎| 一级一级一级毛片 | 黄网免费 | 拍真实国产伦偷精品 | 久久精品国产亚洲一区二区三区 | 免费一级片 | 国产午夜精品久久久久免费视高清 | 欧美色综合一区二区三区 | 狠狠草视频 | 一区二区三区影院 | 正在播放国产精品 | 国产精品成人一区二区三区吃奶 | 久久精品网 | 欧美一级电影免费 | av在线播放一区二区 | 国产精品亚洲一区二区三区在线观看 | 精品国产免费一区二区三区演员表 | 亚洲第1页 | 精品一级| 午夜精品一区二区三区在线观看 |