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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于89C52RC單片機煙霧加溫度加火焰程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:258823 發表于 2017-12-20 23:20 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
基于89C52RC單片機煙霧加溫度加火焰的程序是我在制作傳感器課題設計時留下的寶貴資料

單片機源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define uchar unsigned char                // 以后unsigned char就可以用uchar代替
  4. #define uint  unsigned int                // 以后unsigned int 就可以用uint 代替

  5. sfr ISP_DATA  = 0xe2;                        // 數據寄存器
  6. sfr ISP_ADDRH = 0xe3;                        // 地址寄存器高八位
  7. sfr ISP_ADDRL = 0xe4;                        // 地址寄存器低八位
  8. sfr ISP_CMD   = 0xe5;                        // 命令寄存器
  9. sfr ISP_TRIG  = 0xe6;                        // 命令觸發寄存器
  10. sfr ISP_CONTR = 0xe7;                        // 命令寄存器

  11. sbit Fire_P   = P1^0;                        // 火焰傳感器引腳
  12. sbit DQ       = P1^1;                        // 溫度傳感器的引腳
  13. sbit ADC_CS   = P1^2;                         // ADC0832的CS引腳
  14. sbit ADC_CLK  = P1^3;                         // ADC0832的CLK引腳
  15. sbit ADC_DAT  = P1^4;                 // ADC0832的DI/DO引腳
  16. sbit LcdRs_P  = P2^7;                     // 1602液晶的RS管腳      
  17. sbit LcdRw_P  = P2^6;                     // 1602液晶的RW管腳
  18. sbit LcdEn_P  = P2^5;                     // 1602液晶的EN管腳
  19. sbit Key1_P   = P3^2;                        // 設置按鍵
  20. sbit Key2_P   = P3^3;                        // 減按鍵
  21. sbit Key3_P   = P3^4;                        // 加按鍵
  22. sbit Buzzer_P = P2^0;                        // 蜂鳴器
  23. sbit Led1_P   = P2^3;                        // 報警燈1,火焰報警
  24. sbit Led2_P   = P2^2;                        // 報警燈2,溫度報警
  25. sbit Led3_P   = P2^1;                        // 報警燈3,煙霧報警

  26. uchar gMqAlarm;                                // 煙霧報警值
  27. int   gTempAlarm;                                // 溫度報警值

  28. /*********************************************************/
  29. // 單片機內部EEPROM不使能
  30. /*********************************************************/
  31. void ISP_Disable()
  32. {
  33.         ISP_CONTR = 0;
  34.         ISP_ADDRH = 0;
  35.         ISP_ADDRL = 0;
  36. }

  37. /*********************************************************/
  38. // 從單片機內部EEPROM讀一個字節,從0x2000地址開始
  39. /*********************************************************/
  40. unsigned char EEPROM_Read(unsigned int add)
  41. {
  42.         ISP_DATA  = 0x00;
  43.         ISP_CONTR = 0x83;
  44.         ISP_CMD   = 0x01;
  45.         ISP_ADDRH = (unsigned char)(add>>8);
  46.         ISP_ADDRL = (unsigned char)(add&0xff);
  47.         // 對STC89C51系列來說,每次要寫入0x46,再寫入0xB9,ISP/IAP才會生效
  48.         ISP_TRIG  = 0x46;          
  49.         ISP_TRIG  = 0xB9;
  50.         _nop_();
  51.         ISP_Disable();
  52.         return (ISP_DATA);
  53. }

  54. /*********************************************************/
  55. // 往單片機內部EEPROM寫一個字節,從0x2000地址開始
  56. /*********************************************************/
  57. void EEPROM_Write(unsigned int add,unsigned char ch)
  58. {
  59.         ISP_CONTR = 0x83;
  60.         ISP_CMD   = 0x02;
  61.         ISP_ADDRH = (unsigned char)(add>>8);
  62.         ISP_ADDRL = (unsigned char)(add&0xff);
  63.         ISP_DATA  = ch;
  64.         ISP_TRIG  = 0x46;
  65.         ISP_TRIG  = 0xB9;
  66.         _nop_();
  67.         ISP_Disable();
  68. }

  69. /*********************************************************/
  70. // 擦除單片機內部EEPROM的一個扇區
  71. // 寫8個扇區中隨便一個的地址,便擦除該扇區,寫入前要先擦除
  72. /*********************************************************/
  73. void Sector_Erase(unsigned int add)          
  74. {
  75.         ISP_CONTR = 0x83;
  76.         ISP_CMD   = 0x03;
  77.         ISP_ADDRH = (unsigned char)(add>>8);
  78.         ISP_ADDRL = (unsigned char)(add&0xff);
  79.         ISP_TRIG  = 0x46;
  80.         ISP_TRIG  = 0xB9;
  81.         _nop_();
  82.         ISP_Disable();
  83. }

  84. /*********************************************************/
  85. // 毫秒級的延時函數,time是要延時的毫秒數
  86. /*********************************************************/
  87. void DelayMs(uint time)
  88. {
  89.         uint i,j;
  90.         for(i=0;i<time;i++)
  91.                 for(j=0;j<112;j++);
  92. }

  93. /*********************************************************/
  94. // 延時15微秒
  95. /*********************************************************/
  96. void Delay15us(void)
  97. {
  98.         _nop_();
  99.         _nop_();
  100.         _nop_();
  101.         _nop_();
  102.         _nop_();
  103.         _nop_();
  104.         _nop_();
  105.         _nop_();
  106.         _nop_();
  107.         _nop_();
  108.         _nop_();
  109.         _nop_();
  110.         _nop_();
  111.         _nop_();
  112.         _nop_();
  113. }

  114. /*********************************************************/
  115. // 復位DS18B20(初始化)
  116. /*********************************************************/
  117. void DS18B20_ReSet(void)
  118. {
  119.         uchar i;
  120.         DQ=0;
  121.         i=240;
  122.         while(--i);
  123.         DQ=1;
  124.         i=30;
  125.         while(--i);
  126.         while(~DQ);
  127.         i=4;
  128.         while(--i);
  129. }

  130. /*********************************************************/
  131. // 向DS18B20寫入一個字節
  132. /*********************************************************/
  133. void DS18B20_WriteByte(uchar dat)
  134. {
  135.         uchar j;
  136.         uchar btmp;
  137.         for(j=0;j<8;j++)
  138.         {
  139.                 btmp=0x01;
  140.                 btmp=btmp<<j;
  141.                 btmp=btmp&dat;
  142.                
  143.                 if(btmp>0)                // 寫1
  144.                 {
  145.                         DQ=0;
  146.                         Delay15us();
  147.                         DQ=1;
  148.                         Delay15us();
  149.                         Delay15us();
  150.                         Delay15us();
  151.                         Delay15us();
  152.                 }
  153.                 else                        // 寫0
  154.                 {
  155.                         DQ=0;
  156.                         Delay15us();
  157.                         Delay15us();
  158.                         Delay15us();
  159.                         Delay15us();
  160.                         DQ=1;
  161.                         Delay15us();
  162.                 }
  163.         }
  164. }

  165. /*********************************************************/
  166. // 讀取溫度值
  167. /*********************************************************/
  168. int DS18B20_ReadTemp(void)
  169. {
  170.         uchar j;
  171.         int b,temp=0;       
  172.         DS18B20_ReSet();                                        // 產生復位脈
  173.         DS18B20_WriteByte(0xcc);                        // 忽略ROM指令
  174.         DS18B20_WriteByte(0x44);                        // 啟動溫度轉換指令
  175.         DS18B20_ReSet();                                        // 產生復位脈
  176.         DS18B20_WriteByte(0xcc);                        // 忽略ROM指令
  177.         DS18B20_WriteByte(0xbe);                        // 讀取溫度指令
  178.         for(j=0;j<16;j++)                                        // 讀取溫度數量
  179.         {                                               
  180.                 DQ=0;
  181.                 _nop_();
  182.                 _nop_();
  183.                 DQ=1;       
  184.                 Delay15us();
  185.                 b=DQ;
  186.                 Delay15us();
  187.                 Delay15us();
  188.                 Delay15us();
  189.                 b=b<<j;
  190.                 temp=temp|b;
  191.         }
  192.         temp=temp*0.0625;                                // 合成溫度值       
  193.         return (temp);                                                // 返回檢測到的溫度值

  194. }

  195. /*********************************************************/
  196. // 1602液晶寫命令函數,cmd就是要寫入的命令
  197. /*********************************************************/
  198. void LcdWriteCmd(uchar cmd)
  199. {
  200.         LcdRs_P = 0;
  201.         LcdRw_P = 0;
  202.         LcdEn_P = 0;
  203.         P0=cmd;
  204.         DelayMs(2);
  205.         LcdEn_P = 1;   
  206.         DelayMs(2);
  207.         LcdEn_P = 0;       
  208. }

  209. /*********************************************************/
  210. // 1602液晶寫數據函數,dat就是要寫入的數據
  211. /*********************************************************/
  212. void LcdWriteData(uchar dat)
  213. {
  214.         LcdRs_P = 1;
  215.         LcdRw_P = 0;
  216.         LcdEn_P = 0;
  217.         P0=dat;
  218.         DelayMs(2);
  219.         LcdEn_P = 1;   
  220.         DelayMs(2);
  221.         LcdEn_P = 0;
  222. }

  223. /*********************************************************/
  224. // 1602液晶初始化函數
  225. /*********************************************************/
  226. void LcdInit()
  227. {
  228.         LcdWriteCmd(0x38);        // 16*2顯示,5*7點陣,8位數據口
  229.         LcdWriteCmd(0x0C);        // 開顯示,不顯示光標
  230.         LcdWriteCmd(0x06);        // 地址加1,當寫入數據后光標右移
  231.         LcdWriteCmd(0x01);        // 清屏
  232. }

  233. /*********************************************************/
  234. // 液晶光標定位函數
  235. /*********************************************************/
  236. void LcdGotoXY(uchar line,uchar column)
  237. {
  238.         // 第一行
  239.         if(line==0)        
  240.                 LcdWriteCmd(0x80+column);
  241.          // 第二行
  242.         if(line==1)        
  243.                 LcdWriteCmd(0x80+0x40+column);
  244. }

  245. /*********************************************************/
  246. // 液晶輸出字符串函數
  247. /*********************************************************/
  248. void LcdPrintStr(uchar *str)
  249. {
  250.         while(*str!='\0')
  251.                 LcdWriteData(*str++);
  252. }

  253. /*********************************************************/
  254. // 液晶輸出數字
  255. /*********************************************************/
  256. void LcdPrintNum1(uchar num)
  257. {
  258.         LcdWriteData(num/100+48);                        // 百位
  259.         LcdWriteData(num%100/10+48);                // 十位
  260.         LcdWriteData(num%10+48);                         // 個位
  261. }

  262. /*********************************************************/
  263. // 溫度值的顯示
  264. /*********************************************************/
  265. void LcdPrintNum2(int num)
  266. {
  267.         if(num<0)                                                                        // 顯示負號
  268.         {
  269.                 LcdWriteData('-');
  270.                 num=0-num;       
  271.         }
  272.         else                                                                    // 顯示百位
  273.         {
  274.                 LcdWriteData(num/100+48);
  275.         }
  276.         LcdWriteData(num%100/10+48);                                // 顯示十位
  277.         LcdWriteData(num%10+48);                                        // 顯示個位

  278. }

  279. /*********************************************************/
  280. // 液晶顯示初始化
  281. /*********************************************************/
  282. void LcdShowInit()
  283. {
  284.         LcdGotoXY(0,0);                                        // 液晶光標定位到第0行
  285.         LcdPrintStr("Gas:            ");                // 液晶第0行顯示" Gas:           "
  286.         LcdGotoXY(1,0);                                        // 液晶光標定位到第1行
  287.         LcdPrintStr("Tmp:            ");        // 液晶第1行顯示"Temp:           "
  288. }

  289. /*********************************************************/
  290. // ADC0832的時鐘脈沖
  291. /*********************************************************/
  292. void WavePlus()
  293. {
  294.         _nop_();
  295.         ADC_CLK = 1;
  296.         _nop_();
  297.         ADC_CLK = 0;
  298. }

  299. /*********************************************************/
  300. // 獲取指定通道的A/D轉換結果
  301. /*********************************************************/
  302. uchar Get_ADC0832()
  303. {
  304.         uchar i;
  305.         uchar dat1=0;
  306.         uchar dat2=0;
  307.         ADC_CLK = 0;                                // 電平初始化
  308.         ADC_DAT = 1;
  309.         _nop_();
  310.         ADC_CS = 0;
  311.         WavePlus();                                // 起始信號
  312.         ADC_DAT = 1;
  313.         WavePlus();                                // 通道選擇的第一位
  314.         ADC_DAT = 0;      
  315.         WavePlus();                                // 通道選擇的第二位
  316.         ADC_DAT = 1;
  317.         for(i=0;i<8;i++)                        // 第一次讀取
  318.         {
  319.                 dat1<<=1;
  320.                 WavePlus();
  321.                 if(ADC_DAT)
  322.                         dat1=dat1|0x01;
  323.                 else
  324.                         dat1=dat1|0x00;
  325.         }
  326.         for(i=0;i<8;i++)                        // 第二次讀取
  327.         {
  328.                 dat2>>= 1;
  329.                 if(ADC_DAT)
  330.                         dat2=dat2|0x80;
  331.                 else
  332.                         dat2=dat2|0x00;
  333.                 WavePlus();
  334.         }
  335.         _nop_();                                        // 結束此次傳輸
  336.         ADC_DAT = 1;
  337.         ADC_CLK = 1;
  338.         ADC_CS  = 1;   
  339.         if(dat1==dat2)                                // 返回采集結果
  340.                 return dat1;
  341.         else
  342.                 return 0;

  343. }

  344. /*********************************************************/
  345. // 按鍵掃描
  346. /*********************************************************/
  347. void KeyScanf()
  348. {
  349.         if(Key1_P==0)
  350.         {
  351.                 LcdGotoXY(0,13);
  352.                 LcdWriteCmd(0x0f);                                // 顯示光標,并閃爍
  353.                
  354.                 /*****煙霧報警值的設置**********************/
  355.                 DelayMs(10);                                                // 延時去除按鍵按下的抖動
  356.                 while(!Key1_P);                                        // 等待按鍵釋放
  357.                 DelayMs(10);                                                   // 延時去除按鍵松開的抖動
  358.                
  359.                 while(Key1_P!=0)                                        // 如果按鍵1按下,那么跳到下一級設置
  360.                 {
  361.                         if(Key2_P==0)                                        // 如果減按鍵被按下       
  362.                         {
  363.                                 if(gMqAlarm>1)                        // 只有gMqAlarm大于1才能減1               
  364.                                         gMqAlarm--;                               
  365.                                 LcdGotoXY(0,11);                        // 液晶光標定位到第0行第11列
  366.                                 LcdPrintNum1(gMqAlarm);        // 刷新改變后的報警值
  367.                                 LcdGotoXY(0,13);
  368.                                 DelayMs(250);                                // 延時一下
  369.                         }
  370.                         if(Key3_P==0)                                        // 如果加按鍵被按下       
  371.                         {
  372.                                 if(gMqAlarm<100)                        // 只有gMqAlarm小于100才能加1
  373.                                         gMqAlarm++;                               
  374.                                 LcdGotoXY(0,11);                        // 液晶光標定位到第0行第11列
  375.                                 LcdPrintNum1(gMqAlarm);        // 刷新改變后的報警值
  376.                                 LcdGotoXY(0,13);
  377.                                 DelayMs(250);                                // 延時一下
  378.                         }
  379.                 }
  380.                
  381.                 /*****溫度報警值設置******************/
  382.                 LcdGotoXY(1,13);                                        // 光標定位
  383.                 DelayMs(10);                                                // 延時去除按鍵按下的抖動
  384.                 while(!Key1_P);                                        // 等待按鍵釋放
  385.                 DelayMs(10);                                                   // 延時去除按鍵松開的抖動
  386.                 while(Key1_P!=0)                                        // 如果按鍵1按下,則退出設置模式
  387.                 {
  388.                         if(Key2_P==0)                                        // 如果減按鍵被按下       
  389.                         {
  390.                                 if(gTempAlarm>-54)                // 只有gTempAlarm大于-54才能減1       
  391.                                         gTempAlarm--;                               
  392.                                 LcdGotoXY(1,11);                        // 液晶光標定位到第1行第11列
  393.                                 LcdPrintNum2(gTempAlarm);        // 刷新改變后的報警值
  394.                                 LcdGotoXY(1,13);
  395.                                 DelayMs(250);                                // 延時一下
  396.                         }
  397.                         if(Key3_P==0)                                        // 如果加按鍵被按下       
  398.                         {
  399.                                 if(gTempAlarm<125)                // 只有gTempAlarm小于125才能加1
  400.                                         gTempAlarm++;                               
  401.                                 LcdGotoXY(1,11);                        // 液晶光標定位到第0行第11列
  402.                                 LcdPrintNum2(gTempAlarm);        // 刷新改變后的報警值
  403.                                 LcdGotoXY(1,13);
  404.                                 DelayMs(250);                                // 延時一下
  405.                         }                               
  406.                 }
  407.                
  408.                 /*****退出報警值的設置***************/
  409.                 DelayMs(10);                                                // 延時去除按鍵按下的抖動
  410.                 while(!Key1_P);                                        // 等待按鍵釋放
  411.                 DelayMs(10);                                                   // 延時去除按鍵松開的抖動
  412.                
  413.                 Sector_Erase(0x2000);                                // 擦除單片機內部EEPROM的數據
  414.                 EEPROM_Write(0x2000,gMqAlarm);                // 將新設置的煙霧報警值寫入EEPROM
  415.                 EEPROM_Write(0x2001,gTempAlarm+55);        // 將新設置的溫度報警值+55寫入
  416.                 LcdWriteCmd(0x0c);                                        // 關閉光標
  417.         }
  418. }

  419. /*********************************************************/
  420. // 報警判斷
  421. /*********************************************************/
  422. void AlarmJudge(uchar dat1, int dat2)
  423. {
  424. /*火焰報警判斷*/
  425.         if(Fire_P==0)
  426.         {
  427.                 DelayMs(50);
  428.                 if(Fire_P==0)
  429.                 {
  430.                         Led1_P=0;
  431.                 }
  432.         }
  433.         else
  434.         {
  435.                 Led1_P=1;
  436.         }
  437.        
  438.         /*煙霧報警判斷*/
  439.         if(dat1>gMqAlarm)
  440.         {
  441.                 Led3_P=0;
  442.         }
  443.         else
  444.         {
  445.                 Led3_P=1;
  446.         }
  447.        
  448.         /*溫度報警判斷*/
  449.         if(dat2>gTempAlarm)
  450.         {       
  451.                 Led2_P=0;
  452.         }
  453.         else
  454.         {
  455.                 Led2_P=1;
  456.         }

  457.         /*蜂鳴器報警判斷*/
  458.         if((Led1_P==0)||(Led2_P==0)||(Led3_P==0))
  459.                 Buzzer_P=0;
  460.         else
  461.                 Buzzer_P=1;
  462. }

  463. ……………………

  464. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
單片機程序.doc (64.5 KB, 下載次數: 27)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:561672 發表于 2019-12-13 13:43 | 只看該作者
有沒有程序流程圖  大神
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: www.久久久久久久久久久久 | 国产伦精品一区二区三区在线 | 中文字幕日韩欧美一区二区三区 | www.天天操 | 久久精品亚洲一区二区三区浴池 | 国产一区二区视频免费在线观看 | 日韩成人免费视频 | 成人免费久久 | 精品国产一区二区三区日日嗨 | 亚洲精品视频在线播放 | 国产精品欧美一区喷水 | 一区二区三区国产 | 国产小视频在线 | 国产一区成人 | 亚洲国产精品一区二区www | 日韩欧美国产精品 | 中文字幕一区在线 | 欧美一区二区在线观看 | 亚洲九色 | 欧美日产国产成人免费图片 | 免费黄色的视频 | 超碰综合 | 国产成人免费 | 日本午夜一区二区三区 | 伊人久麻豆社区 | 成人免费视频网站在线看 | 精品毛片 | 成人午夜在线 | www.9191 | 综合欧美亚洲 | 丝袜久久 | 成人福利在线观看 | 久久九九色| 一区二区国产精品 | www.五月天婷婷.com | 黄色一级大片视频 | 国产免费一区二区 | 欧美成人第一页 | 蜜桃视频一区二区三区 | 免费在线黄色av | 欧美不卡一区二区三区 |