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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

用STM8S103K單片機制作通風機控制器 有源碼有說明無圖紙

  [復制鏈接]
跳轉到指定樓層
樓主
剛開始學習單片機,這是我第一次做著玩的,希望別噴,所有模塊除了電源都買的成品,沒有畫圖.主要由外殼,LCD1602顯示屏, 4×4單線鍵盤, DS3231時鐘模塊, STM8S103最小系統板,電源模塊,DS18B20溫度傳感器,4繼電器模塊組成.
用途就是無線電業余中繼控制柜里散熱用通風機的邏輯控制,能夠控制通風機運行時間段,根據不同的當前溫度調整通風機轉速工況

FB-9B型通風機控制器使用說明書

目錄
1. 概述
1.1. 適用范圍
1.2. 功能
2. 主要技術參數
2.1. 環境條件
2.2. 技術參數
3. 安裝
3.1. 存儲
3.2. 安裝
4. 控制器組成
5. 使用與操作
5.1. 操作說明
5.2. 設置參數:
5.2.1. “日期時間參數設置”說明:
5.2.2. “溫度判定參數設置”說明:
5.2.3. “季節與時間段參數設置”說明:
6. 常見故障與處理
7. 裝箱單

  • 概述
    • 適用范圍

通風機控制器是為FB-9B橫流風機而設計的專用控制器。

1 控制器總圖

1.LCD1602液晶顯示屏;2.模擬量單線4×4鍵盤;3.DS18B20溫度傳感器插座;

4.通風機插座;5.電源插座與電源開關



    • 功能

時間顯示:通過DS3231時鐘芯片進行時鐘顯示,時間格式:24小時制,XX年XX月XX日,XX小時XX分XX秒。

溫度顯示: 通過DS18B20溫度傳感器對溫度進行測量溫度顯示范圍:-55℃~125℃。

通風機工況控制: 繼電器K1/K2/K3,根據日期、時間、當前溫度,可以控制通風機的啟動、停止、中速運行、高速運行。

顯示屏背光控制:繼電器K4控制顯示屏背光。

鍵盤輸入操作:主要實現參數信息輸入,功能界面變換,顯示屏背光控制觸發。

參數設置:可設定通風機允許工作的日期范圍,可設定通風機允許工作的時間范圍,可設定通風機中速運行的溫度范圍,可設定大于多少溫度通風機高速運行;可設定小于多少溫度通風機停止運行。

  • 主要技術參數
    • 環境條件

使用環境溫度                                          -25℃~60℃

空氣的相對濕度                            在95%以下(溫度為25℃時);

控制器禁止放在含有腐蝕性或爆炸性氣體(如灰塵、蒸汽或煤氣、石油液化氣等)的環境中。



    • 技術參數

                                 電   源:                                            AC220V. N. PE. 50Hz. 0.2kVA

顯   示:           LCD1602

鍵   盤:           模擬信號單線4×4小鍵盤

MCU芯片:                                            STM8S103K

時鐘芯片:                                 DS3231

溫度采集:                                 單路DS18B20

溫度測量范圍:      -55℃~125℃

顯示分辨率:        1℃

繼電器輸出:                              4組單觸點

       調試接口:          ST-LINK V2

控制電源:                                                        DC 5V 2A線性電源

控制器重量:                   300g

外形尺寸(L×W×H): 250×150×100 mm                           

  • 安裝
    • 存儲

長期儲存前,須對控制器進行保養、修復損壞器件,并對其進行徹底清理,保持技術狀態良好;

存放前,用保鮮膜將屏幕及鍵盤覆蓋;

應將控制器面板四個螺絲必須完全鎖閉;

應儲存在清潔、干燥、無腐蝕性氣體的環境中,避免周圍環境劇烈變化,無陽光直接照射并且不能堆放。

存儲溫度              -10~60℃;

空氣的相對濕度在95%以下(溫度為25℃時);



    • 安裝

FB-9B型通風機控制器安裝管理人員要仔細研究和分析控制器的設計方案和設計圖紙,理解使用方法、控制原理。

校驗控制器外型尺寸,確認安裝位置。

按照圖3連接控制器供電的電源線、連接控制器與通風機的線纜、連接控制器與DS18B20溫度傳感器的線纜,即安裝完畢。

2 控制面板實物圖片


3 接口實物圖片

  • 控制器組成

通風機控制器主要由DS18B20溫度傳感器,DS3231時鐘芯片,STM8S103K八位單片機,LCD1602液晶顯示器顯示,模擬量單線4×4鍵盤,繼電器K1/K2/K3/K4,供電模塊等組成。

4 DS18B20溫度傳感器實物圖片

5 DS3231時鐘芯片實物圖片

6 STM8S103K八位單片機實物圖片

7 LCD1602液晶顯示器實物圖片

8 繼電器K1/K2/K3/K4實物圖片

9 電源模塊實物圖片

10模擬量單線4×4鍵盤實物圖片

11通風機電機實物圖片

12 MCU控制系統原理框圖

  • 使用與操作
    • 操作說明

              鍵盤按鍵定義請參考圖10。

              通風機控制器正常使用只需要將圖1電源開關打開即可,無需其它操作。

該控制器控制通風機邏輯:

              當首次打開電源開關后,LCD1602屏幕背光開啟,進入系統初始化界面,初始化一切正常則進入圖13正常工作界面。

              開機首次進入正常工作界面后,LCD1602的背光將被自動關閉,如果需要打開背光按下鍵盤F1鍵,背光將被開啟,隨便按下任意按鍵之后再次按下F1鍵背光關閉。程序設計重復的按鍵操作是不被執行的,正常工作推薦關閉LCD1602背光。

              控制器正常工作狀態,每5秒左右更新一次溫度,通過溫度值控制通風機運行狀態,當溫度小于用戶設定溫度時通風機停止工作, 此時顯示屏工作狀態位顯示S。

              當大于用戶設定溫度上限時通風機高速運行, 此時顯示屏工作狀態位顯示H。

              當溫度設定在用戶設定溫度之間時通風機中速運行, 此時顯示屏工作狀態位顯示M。

              每個小時發生變化則對用戶設定的時間范圍參數進行檢查,當在用戶設定小時范圍內則通風機允許工作,否則不允許工作,這個判定優先級大于溫度判定, 此時顯示屏工作狀態位顯示C。

  每個月發生變化則對用戶設定的日期范圍參數進行檢查,當前值在用戶設月范圍內則通風機允許工作,否則不允許工作,這個判定優先級最高,此時顯示屏工作狀態位顯示C。

13正常工作界面

              第一行顯示XX年XX月XX日 星期幾 最后一個字符代表工作狀態位:S代表停機 M代表風機中速運行 H代表風機高速運行 C特殊季節或者特殊時間段風機不允許工作,這個參數可以根據使用情況自行設置,具體設置方法后面詳細描述

              第二行顯示XX小時XX分XX秒 T:代表溫度,系統大概5秒檢測一次溫度并在屏幕更新溫度值。



    • 設置參數:
      • 日期時間參數設置說明:
                            在圖13正常工作界面按下F2鍵進入圖14日期時間參數設置界面,在該界面下可以設置DS3231時鐘芯片的日期時間參數,其格式為XX年XX月XX日X星期XX小時XX分XX秒,也就是如圖14第一行YYMMDD W hhmmss。
第二行光標對應第一行的相應位,這時候按照順序輸入即可,但是每輸入一個字符必須按下OK鍵確認,輸入數據舉例,18年08月08日星期三12點30分30秒,則這樣操作:"1OK8OK0OK8OK0OK8OK OK1OK2OK3OK0OK3OK0OK",當敲入最后一個OK時自動更新數據并返回正常工作界面,如果輸入錯誤或者不想修改,只要最后一個OK沒有按下則隨時按下ESC鍵,則不更新數據并返回工作界面。

14 日期時間參數設置界面





      • 溫度判定參數設置說明:
                            在圖13正常工作界面按下F3鍵進入圖15溫度判定參數設置界面。
                            S:T<XX代表溫度小于XX通風機為停機狀態。
                            H:T>XX代表溫度大于XX通風機為高速運行狀態。
                            M:XX<T>XX代表溫度大于XX并且小于XX通風機為中速運行狀態。
                            每輸入一個字符必須按下OK鍵確認,輸入數據舉例,S:T<30 H:>40 M:40<T>30,則這樣操作:"3OK0OK4OK0OK4OK0OK3OK0OK",當敲入最后一個OK時自動更新數據并返回正常工作界面,如果輸入錯誤或者不想修改,只要最后一個OK沒有按下則隨時按下ESC鍵,則不更新數據并返回工作界面。

15 溫度判定參數設置界面





      • 季節與時間段參數設置說明:
                            在圖13正常工作界面按下F4鍵進入圖16季節與時間段參數設置界面。
                            RUN_H:XX<hh>XX代表小時大于多少XX并且小于多少XX通風機允許工作。
                            RUN_M:XX<MM>MM代表月份大于多少XX并且小于多少XX通風機允許工作。
                            每輸入一個字符必須按下OK鍵確認,輸入數據舉例,RUN_h:21<hh>08 RUN_M:10<MM>07。則這樣操作:"2OK1OK0OK8OK1OK0OK0OK7OK",當敲入最后一個OK時自動更新數據并返回正常工作界面,如果輸入錯誤或者不想修改,只要最后一個OK沒有按下則隨時按下ESC鍵,則不更新數據并返回工作界面。

16季節與時間段參數設置界面


  • 常見故障與處理

常見故障及處理方法:

序號

故障現象

處理方法

1

控制器不工作

1更換檢查FU1玻璃管保險絲;

2.檢查維修供電模塊;

3.更換檢查總開關;

4.檢查線路。

2

繼電器無動作

1檢查更換繼電器板;

2.檢查線路。

3

LCD1602屏幕不亮

  • 檢查供電線路;
  • 檢查K4繼電器動作是否正常。

4

無法進入系統界面

1.檢查DS18B20溫度傳感器電纜以及連接器;

2.檢查更換DS18B20溫度傳感器;

3.檢查線路。

5

通風機控制失效,控制標志位一直顯示C或S或M或H

  • 檢查時間條件參數的設置;
  • 檢查溫度條件參數的設置;
  • 當以上參數寫入不符合規則有可能造成,控制邏輯失常。

單片機源程序如下:


  1. /*****************************************************************
  2. * 實驗名稱及內容:風機控制
  3. * 實驗平臺及編程人員:stm8s103k3開發版 Hao
  4. ******************************************************************/
  5. #include "iostm8s103k3.h"//主控芯片的頭文件
  6. /*************************常用數據類型定義*************************/
  7. #define u8  uint8_t
  8. #define u16 uint16_t
  9. #define u32 uint32_t
  10. typedef unsigned char    uint8_t;//自定義類型
  11. typedef unsigned short   uint16_t;//自定義類型
  12. typedef unsigned long    uint32_t;//自定義類型
  13. /*************************端口/引腳定義區域************************/
  14. #define  LCDRS          PC_ODR_ODR1     //LCD1602數據/命令選擇端口
  15. #define  LCDRW          PC_ODR_ODR2     //LCD1602讀寫控制端口
  16. #define  LCDEN          PC_ODR_ODR3     //LCD1602使能信號端口
  17. #define  LCDDATA        PB_ODR          //LCD1602數據端口D0至D7
  18. #define  LCDBUSY        PB_IDR_IDR7     //LCD1602數據端口D7
  19. #define  DS18B20_DQ     PA_ODR_ODR3     //PA3單總線引腳位定義
  20. #define  K1             PD_ODR_ODR2     //PD2控制K1繼電器引腳定義
  21. #define  K2             PD_ODR_ODR3     //PD3控制K2繼電器引腳定義
  22. #define  K3             PD_ODR_ODR4     //PD4控制K3繼電器引腳定義
  23. #define  K4             PD_ODR_ODR5     //PD5控制K4繼電器引腳定義
  24. #define  SDA_OUT        PC_ODR_ODR7     //I2C總線時鐘引腳PC7(輸出)
  25. #define  SDA_IN         PC_IDR_IDR7     //I2C總線時鐘引腳PC7(輸入)
  26. #define  SCL            PC_ODR_ODR6     //I2C總線時鐘引腳PC6
  27. /***********************用戶自定義數據區域***********************/
  28. u8 table0[]="==Sys FAN init==";//LCD1602顯示字符串數組1顯示效果用初始化界面
  29. u8 table3[]={'0','1','2','3','4','5','6','7','8','9'};//0至9字符數組
  30. u8 add_word_year[]={0x08,0x0F,0x12,0x0F,0x0A,0x1F,0x02,0x02};//LCD1602自造字“年”地址00H
  31. u8 add_word_month[]={0x0F,0x09,0x0F,0x09,0x0F,0x09,0x11,0x00};//LCD1602自造字“月”地址01H
  32. u8 add_word_day[]={0x1F,0x11,0x11,0x1F,0x11,0x11,0x1F,0x00};//LCD1602自造字“日”地址02H
  33. u8 add_word_Temp[]={0x18,0x18,0x07,0x08,0x08,0x08,0x07,0x00};//LCD1602自造字“℃”地址05H
  34. static u16 Tem_u16=0;                   //整數溫度值變量
  35. static float Tem_f=0;                   //浮點數溫度值變量
  36. u8 flag=0;                               //溫度值正負標志變量
  37. u8 flag_DIS=0;                           //界面選擇標志位
  38. u8 cj=1;                                 //風機切換標志位
  39. u8 flag_time=0;                          //時間日期讀取標志位
  40. u8 flag_KOC=0,stemp1,stemp2;             //繼電器邏輯控制標志位
  41. u8 flag_save=0;//按鍵存儲數據標志位
  42. static u16 AD_Vtemp[10]={0};//裝載10次ADC采樣數據
  43. static u16 AD_val=0;//ADC單次采樣數據
  44. static u8 KEY_NO=0,KEY_NO1=0;;//按鍵鍵值碼
  45. static u16 GETvoltage=0;//獲取到的電壓
  46. u8 GETDS3231_DAT; //定義全局變量用于保存DS3231讀回數據值
  47. u8 OPT[8]={0x30,0x30,0x40,0x40,0x09,0x20,0x06,0x10};//用戶自定義選項參數數組
  48. u8 OPT1[8]={0x30,0x30,0x40,0x40,0x09,0x20,0x06,0x10};//用戶自定義選項參數數組
  49. u8 KS=0,qian,bai,shi,ge;//KS為按鍵按下標志位,qian為千位、百、十、個
  50. u8 year,month,day,week,hour,branch,second;//修改時間臨時存儲變量
  51. u8 mt,lt;//高位存儲臨時變量,低位存儲臨時變量

  52. /***************************函數聲明區域***************************/
  53. void delay(u16 Count);//延時函數聲明
  54. void delay_u(u16 Count);//us延時函數聲明
  55. void delay_ms(u16 Count);//ms延時函數聲明
  56. void GPIO_Init(void);//GPIO配置函數聲明
  57. void LCD1602_Write(u8 cmdordata,u8 writetype);//寫入液晶模組命令或數據函數聲明
  58. void LCD1602_init(void);//LCD1602初始化函數聲明
  59. void LCD1602_DIS(u8 val);//顯示字符函數聲明
  60. void LCD1602_Busy(void);//LCD1602判忙函數
  61. void add_word(void);//LCD1602自造字添加到CGRAM函數聲明
  62. void LCD1602_DIS_CHAR(u8 x,u8 y,u8 z);//在設定地址寫入字符數據函數聲明
  63. void LCD1602_DIS_CHAR_S(u8 x,u8 y,u8 z);//在設定地址寫入光標函數聲明
  64. void LCD1602_screen_sidesway(u8 x);//LCD1602屏幕移動函數聲明
  65. void LCD1602_cursor_sidesway(u8 x,u8 y);//LCD1602光標移動函數聲明
  66. void LCD1602_DIS_swich(u8 x,u8 y,u8 z);//LCD1602屏幕開關與光標開關函數聲明
  67. void LCD1602_DIS_Clear();//LCD1602屏幕清屏命令函數聲明
  68. void DS18B20_reset(void);               //DS18B20初始化時序
  69. void DS18B20_DQ_DDR(u8 ddr);            //DG單總線引腳方向配置函數
  70. void DS18B20_init(void);                //DS18B20初始化函數
  71. void DS18B20_Wbyte(u8 x);               //DS18B20寫字節函數
  72. u8 DS18B20_Rbit(void);                  //DS18B20讀總線位函數
  73. u8 DS18B20_Rbyte(void);                 //DS18B20讀字節函數
  74. void DS18B20_get_Temperature(void);     //溫度取值和處理函數
  75. void ADC_init(void);            //ADC2初始化函數聲明
  76. void ADC_GET(void);             //ADC2模數轉換函數聲明
  77. void AVG_AD_Vtemp(void);        //平均值濾波函數聲明
  78. void I2C_SDA_DDR(u8 ddr);//I2C_SDA串行數據引腳方向性配置函數聲明
  79. void I2C_START(void);//I2C總線起始信號配置函數聲明
  80. void I2C_STOP(void);//I2C總線終止信號配置函數聲明
  81. u8 I2C_Write8Bit(u8 DAT);//I2C總線單字節數據寫入函數聲明
  82. u8 I2C_Read8BitNACK(void);//單字節數據讀出(發送無應答)函數聲明
  83. u8 I2C_Read8BitACK(void);//單字節數據讀出(發送應答)函數聲明
  84. u8 DS3231_ReadByte(u8 ADDR);//DS3231讀出單個字節函數聲明
  85. void DS3231_WriteByte(u8 ADDR,u8 DAT);//DS3231寫入單個字節函數聲明
  86. u8 BCD2HEX(u8 val); //BCD轉換為Byte函數聲明
  87. u8 HEX2BCD(u8 val); //Byte轉換為BCD碼函數聲明
  88. u8 unlock_EEPROM(void);//解鎖EEPROM函數聲明
  89. void OPTconfig(void);//OPT選項字節配置函數聲明
  90. void read_DS3231(void);//讀取日期函數聲明
  91. void read_18b20_flag(void);//上電讀取溫度判斷工作位標志函數聲明
  92. void key_Testing(void);//鍵盤檢測函數聲明
  93. void OPT_Load(void);//參數初始化函數聲明
  94. void K_OC(void);//繼電器邏輯控制函數聲明
  95. u8 ASC_shi(u8 val);//取十位變換0~9ASCII碼函數聲明
  96. u8 ASC_ge(u8 val);//取個位變換0~9ASCII碼函數聲明
  97. /**************************主函數區域****************************/
  98. int main( void )
  99. {
  100.     //************HSI->HSE時鐘自動切換流程及注釋說明************
  101.     //如果CLK_CMSR中的主時鐘源為HSI,則CLK_CMSR=0xE1
  102.     //如果CLK_CMSR中的主時鐘源為LSI,則CLK_CMSR=0xD2
  103.     //如果CLK_CMSR中的主時鐘源為HSE,則CLK_CMSR=0xB4
  104.     if(CLK_CMSR!=0xB4)
  105.     //判斷主時鐘狀態寄存器CLK_CMSR中的主時鐘源是否是HSE
  106.     //若不是則進入if程序段
  107.     {
  108.       //1.首先要配置時鐘切換使能位SWEN=1,使能切換過程
  109.       CLK_SWCR|=0x02;//展開為二進制0000 0010 SWEN位=1
  110.       //2.選擇主時鐘源,對主時鐘切換寄存器CLK_SWR寫入欲切換時鐘
  111.       CLK_SWR=0xB4;//配置CLK_CMSR中的主時鐘源為HSE
  112.       //3.等待時鐘切換控制寄存器CLK_SWCR中的切換中斷標志位SWIF=1
  113.       while((CLK_SWCR & 0x08)==0);
  114.       //4.清除相關標志位
  115.       CLK_SWCR=0;
  116.     }
  117.    
  118.     GPIO_Init();                         //配置GPIO
  119.     LCD1602_init();                      //LCD1602初始化   
  120.     K4=1;                                //打開LCD1602背光
  121.     LCD1602_DIS(0);                      //顯示系統初始化界面   
  122.     LCD1602_DIS(1);                      //顯示控制系統正常運行界面
  123.     delay_ms(500);
  124.     K4=0;                                //進入正常運行界面后關閉LCD1602背光
  125.     ADC_init();                          //初始化ADC   
  126.     OPT_Load();                          //讀取系統參數
  127.     DS18B20_init();                      //初始化DS18B20設備
  128.     read_18b20_flag();                   //讀取18B20溫度確定標志位
  129.     u8 time=255;                         //溫度采集標志
  130.    
  131.    
  132.     IWDG_KR=0xCC;//軟件程序啟用IWDG
  133.     IWDG_KR=0x55;//允許對受保護的IWDG_PR和IWDG_RLR寄存器進行操作
  134.     //*********************預分頻因子配置語句**********************
  135.     //IWDG_PR=0;//設定預分頻因子為4分頻
  136.     //IWDG_PR=0x01;//設定預分頻因子為8分頻
  137.     //IWDG_PR=0x02;//設定預分頻因子為16分頻
  138.     //IWDG_PR=0x03;//設定預分頻因子為32分頻
  139. //    IWDG_PR=0x04;//設定預分頻因子為64分頻
  140.     //IWDG_PR=0x05;//設定預分頻因子為128分頻
  141.     IWDG_PR=0x06;//設定預分頻因子為256分頻
  142.     //*************************************************************
  143.     IWDG_RLR=0xFF;//配置重裝載寄存器數值為最大0xFF
  144.     IWDG_KR=0xAA;//刷新IWDG相關配置
  145.    
  146.     while(1)
  147.     {      
  148.       IWDG_KR=0xAA;//執行完成delay函數后“喂狗”
  149.       key_Testing();//鍵盤檢測
  150.       if(flag_DIS==1)
  151.       {
  152.         read_DS3231();//讀取DS3231時鐘數據
  153.         
  154.         if(time>20)
  155.         {
  156.           time=0;        
  157.           DS18B20_init();       //初始化DS18B20設備
  158.           delay(15);
  159.           DS18B20_get_Temperature();//溫度取值和處理
  160.           delay(15);//等待采樣轉換完成   
  161.           if(flag==1)//溫度正負判斷
  162.             LCD1602_DIS_CHAR(2,11,'+');//在第2行第10列顯示+
  163.           else
  164.             LCD1602_DIS_CHAR(2,11,'-');//在第2行第10列顯示-
  165.       
  166.           bai=Tem_u16%1000/100;//取轉換百位
  167.           shi=Tem_u16%100/10;//取轉換十位
  168.           ge=Tem_u16%10;//取轉換個位      

  169.           LCD1602_DIS_CHAR(2,12,table3[bai]);//在設定地址寫入百位
  170.           LCD1602_DIS_CHAR(2,13,table3[shi]);//在設定地址寫入十位
  171.           LCD1602_DIS_CHAR(2,14,table3[ge]);//在設定地址寫入個位
  172.                         
  173.           if(stemp2==1)//判定月份是否在范圍內   
  174.           {      
  175.             if(stemp1==1)//判斷小時是否在范圍內  
  176.             {        
  177.               flag_KOC=1;//判斷在月份內,符合小時范圍內,繼電器邏輯控制允許啟動
  178.             }
  179.             else
  180.             {
  181.               flag_KOC=0;      
  182.             }
  183.           }
  184.           else//如果月份不在范圍內,繼電器邏輯控制不允許啟動
  185.           {      
  186.             flag_KOC=0;   
  187.           }   
  188.           if(flag_KOC==1)
  189.           {
  190.             K_OC();//繼電器邏輯控制
  191.           }
  192.           else
  193.           {
  194.             cj=1;            
  195.             K3=0;            
  196.             K2=0;            
  197.             K1=0;            
  198.             LCD1602_DIS_CHAR(1,15,'C');//在第1行第15列顯示風機停止運轉狀態           
  199.           }
  200.         }
  201.         else
  202.         {
  203.           time=time+1;
  204.         }
  205.       }
  206.     }
  207. }
  208. /****************************************************************/
  209. //延時函數delay(),有形參Count用于控制延時函數執行次數,無返回值
  210. /****************************************************************/
  211. void delay(u16 Count)//延時函數
  212. {
  213.   Count=Count*200;
  214.   u8 i,j;
  215.   while (Count--)//Count形參控制延時次數
  216.   {
  217.     IWDG_KR=0xAA;//執行完成delay函數后“喂狗”
  218.     for(i=0;i<50;i++)
  219.       for(j=0;j<20;j++);
  220.   }
  221. }
  222. /****************************************************************/
  223. //延時函數delay_u(),有形參Count,無返回值
  224. /****************************************************************/
  225. void delay_u(u16 Count)
  226. {  
  227.   do{ }//直到型循環執行空操作
  228.   while(Count--);//Count形參控制執行次數影響延時時間
  229. }
  230. /****************************************************************/
  231. //延時函數delay_ms(),有形參Count用于控制延時函數執行次數,無返回值
  232. /****************************************************************/
  233. void delay_ms(u16 Count)//延時函數
  234. {
  235.   u16 i;     
  236.   while(Count--)
  237.     IWDG_KR=0xAA;//執行完成delay函數后“喂狗”
  238.     for(i=900;i>0;i--)
  239.     delay_u(1);
  240. }
  241. /****************************************************************/
  242. //LCD1602判忙函數LCD1602_Busy(),無形參和返回值
  243. /****************************************************************/
  244. void LCD1602_Busy(void)
  245. {     
  246.     LCDRS=0;              //判斷寫入類型0為命令1為數據      
  247.     LCDRW=1;
  248.     PB_DDR_DDR7=0;        //配置PB7為輸入模式
  249.     PB_CR1_C17=0;         //配置PB7為懸浮輸入模式
  250.     PB_CR2_C27=0;         //配置PB7關閉
  251.     do
  252.     {      
  253.       LCDEN=0;//使能清“0”   
  254.       LCDEN=1;//使能置“1”
  255.     }while(LCDBUSY==1);
  256.     LCDEN=0;
  257.     LCDRW=0;
  258.     delay(50);
  259.     PB_DDR_DDR7=1;        //配置PB7為輸出模式
  260.     PB_CR1_C17=1;         //配置PB7為推挽輸出模式
  261.     PB_CR2_C27=0;         //配置PB7低速
  262.     delay(50);
  263. }
  264. /****************************************************************/
  265. //LCD1602初始化函數LCD1602_init(),無形參和返回值
  266. /****************************************************************/
  267. void LCD1602_init(void)
  268. {
  269.   LCD1602_Write(0x02,0);//數據總線為4位
  270.   LCD1602_Write(0x28,0);//數據總線為4位,顯示2行,5*7點陣/每字符  
  271.   LCD1602_DIS_swich(1,0,0);//設置開顯示,不顯示光標
  272.   LCD1602_Write(0x06,0);//寫入新數據后顯示屏整體不移動僅光標右移
  273.   LCD1602_DIS_Clear();//LCD1602清屏命令
  274.   add_word();//加載自造字到CGRAM
  275. }
  276. /****************************************************************/
  277. //顯示字符函數LCD1602_DIS(),有形參無返回值
  278. /****************************************************************/
  279. void LCD1602_DIS(u8 val)
  280. {
  281.   if(val==0)//系統初始化界面顯示
  282.   {
  283.     LCD1602_Write(0x01,0);//寫入清屏命令
  284.     u8 i;//定義控制循環變量i
  285.     LCD1602_Write(0x80,0);//選擇第一行
  286.     for(i=0;i<16;i++)
  287.     {
  288.       LCD1602_Write(table0[i],1);//寫入table1[]內容
  289.       delay(5);
  290.     }
  291.     LCD1602_Write(0xC0,0);//選擇第二行
  292.     for(i=0;i<16;i++)
  293.     {
  294.       LCD1602_Write('>',1);//帶延時逐一顯示字符“*”模擬進度條
  295.       delay(100);
  296.     }
  297.     flag_DIS=0;//屏幕標志位 ,系統初始化界面
  298.   }  
  299.   if(val==1)//正常工作界面顯示,時鐘 溫度 風機工作狀態
  300.   {
  301.     LCD1602_Write(0x01,0);//寫入清屏命令
  302.     LCD1602_Write(0x80,0);//選擇第一行
  303.     LCD1602_DIS_CHAR(1,0,' ');
  304.     LCD1602_DIS_CHAR(1,1,' ');
  305.     LCD1602_DIS_CHAR(1,2,0x00);
  306.     LCD1602_DIS_CHAR(1,3,' ');
  307.     LCD1602_DIS_CHAR(1,4,' ');
  308.     LCD1602_DIS_CHAR(1,5,0x01);
  309.     LCD1602_DIS_CHAR(1,6,' ');
  310.     LCD1602_DIS_CHAR(1,7,' ');
  311.     LCD1602_DIS_CHAR(1,8,0x02);
  312.     LCD1602_DIS_CHAR(1,9,' ');
  313.     LCD1602_DIS_CHAR(1,10,' ');
  314.     LCD1602_DIS_CHAR(1,11,' ');
  315.     LCD1602_DIS_CHAR(1,12,' ');
  316.     LCD1602_DIS_CHAR(1,13,' ');
  317.     LCD1602_DIS_CHAR(1,14,' ');
  318.     LCD1602_DIS_CHAR(1,15,' ');

  319.     LCD1602_DIS_CHAR(2,0,' ');
  320.     LCD1602_DIS_CHAR(2,1,' ');
  321.     LCD1602_DIS_CHAR(2,2,':');
  322.     LCD1602_DIS_CHAR(2,3,' ');
  323.     LCD1602_DIS_CHAR(2,4,' ');
  324.     LCD1602_DIS_CHAR(2,5,':');
  325.     LCD1602_DIS_CHAR(2,6,' ');
  326.     LCD1602_DIS_CHAR(2,7,' ');
  327.     LCD1602_DIS_CHAR(2,8,' ');
  328.     LCD1602_DIS_CHAR(2,9,'T');
  329.     LCD1602_DIS_CHAR(2,10,':');
  330.     LCD1602_DIS_CHAR(2,11,' ');
  331.     LCD1602_DIS_CHAR(2,12,' ');
  332.     LCD1602_DIS_CHAR(2,13,' ');
  333.     LCD1602_DIS_CHAR(2,14,' ');
  334.     LCD1602_DIS_CHAR(2,15,0x05);//在設定地址寫入個位
  335.     read_18b20_flag();//進入正常工作界面后,重新檢測溫度并且對控制風機狀態標志位初始化
  336.     flag_DIS=1;//屏幕標志位 ,正常工作界面顯示,時鐘 溫度 風機工作狀態     
  337.   }  
  338.   if(val==2)//設置風機調速控制溫度值界面
  339.   {
  340.     LCD1602_Write(0x01,0);//寫入清屏命令
  341.     LCD1602_Write(0x80,0);//選擇第一行
  342.     LCD1602_DIS_CHAR(1,0,'S');
  343.     LCD1602_DIS_CHAR(1,1,':');
  344.     LCD1602_DIS_CHAR(1,2,'T');
  345.     LCD1602_DIS_CHAR(1,3,'<');
  346.     LCD1602_DIS_CHAR(1,4,ASC_shi(OPT[0]));
  347.     LCD1602_DIS_CHAR(1,5,ASC_ge(OPT[0]));
  348.     LCD1602_DIS_CHAR(1,6,' ');
  349.     LCD1602_DIS_CHAR(1,7,' ');
  350.     LCD1602_DIS_CHAR(1,8,'H');
  351.     LCD1602_DIS_CHAR(1,9,':');
  352.     LCD1602_DIS_CHAR(1,10,'T');
  353.     LCD1602_DIS_CHAR(1,11,'>');
  354.     LCD1602_DIS_CHAR(1,12,ASC_shi(OPT[1]));
  355.     LCD1602_DIS_CHAR(1,13,ASC_ge(OPT[1]));
  356.     LCD1602_DIS_CHAR(1,14,' ');
  357.     LCD1602_DIS_CHAR(1,15,' ');

  358.     LCD1602_DIS_CHAR(2,0,'M');
  359.     LCD1602_DIS_CHAR(2,1,':');
  360.     LCD1602_DIS_CHAR(2,2,ASC_shi(OPT[2]));
  361.     LCD1602_DIS_CHAR(2,3,ASC_ge(OPT[2]));
  362.     LCD1602_DIS_CHAR(2,4,'<');
  363.     LCD1602_DIS_CHAR(2,5,'T');
  364.     LCD1602_DIS_CHAR(2,6,'>');
  365.     LCD1602_DIS_CHAR(2,7,ASC_shi(OPT[3]));
  366.     LCD1602_DIS_CHAR(2,8,ASC_ge(OPT[3]));
  367.     LCD1602_DIS_CHAR(2,9,' ');
  368.     LCD1602_DIS_CHAR(2,10,' ');
  369.     LCD1602_DIS_CHAR(2,11,' ');
  370.     LCD1602_DIS_CHAR(2,12,' ');
  371.     LCD1602_DIS_CHAR(2,13,' ');
  372.     LCD1602_DIS_CHAR(2,14,' ');
  373.     LCD1602_DIS_CHAR(2,15,' ');//在設定地址寫入個位
  374.     LCD1602_DIS_CHAR_S(1,4,1);//在設定地址顯示光標閃爍
  375.     flag_DIS=2;//屏幕標志位 ,設置風機調速控制溫度值界面
  376.   }
  377.   if(val==3)//設置系統時鐘界面
  378.   {
  379.     LCD1602_Write(0x01,0);//寫入清屏命令
  380.     LCD1602_Write(0x80,0);//選擇第一行第1列
  381.     LCD1602_DIS_CHAR(1,0,'Y');
  382.     LCD1602_DIS_CHAR(1,1,'Y');
  383.     LCD1602_DIS_CHAR(1,2,'M');
  384.     LCD1602_DIS_CHAR(1,3,'M');
  385.     LCD1602_DIS_CHAR(1,4,'D');
  386.     LCD1602_DIS_CHAR(1,5,'D');
  387.     LCD1602_DIS_CHAR(1,6,' ');
  388.     LCD1602_DIS_CHAR(1,7,'W');
  389.     LCD1602_DIS_CHAR(1,8,' ');
  390.     LCD1602_DIS_CHAR(1,9,'h');
  391.     LCD1602_DIS_CHAR(1,10,'h');
  392.     LCD1602_DIS_CHAR(1,11,'m');
  393.     LCD1602_DIS_CHAR(1,12,'m');
  394.     LCD1602_DIS_CHAR(1,13,'s');
  395.     LCD1602_DIS_CHAR(1,14,'s');
  396.     LCD1602_DIS_CHAR(1,15,' ');

  397.     LCD1602_DIS_CHAR(2,0,' ');
  398.     LCD1602_DIS_CHAR(2,1,' ');
  399.     LCD1602_DIS_CHAR(2,2,' ');
  400.     LCD1602_DIS_CHAR(2,3,' ');
  401.     LCD1602_DIS_CHAR(2,4,' ');
  402.     LCD1602_DIS_CHAR(2,5,' ');
  403.     LCD1602_DIS_CHAR(2,6,' ');
  404.     LCD1602_DIS_CHAR(2,7,' ');
  405.     LCD1602_DIS_CHAR(2,8,' ');
  406.     LCD1602_DIS_CHAR(2,9,' ');
  407.     LCD1602_DIS_CHAR(2,10,' ');
  408.     LCD1602_DIS_CHAR(2,11,' ');
  409.     LCD1602_DIS_CHAR(2,12,' ');
  410.     LCD1602_DIS_CHAR(2,13,' ');
  411.     LCD1602_DIS_CHAR(2,14,' ');
  412.     LCD1602_DIS_CHAR(2,15,' ');//在設定地址寫入個位
  413.     LCD1602_DIS_CHAR_S(2,0,1);//在設定地址顯示光標閃爍
  414.     flag_DIS=3;//屏幕標志位 ,設置系統時鐘界面
  415.   }
  416.   if(val==4)//設置風機允許運行時間的參數界面
  417.   {
  418.     LCD1602_Write(0x01,0);//寫入清屏命令
  419.     LCD1602_Write(0x80,0);//選擇第一行
  420.     LCD1602_DIS_CHAR(1,0,'R');
  421.     LCD1602_DIS_CHAR(1,1,'U');
  422.     LCD1602_DIS_CHAR(1,2,'N');
  423.     LCD1602_DIS_CHAR(1,3,'_');
  424.     LCD1602_DIS_CHAR(1,4,'h');
  425.     LCD1602_DIS_CHAR(1,5,':');
  426.     LCD1602_DIS_CHAR(1,6,ASC_shi(OPT[4]));
  427.     LCD1602_DIS_CHAR(1,7,ASC_ge(OPT[4]));
  428.     LCD1602_DIS_CHAR(1,8,'<');
  429.     LCD1602_DIS_CHAR(1,9,'h');
  430.     LCD1602_DIS_CHAR(1,10,'h');
  431.     LCD1602_DIS_CHAR(1,11,'>');
  432.     LCD1602_DIS_CHAR(1,12,ASC_shi(OPT[5]));
  433.     LCD1602_DIS_CHAR(1,13,ASC_ge(OPT[5]));
  434.     LCD1602_DIS_CHAR(1,14,' ');
  435.     LCD1602_DIS_CHAR(1,15,' ');

  436.     LCD1602_DIS_CHAR(2,0,'R');
  437.     LCD1602_DIS_CHAR(2,1,'U');
  438.     LCD1602_DIS_CHAR(2,2,'N');
  439.     LCD1602_DIS_CHAR(2,3,'_');
  440.     LCD1602_DIS_CHAR(2,4,'M');
  441.     LCD1602_DIS_CHAR(2,5,':');
  442.     LCD1602_DIS_CHAR(2,6,ASC_shi(OPT[6]));
  443.     LCD1602_DIS_CHAR(2,7,ASC_ge(OPT[6]));
  444.     LCD1602_DIS_CHAR(2,8,'<');
  445.     LCD1602_DIS_CHAR(2,9,'M');
  446.     LCD1602_DIS_CHAR(2,10,'M');
  447.     LCD1602_DIS_CHAR(2,11,'>');
  448.     LCD1602_DIS_CHAR(2,12,ASC_shi(OPT[7]));
  449.     LCD1602_DIS_CHAR(2,13,ASC_ge(OPT[7]));
  450.     LCD1602_DIS_CHAR(2,14,' ');
  451.     LCD1602_DIS_CHAR(2,15,' ');//在設定地址寫入個位
  452.     LCD1602_DIS_CHAR_S(1,6,1);//在設定地址顯示光標閃爍
  453.     flag_DIS=4;//屏幕標志位 ,設置風機允許運行時間的參數界面
  454.   }
  455. }
  456. /****************************************************************/
  457. //寫入液晶模組命令或數據函數LCD1602_Write(),有形參cmdordata
  458. //和writetype,無返回值。
  459. /****************************************************************/
  460. void LCD1602_Write(u8 cmdordata,u8 writetype)
  461. {
  462.     LCD1602_Busy();//LCD1602判忙
  463.     LCDRS=writetype;//判斷寫入類型0為命令1為數據   
  464.     LCDDATA &= 0x0F; //清高四位   
  465.     LCDDATA|=cmdordata & 0xF0; //寫高四位   
  466.     LCDEN=1;delay(5);//使能置“1”
  467.     LCDEN=0;delay(5);//使能清“0”
  468.     cmdordata=cmdordata << 4; //低四位移到高四位
  469.     LCDDATA &= 0x0F; //清高四位  
  470.     LCDDATA |= cmdordata & 0xF0; //寫低四位
  471.     LCDEN=1;delay(5);//使能置“1”
  472.     LCDEN=0;delay(5);//使能清“0”
  473. }
  474. /****************************************************************/
  475. //寫入液晶模組自造字“月”add_yue(),無形參和返回值
  476. /****************************************************************/
  477. void add_word() //自造字庫“年、月、日、$、元、℃、↑、10”
  478. {
  479.   int a,b;
  480.   for (a=0x40;a<0x48;a++)//年
  481.   {
  482.     LCD1602_Write(a,0);   
  483.     b=a&0x0f;
  484.     LCD1602_Write(add_word_year[b],1);   
  485.   }  
  486.   for (a=0x48;a<0x50;a++)//月
  487.   {
  488.     LCD1602_Write(a,0);   
  489.     b=a&0x07;
  490.     LCD1602_Write(add_word_month[b],1);   
  491.   }
  492.   for (a=0x50;a<0x58;a++)//日
  493.   {
  494.     LCD1602_Write(a,0);   
  495.     b=a&0x0f;
  496.     LCD1602_Write(add_word_day[b],1);   
  497.   }  
  498.   for (a=0x68;a<0x70;a++)//℃
  499.   {
  500.     LCD1602_Write(a,0);
  501.     b=a&0x07;
  502.     LCD1602_Write(add_word_Temp[b],1);   
  503.   }
  504. }
  505. /****************************************************************/
  506. //設定地址寫入字符函數LCD1602_DIS_CHAR(),有形參x、y、z無返回值
  507. //x表示1602液晶的行,y表示列地址,z表示欲寫入的字符
  508. /****************************************************************/
  509. void LCD1602_DIS_CHAR(u8 x,u8 y,u8 z)
  510. {
  511.   LCD1602_DIS_swich(1,0,0);//設置開顯示,不顯示光標
  512.   u8 address;
  513.   if(x==1)//若欲顯示在第一行
  514.     address=0x80+y;//第一行的行首地址+列地址
  515.   else
  516.     address=0xC0+y;//第二行的行首地址+列地址
  517.   LCD1602_Write(address,0);//設定顯示地址
  518.   LCD1602_Write(z,1);//寫入字符數據
  519. }
  520. /****************************************************************/
  521. //設定地址寫入光標函數聲明LCD1602_DIS_CHAR_S(),有形參x、y無返回值
  522. //x表示1602液晶的行,y表示列地址,z=1表示開顯示,顯示光標,z=0表示開顯示,不顯示光標
  523. /****************************************************************/
  524. void LCD1602_DIS_CHAR_S(u8 x,u8 y,u8 z)
  525. {
  526.   if(z==1)   
  527.     LCD1602_DIS_swich(1,1,1);//設置開顯示,顯示光標
  528.   else
  529.     LCD1602_DIS_swich(1,0,0);//設置開顯示,不顯示光標
  530.   u8 address;
  531.   if(x==1)//若欲顯示在第一行
  532.     address=0x80+y;//第一行的行首地址+列地址
  533.   else
  534.     address=0xC0+y;//第二行的行首地址+列地址
  535.   LCD1602_Write(address,0);//設定顯示地址
  536. }
  537. /****************************************************************/
  538. //設定LCD1602液晶顯示與光標顯示的函數LCD1602_DIS_swich(),有形參x、y、z無返回值
  539. //x表示1602顯示,y表示1602光標顯示,z表示1602光標閃動
  540. /****************************************************************/
  541. void LCD1602_DIS_swich(u8 x,u8 y,u8 z)
  542. {
  543.   int a=0x08;
  544.   if(x==1)   
  545.   {
  546.     a=a|0x04;
  547.   }
  548.   if(y==1)
  549.   {
  550.     a=a|0x02;
  551.   }
  552.   if(z==1)
  553.   {
  554.    a=a|0x01;
  555.   }
  556.   LCD1602_Write(a,0);
  557. }
  558. /****************************************************************/
  559. //設定LCD1602液晶畫面平移的函數LCD1602_screen_sidesway(),有形參x無返回值
  560. //x=1畫面向右移動一個字符;X=0畫面向左移動一個字符
  561. /****************************************************************/
  562. void LCD1602_screen_sidesway(u8 x)
  563. {
  564.   if(x==1)
  565.   {
  566.     LCD1602_Write(0x1c,0);//畫面向右平移一個字符位
  567.   }
  568.   else
  569.   {
  570.     LCD1602_Write(0x18,0);//畫面向左平移一個字符位
  571.   }
  572. }
  573. /****************************************************************/
  574. //設定LCD1602液晶畫面平移的函數LCD1602_cursor_sidesway(),有形參x,y無返回值
  575. //x=1光標向右移動;X=0光標向左移動 y代表多少個字符
  576. /****************************************************************/
  577. void LCD1602_cursor_sidesway(u8 x,u8 y)
  578. {
  579.   for(int i=0;i<y;i++)
  580.   {
  581.     if(x==1)
  582.     {  
  583.       LCD1602_Write(0x14,0);//光標向右平移一個字符位
  584.     }
  585.     else
  586.     {
  587.       LCD1602_Write(0x10,0);//光標向左平移一個字符位
  588.     }
  589.   }
  590. }
  591. /****************************************************************/
  592. //設定LCD1602液晶清屏LCD1602_DIS_Clear(),無形參無返回值
  593. /****************************************************************/
  594. void LCD1602_DIS_Clear()
  595. {
  596.   LCD1602_Write(0x01,0);//寫入清屏命令
  597. }
  598. /****************************************************************/
  599. //GPIO配置函數GPIO_Init(),無返回值
  600. /****************************************************************/
  601. void GPIO_Init(void)
  602. {
  603.   PD_DDR_DDR2=1;        //配置PD2為輸出模式 K1
  604.   PD_CR1_C12=1;         //配置PD2為推挽輸出模式 K1
  605.   PD_CR2_C22=0;         //配置PD2低速率輸出 K1
  606.   PD_DDR_DDR3=1;        //配置PD3為輸出模式 K2
  607.   PD_CR1_C13=1;         //配置PD3為推挽輸出模式 K2
  608.   PD_CR2_C23=0;         //配置PD3低速率輸出 K2
  609.   PD_DDR_DDR4=1;        //配置PD4為輸出模式 K3
  610.   PD_CR1_C14=1;         //配置PD4為推挽輸出模式 K3
  611.   PD_CR2_C24=0;         //配置PD4低速率輸出 K3
  612.   PD_DDR_DDR5=1;        //配置PD5為輸出模式 K4
  613.   PD_CR1_C15=1;         //配置PD5為推挽輸出模式 K4
  614.   PD_CR2_C25=0;         //配置PD5低速率輸出 K4
  615.   K4=0;                 //K4初始化為不輸出
  616.   
  617.   PC_DDR_DDR1=1;        //配置PC1為輸出模式
  618.   PC_CR1_C11=1;         //配置PC1為推挽輸出模式
  619.   PC_CR2_C21=0;         //配置PC1低速率輸出
  620.   
  621.   PC_DDR_DDR2=1;        //配置PC2為輸出模式
  622.   PC_CR1_C12=1;         //配置PC2為推挽輸出模式
  623.   PC_CR2_C22=0;         //配置PC2低速率輸出
  624.   LCDRW=0;              //配置LCD1602為寫入模式
  625.   
  626.   PC_DDR_DDR3=1;        //配置PC3為輸出模式
  627.   PC_CR1_C13=1;         //配置PC3為推挽輸出模式
  628.   PC_CR2_C23=0;         //配置PC3低速率輸出
  629.   
  630.   PC_DDR_DDR6=1;        //配置PC6引腳(SCL)為輸出模式
  631.   PC_CR1_C16=1;         //配置PC6引腳(SCL)為推挽輸出模式
  632.   PC_CR2_C26=0;         //配置PC6引腳(SCL)低速率輸出模式
  633.   
  634.   PB_DDR=0xF0;          //配置PB端口為輸出模式
  635.   PB_CR1=0xFF;          //配置PB端口為推挽輸出模式
  636.   PB_CR2=0x00;          //配置PB端口低速率輸出
  637.   LCDDATA=0xFF;         //初始化PB端口全部輸出高電平
  638.   
  639.   DS18B20_DQ_DDR(1);    //配置DQ單總線為輸出模式
  640.   DS18B20_DQ=1;         //配置DQ單總線為高電平狀態
  641.   delay(300);           //延時等待配置穩定  
  642. }
  643. /****************************************************************/
  644. //設備初始化時序產生函數DS18B20_reset(),無形參和返回值
  645. /****************************************************************/
  646. void DS18B20_reset(void)
  647. {
  648.   u8 x;//變量x用于取回總線電平狀態
  649.   DS18B20_DQ_DDR(1);//改變DQ引腳方向性為輸出方式
  650.   DS18B20_DQ=1;//控制器首先應為高電平狀態
  651.   delay_u(910);//延時大約800us
  652.   DS18B20_DQ=0;//控制器拉低總線發送復位脈沖
  653.   delay_u(910);//拉低時間大約800us
  654.   DS18B20_DQ=1;//控制器釋放總線
  655.   delay_u(30);//DS18B20等待大約30us
  656.   DS18B20_DQ_DDR(0);//改變DQ引腳方向性為輸入方式
  657.   delay_u(30);//等待DS18B20應答脈沖大約30us
  658.   x=PA_IDR_IDR3;//取回總線電平狀態
  659.   while(x);//等待應答脈沖出現低電平  
  660.   delay_u(900);//控制器等待至少480us
  661. }
  662. /****************************************************************/
  663. //設備DQ引腳方向性配置函數DS18B20_DQ_DDR(),有形參ddr無返回值
  664. /****************************************************************/
  665. void DS18B20_DQ_DDR(u8 ddr)
  666. {
  667.   if(ddr==1)//配置為輸出方式
  668.   {
  669.     PA_DDR_DDR3=1;//配置PA3引腳為輸出引腳
  670.     PA_CR1_C13=1;//配置PA3引腳為推挽輸出模式
  671.     PA_CR2_C23=0;//配置PA3引腳低速率輸出模式
  672.   }
  673.   else//配置為輸入方式
  674.   {
  675.     PA_DDR_DDR3=0;//配置PA3引腳為輸入引腳
  676.     PA_CR1_C13=1;// 配置PA3引腳為弱上拉模式   
  677.     PA_CR2_C23=0;//禁止PA3引腳外部中斷功能
  678.   }
  679. }
  680. /****************************************************************/
  681. //設備初始化函數DS18B20_init(),無形參和返回值
  682. /****************************************************************/
  683. void DS18B20_init(void)
  684. {
  685.   DS18B20_reset();//DS18B20初始化時序
  686.   delay_u(500);//等待初始化結束
  687.   DS18B20_Wbyte(0xCC);//寫ROM指令(跳過ROM)
  688.   DS18B20_Wbyte(0x44);//寫功能指令(溫度轉換)  
  689. }
  690. /****************************************************************/
  691. //設備寫一個字節函數DS18B20_Wbyte(),有形參xbyte無返回值
  692. /****************************************************************/
  693. void DS18B20_Wbyte(u8 xbyte)
  694. {
  695.   u8 i,x=0;//i為循環控制變量,x為取位運算變量
  696.   DS18B20_DQ_DDR(1);//改變DQ引腳方向性為輸出方式
  697.   for(i=0;i<8;i++)//8次循環實現逐位寫入
  698.   {
  699.     x=xbyte & 0x01;//從最低位取值到最高位
  700.     if(x)//寫“1”
  701.     {
  702.       DS18B20_DQ=0;//DQ單總線拉低
  703.       delay_u(13);//延時大約15us
  704.       DS18B20_DQ=1;//DQ單總線寫入“1”
  705.       delay_u(42);//延時大約45us
  706.       DS18B20_DQ=1;//最終保持高電平
  707.       delay_u(2);
  708.     }
  709.     else//寫“0”
  710.     {
  711.       DS18B20_DQ=0;//DQ單總線拉低
  712.       delay_u(13);//延時大約15us
  713.       DS18B20_DQ=0;//DQ單總線寫入“0”
  714.       delay_u(42);//延時大約45us
  715.       DS18B20_DQ=1;//最終保持高電平
  716.       delay_u(2);
  717.     }
  718.     xbyte=xbyte>>1;//右移一位實現逐位移出
  719.   }
  720. }
  721. /****************************************************************/
  722. //設備讀字節函數DS18B20_Rbyte(),無形參有返回值rbyte
  723. /****************************************************************/
  724. u8 DS18B20_Rbyte(void)
  725. {
  726.   u8 rbyte=0,i=0,tempbit=0;//rbyte是最終得到的字節,i為循環控制變量
  727.   //tempbit為逐位取出的中間運算變量
  728.   for(i=0;i<8;i++)//8次循環實現逐位拼合
  729.   {
  730.     tempbit=DS18B20_Rbit();//讀取單個位
  731.     rbyte=rbyte>>1;//右移實現將高低位排列
  732.     rbyte=rbyte|tempbit;//或運算移入數據
  733.   }
  734.   return rbyte;//返回最終字節
  735. }
  736. /****************************************************************/
  737. //設備讀取單個位函數DS18B20_Rbit(),無形參有返回值rbit
  738. /****************************************************************/
  739. u8 DS18B20_Rbit(void)
  740. {
  741.   u8 rbit=0,x=0;//rbit是最終位數據,x是取狀態變量
  742.   DS18B20_DQ_DDR(1);//改變DQ引腳方向性為輸出方式
  743.   DS18B20_DQ=0;//DQ單總線寫入“0”
  744.   delay_u(13);//延時大約15us
  745.   DS18B20_DQ=1;//釋放DQ單總線
  746.   DS18B20_DQ_DDR(0);//改變DQ引腳方向性為輸入方式
  747.   //delay_u(30);//延時大約15us【舊版本,應適當縮小這個時間】
  748.   delay_u(9);//延時小于15us,在10us左右【新版本】
  749.   x=PA_IDR_IDR3;//獲取單總線電平狀態
  750.   if(x)//狀態判定
  751.     rbit=0x80;//若為高電平則最高位“1”得到0x80反之為初始值0
  752.   delay_u(54);//延時大約60us
  753.   return rbit;////返回最終位數據
  754. }
  755. /****************************************************************/
  756. //設備溫度獲取和轉換函數DS18B20_get_Temperature(),無形參和返回值
  757. /****************************************************************/
  758. void DS18B20_get_Temperature(void)
  759. {
  760.   u8 msb_byte=0,lsb_byte=0;//msb是溫度值高位,lsb是溫度值低位
  761.   DS18B20_reset();//初始化時序
  762.   delay_u(900);//等待初始化穩定
  763.   DS18B20_Wbyte(0xCC);//寫ROM指令(跳過ROM)
  764.   DS18B20_Wbyte(0xBE);//寫功能指令(讀暫存器)
  765.   delay_u(900);//等待配置穩定  
  766.   lsb_byte=DS18B20_Rbyte();//讀取第一個低位數據字節
  767.   msb_byte=DS18B20_Rbyte();//讀取第二個高位數據字節  
  768.   Tem_u16=msb_byte;//先將高位給全局變量Tem_u16
  769.   Tem_u16=Tem_u16<<8;//然后將Tem_u16低8位左移為高8位
  770.   Tem_u16=Tem_u16|lsb_byte;//拼合低位給Tem_u16低8位  
  771.   if(Tem_u16<=0x07FF)//溫度值正負判斷
  772.     flag=1;//溫度值為正
  773.   else
  774.     flag=0;//溫度值為負
  775.   Tem_f=Tem_u16*0.0625;//乘以0.0625最小分辨值得到12位溫度實際值
  776.   Tem_u16=(u16)(Tem_f+0.5);//4舍5入得到溫度整數值  
  777. }
  778. /****************************************************************/
  779. //ADC2初始化函數ADC_init(),無形參,無返回值
  780. /****************************************************************/
  781. void ADC_init(void)
  782. {
  783.   //1.選擇模擬通道,按需配置中斷
  784.   ADC_CSR=0x00;//選擇通道AIN0(PB0),禁止中斷
  785.   //2.配置分頻系數,明確轉換模式
  786.   ADC_CR1=0x02;//配置預分頻為fMaster/2,連續轉換模式
  787.   //3.配置觸發事件,明確對齊方式
  788.   ADC_CR2=0x08;//禁止外部觸發,數據右對齊(先讀低再讀高)
  789.   //ADC_CR2=0x00;//禁止外部觸發,數據左對齊(先讀高再讀低)
  790.   //4.初始配置模擬通道(無中斷懸浮輸入)
  791.   PB_DDR_DDR0=0;//配置PB0端口為輸入模式
  792.   PB_CR1_C10=0;//配置PB0端口為懸浮輸入模式
  793.   PB_CR2_C20=0;//配置PB0端口禁止外部中斷
  794.   //5.按需禁止/使能施密特觸發器功能
  795.   ADC_TDRL=0x00;//使能斯密特觸發器
  796.   //6.使能ADC上電喚醒并禁用I/O輸出功能
  797.   ADC_CR1|=0x01;//首次將ADON位置1用于喚醒
  798.   //7.啟動ADC轉換并獲取轉換數據
  799.   //ADC_GET();//用戶編寫的ADC轉換函數
  800. }
  801. /****************************************************************/
  802. //ADC2模數轉換函數ADC_GET(),無形參,無返回值
  803. /****************************************************************/
  804. void ADC_GET(void)
  805. {
  806.   u8 num=0;//循環控制變量,用于控制次數
  807.   ADC_CR1=0x02;//配置預分頻為fMaster/2,連續轉換模式
  808.   ADC_CR1|=0x01;//首次將ADON位置1用于喚醒
  809.   ADC_CR1|=0x01;//再次將ADON位置1用于啟動ADC轉換
  810.   while(num<10)//采10次結果
  811.   {   
  812.     while((ADC_CSR & 0x80)==0);//等待ADC轉換結束
  813.     ADC_CSR &= 0x7F;//清除ADC轉換完成標志位
  814.     AD_Vtemp[num]=(u16)ADC_DRL;//先將ADC轉換數據低位賦值
  815.     AD_Vtemp[num]|=(u16)ADC_DRH<<8;//再將左移8位后的高位數據與原低位數據進行或連接
  816.     //(高位數據)+(低位數據)=完整ADC采樣數據結果
  817.     num++;//循環控制變量自增
  818.   }
  819.   ADC_CR1 &= 0xFD;//關閉ADC轉換
  820. }
  821. /****************************************************************/
  822. //平均值濾波函數AVG_AD_Vtemp(),無形參,無返回值
  823. /****************************************************************/
  824. void AVG_AD_Vtemp(void)
  825. {
  826.   u8 i,j;//定義排序用內外層循環變量i和j
  827.   u16 temp;//定義中間“暫存”變量temp
  828.   for(i=10;i>=1;i--)//外層循環
  829.   {
  830.     for(j=0;j<(i-1);j++)//內層循環
  831.     {
  832.       if(AD_Vtemp[j]>AD_Vtemp[j+1])//數值比較
  833.       {
  834.         temp=AD_Vtemp[j];//數值換位
  835.         AD_Vtemp[j]=AD_Vtemp[j+1];
  836.         AD_Vtemp[j+1]=temp;
  837.       }
  838.     }
  839.   }
  840.   for(i=2;i<=7;i++)//去掉2個最低去掉2個最高
  841.     AD_val+=AD_Vtemp[i];//將中間6個數值累加
  842.   AD_val=(u16)(AD_val/6);//累加和求平均值
  843. }
  844. /****************************************************************/
  845. //I2C_SDA串行數據引腳方向性配置函數I2C_SDA_DDR(),有形參ddr,無返回值
  846. /****************************************************************/
  847. void I2C_SDA_DDR(u8 ddr)
  848. {
  849.   if(ddr==1)//配置為輸出方式
  850.   {
  851.     PC_DDR_DDR7=1;//配置PC7引腳(SDA)為輸出引腳
  852.     PC_CR1_C17=1;//配置PC7引腳(SDA)為推挽輸出模式
  853.     PC_CR2_C27=0;//配置PC7引腳(SDA)低速率輸出模式
  854.   }
  855.   else//配置為輸入方式
  856.   {
  857.     PC_DDR_DDR7=0;//配置PC7引腳(SDA)為輸入引腳
  858.     PC_CR1_C17=1;//配置PC7引腳(SDA)為弱上拉輸入模式
  859.     PC_CR2_C27=0;//禁止PC7引腳(SDA)外部中斷功能
  860.   }
  861. }
  862. /****************************************************************/
  863. //I2C總線起始信號配置函數I2C_START(),無形參,無返回值
  864. /****************************************************************/
  865. void I2C_START(void)
  866. {
  867.   I2C_SDA_DDR(1);//配置SDA引腳為推挽輸出模式
  868.   SDA_OUT=1;//SDA引腳置為高電平
  869.   SCL=1;//SCL引腳置為高電平
  870.   delay(1);//延時等待
  871.   SDA_OUT=0;//將SDA置低產生下降沿(產生起始信號)
  872.   delay(1);//延時等待
  873.   SCL=0;//將SCL置低產生下降沿(允許SDA數據傳送)
  874.   delay(1);//延時等待
  875. }
  876. /****************************************************************/
  877. //I2C總線終止信號配置函數I2C_STOP(),無形參,無返回值
  878. /****************************************************************/
  879. void I2C_STOP(void)
  880. {
  881.   I2C_SDA_DDR(1);//配置SDA引腳為推挽輸出模式
  882.   SDA_OUT=0;//SDA引腳置為低電平
  883.   SCL=0;//SCL引腳置為低電平
  884.   delay(1);//延時等待
  885.   SCL=1;//將SCL引腳置高產生上升沿
  886.   delay(1);//延時等待
  887.   SDA_OUT=1;//將SDA引腳置高產生上升沿(產生終止信號)
  888.   delay(1);//延時等待
  889. }
  890. /****************************************************************/
  891. //I2C總線單字節數據寫入函數I2C_Write8Bit(u8 DAT),有形參DAT
  892. //有返回值I2C_Write_ACK(應答信號變量值),若返回值為“0”則有從機應答
  893. //若返回值為“1”則從機無應答
  894. /****************************************************************/
  895. u8 I2C_Write8Bit(u8 DAT)
  896. {
  897.   u8 num,I2C_Write_ACK=0;//定義循環控制變量num
  898.   //定義應答信號變量I2C_Write_ACK
  899.   I2C_SDA_DDR(1);//配置SDA引腳為推挽輸出模式
  900.   delay(1);//延時等待
  901.   for(num=0x80;num!=0;num>>=1)//執行8次循環
  902.   {
  903.     if((DAT&num)==0)//按位“與”判斷DAT每一位值
  904.       SDA_OUT=0;//判斷數值為“0”送出低電平
  905.     else
  906.       SDA_OUT=1;//判斷數值為“1”送出高電平
  907.     delay(1);//延時等待
  908.     SCL=1;//拉高SCL引腳以保持SDA引腳數據穩定
  909.     delay(1);//延時等待
  910.     SCL=0;//拉低SCL引腳以允許SDA引腳數據變動
  911.     delay(1);//延時等待
  912.   }
  913.   SDA_OUT=1;//置高SDA引腳電平(釋放數據線)
  914.   delay(1);//延時等待
  915.   SCL=1;//拉高SCL產生應答位時鐘
  916.   delay(1);//延時等待
  917.   I2C_SDA_DDR(0);//配置SDA引腳為弱上拉輸入模式
  918.   delay(1);//延時等待
  919.   I2C_Write_ACK=SDA_IN;//取回SDA線上電平賦值給應答信號變量
  920.   delay(1);//延時等待
  921.   SCL=0;//將SCL引腳置低
  922.   delay(5);
  923.   return I2C_Write_ACK;//將應答信號變量值進行返回
  924. }
  925. /****************************************************************/
  926. //單字節數據讀出函數(發送無應答)I2C_Read8BitNACK()
  927. //無形參,有返回值(讀出的單字節數據)
  928. /****************************************************************/
  929. u8 I2C_Read8BitNACK(void)
  930. {
  931.   u8 x,I2CDATA;//定義循環控制變量x,讀出數據暫存變量I2CDATA
  932.   I2C_SDA_DDR(1);//配置SDA引腳為推挽輸出模式
  933.   SDA_OUT=1;//首先確保主機釋放SDA
  934.   SCL=0;//置低SCL引腳以允許從機發送下一位
  935.   delay(1);//延時等待
  936.   I2C_SDA_DDR(0);//配置SDA引腳為弱上拉輸入模式
  937.   delay(1);//延時等待
  938.   for(x=0x80;x!=0;x>>=1)//從高位到低位依次進行
  939.   {
  940.     delay(1);//延時等待
  941.     SCL=1;//將SCL引腳置為高電平
  942.     if(SDA_IN==0)//讀取SDA引腳的電平狀態并進行判定
  943.       I2CDATA&=~x;//判定為“0”則將I2CDATA中對應位清零
  944.     else
  945.       I2CDATA|=x;//判定為“1”則將I2CDATA中對應位置“1”
  946.     delay(1);//延時等待
  947.     SCL=0;//置低SCL引腳以允許從機發送下一位
  948.   }
  949.   I2C_SDA_DDR(1);//配置SDA引腳為推挽輸出模式
  950.   delay(1);//延時等待
  951.   SDA_OUT=1;//8位數據發送后拉高SDA引腳發送“無應答信號”
  952.   delay(1);//延時等待
  953.   SCL=1;//將SCL引腳置為高電平
  954.   delay(1);//延時等待
  955.   SCL=0;//將SCL引腳置為低電平完成“無應答位”并保持總線
  956.   return I2CDATA;//將讀出的單字節數據進行返回
  957. }
  958. /****************************************************************/
  959. //單字節數據讀出函數(發送應答)I2C_Read8BitACK()
  960. //無形參,有返回值(讀出的單字節數據)
  961. /****************************************************************/
  962. u8 I2C_Read8BitACK(void)
  963. {
  964.   u8 x,I2CDATA;//定義循環控制變量x,讀出數據暫存變量I2CDATA
  965.   I2C_SDA_DDR(1);//配置SDA引腳為推挽輸出模式
  966.   delay(1);//延時等待
  967.   SDA_OUT=1;//首先確保主機釋放SDA
  968.   delay(1);//延時等待
  969.   I2C_SDA_DDR(0);//配置SDA引腳為弱上拉輸入模式
  970.   delay(1);//延時等待
  971.   for(x=0x80;x!=0;x>>=1)//從高位到低位依次進行
  972.   {
  973.     delay(1);//延時等待
  974.     SCL=1;//將SCL引腳置為高電平
  975.     if(SDA_IN==0)//讀取SDA引腳的電平狀態并進行判定
  976.       I2CDATA&=~x;//判定為“0”則將I2CDATA中對應位清零
  977.     else
  978.       I2CDATA|=x;//判定為“1”則將I2CDATA中對應位置“1”
  979.     delay(1);//延時等待
  980.     SCL=0;//置低SCL引腳以允許從機發送下一位
  981.   }
  982.   I2C_SDA_DDR(1);//配置SDA引腳為推挽輸出模式
  983.   delay(1);//延時等待
  984.   SDA_OUT=0;//8位數據發送后置低SDA引腳發送“應答信號”
  985.   delay(1);//延時等待
  986.   SCL=1;//將SCL引腳置為高電平
  987.   delay(1);//延時等待
  988.   SCL=0;//將SCL引腳置為低電平完成“應答位”并保持總線
  989.   return I2CDATA;//將讀出的單字節數據進行返回
  990. }
  991. /****************************************************************/
  992. //DS3231讀出單個字節函數DA3231_ReadByte(),有形參ADDR
  993. //ADDR為欲讀出數據的地址,有返回值DS3231_DATA(讀出的單字節數據)
  994. /****************************************************************/
  995. u8 DS3231_ReadByte(u8 ADDR)
  996. {
  997.   u8 DS3231_DATA;//定義變量用于存放讀出數據
  998.   I2C_START();//產生I2C通信起始信號
  999.   I2C_Write8Bit(0xD0);//寫入(器件地址+寫)指令
  1000.   I2C_Write8Bit(ADDR);//指定欲讀取DS3231芯片的地址
  1001.   I2C_START();//產生I2C通信起始信號
  1002.   I2C_Write8Bit(0xD1);//寫入(器件地址+讀)指令  
  1003.   DS3231_DATA=I2C_Read8BitNACK();//單字節讀取(發送無應答)
  1004.   I2C_STOP();//產生I2C通信終止信號
  1005.   return DS3231_DATA;//返回實際讀取到的數據值
  1006. }
  1007. /****************************************************************/
  1008. //DS3231寫入單個字節函數DS3231_WriteByte(),有形參ADDR、DAT
  1009. //ADDR為欲寫入地址,DAT為欲寫入數據,無返回值
  1010. /****************************************************************/
  1011. void DS3231_WriteByte(u8 ADDR,u8 DAT)
  1012. {
  1013.   I2C_START();//產生I2C通信起始信號
  1014.   I2C_Write8Bit(0xD0);//寫入(器件地址+寫)指令
  1015.   I2C_Write8Bit(ADDR);//指定欲寫入DS3231芯片的地址
  1016.   I2C_Write8Bit(DAT);//寫入實際數據
  1017.   I2C_STOP();//產生I2C通信終止信號
  1018. }
  1019. /****************************************************************/
  1020. //BCD轉換為Byte函數BCD2HEX(),有形參val
  1021. //val為欲轉換的BCD碼,返回Byte
  1022. /****************************************************************/
  1023. u8 BCD2HEX(u8 val)    //BCD轉換為Byte
  1024. {
  1025.     u8 temp;
  1026.     temp=val&0x0f;
  1027.     val>>=4;
  1028.     val&=0x0f;
  1029.     val*=10;
  1030.     temp+=val;   
  1031.     return temp;
  1032. }
  1033. /****************************************************************/
  1034. //Byte碼轉換為BCD碼函數HEX2BCD(),有形參val
  1035. //val為欲轉換Byte碼,返回值為BCD碼
  1036. /****************************************************************/
  1037. u8 HEX2BCD(u8 val)    //Byte碼轉換為BCD碼
  1038. {
  1039.     u8 i,j,k;
  1040.     i=val/10;
  1041.     j=val;
  1042.     k=j+(i<<4);
  1043.     return k;
  1044. }
  1045. /****************************************************************/
  1046. //解鎖EEPROM函數unlock_EEPROM(),無形參,有返回值“0”或者“1”
  1047. //若返回值為“1”則解鎖失敗,若返回值為“0”則解鎖成功
  1048. /****************************************************************/
  1049. u8 unlock_EEPROM(void)
  1050. {
  1051.   //1.首先寫入MASS密匙以解鎖EEPROM
  1052.   FLASH_DUKR=0xAE;
  1053.   FLASH_DUKR=0x56;
  1054.   //2.判斷DUL位是否解鎖成功
  1055.   if(FLASH_IAPSR & 0x80)
  1056.     return 1;//解鎖失敗
  1057.   else
  1058.     return 0;//解鎖成功
  1059. }
  1060. /****************************************************************/
  1061. //OPT選項字節配置函數OPTconfig(),無形參,無返回值
  1062. /****************************************************************/
  1063. void OPTconfig(void)
  1064. {
  1065.   do//輸入MASS密匙用于解鎖DATA EEPROM的寫保護
  1066.   {
  1067.     FLASH_DUKR=0xAE;//硬件密匙1
  1068.     FLASH_DUKR=0x56;//硬件密匙2
  1069.   }
  1070.   while(!(FLASH_IAPSR & 0x08));//等待解鎖Flash完成
  1071.   FLASH_CR2 =0x80;//對選項字節進行寫操作被使能
  1072.   FLASH_NCR2=0x7F;//互補控制寄存器FLASH_NCR2中的NOPT位要為“0”
  1073.   *((u8*)0X4000)= OPT[0];//配置低于多少溫度風機停機條件
  1074.   *((u8*)0x4001)= OPT[1];//配置大于多少溫度風機中速啟動條件
  1075.   *((u8*)0x4002)= OPT[2];//配置小于多少溫度風機中速啟動條件
  1076.   *((u8*)0x4003)= OPT[3];//配置大于多少溫度風機高速啟動條件
  1077.   *((u8*)0x4004)= OPT[4];//配置小于哪個小時風機允許啟動條件
  1078.   *((u8*)0x4005)= OPT[5];//配置大于哪個小時風機允許啟動條件
  1079.   *((u8*)0x4006)= OPT[6];//配置小于哪個月份風機允許啟動條件
  1080.   *((u8*)0x4007)= OPT[7];//配置大于哪個月份風機允許啟動條件
  1081.   FLASH_IAPSR=0x40;//程序存儲區(FLASH)上鎖,數據存儲區(EEPROM)上鎖
  1082. }
  1083. /****************************************************************/
  1084. //讀取時鐘并顯示函數read_DS3231(),無形參,無返回值
  1085. /****************************************************************/
  1086. void read_DS3231(void)
  1087. {
  1088.   u8 stemp,shi1,ge1;
  1089.   GETDS3231_DAT=DS3231_ReadByte(0x00);//讀取指定地址的數據秒
  1090.   stemp=BCD2HEX(GETDS3231_DAT);
  1091.   shi1=stemp/10;//取轉換十位
  1092.   ge1=stemp%10;//取轉換個位
  1093.   LCD1602_DIS_CHAR(2,6,table3[shi1]);//在第2行第6列顯示讀回數據   
  1094.   LCD1602_DIS_CHAR(2,7,table3[ge1]);//在第2行第7列顯示讀回數據
  1095.   if(table3[shi1]=='0' & table3[ge1]=='0' | flag_time==0)
  1096.   {
  1097.     GETDS3231_DAT=DS3231_ReadByte(0x01);//讀取指定地址的數據分
  1098.     stemp=BCD2HEX(GETDS3231_DAT);
  1099.     shi1=stemp/10;//取轉換十位
  1100.     ge1=stemp%10;//取轉換個位
  1101.     LCD1602_DIS_CHAR(2,3,table3[shi1]);//在第2行第3列顯示讀回數據   
  1102.     LCD1602_DIS_CHAR(2,4,table3[ge1]);//在第2行第4列顯示讀回數據
  1103.   }
  1104.   if(table3[shi1]=='0' & table3[ge1]=='0' | flag_time==0)
  1105.   {
  1106.     GETDS3231_DAT=DS3231_ReadByte(0x02);//讀取指定地址的數據小時
  1107.     GETDS3231_DAT&=0x3f;
  1108.     stemp=BCD2HEX(GETDS3231_DAT);
  1109.     if(stemp>OPT1[5] & stemp<OPT1[4])
  1110.     {
  1111.       stemp1=1;
  1112.     }
  1113.     else
  1114.     {
  1115.       stemp1=0;
  1116.     }
  1117.     shi1=stemp/10;//取轉換十位
  1118.     ge1=stemp%10;//取轉換個位
  1119.     LCD1602_DIS_CHAR(2,0,table3[shi1]);//在第2行第0列顯示讀回數據   
  1120.     LCD1602_DIS_CHAR(2,1,table3[ge1]);//在第2行第1列顯示讀回數據
  1121.   }
  1122.   if(table3[shi1]=='0' & table3[ge1]=='0' | flag_time==0)
  1123.   {
  1124.     GETDS3231_DAT=DS3231_ReadByte(0x04);//讀取指定地址的數據日
  1125.     GETDS3231_DAT&=0x3f;
  1126.     stemp=BCD2HEX(GETDS3231_DAT);
  1127.     shi1=stemp/10;//取轉換十位
  1128.     ge1=stemp%10;//取轉換個位
  1129.     LCD1602_DIS_CHAR(1,6,table3[shi1]);//在第2行第0列顯示讀回數據   
  1130.     LCD1602_DIS_CHAR(1,7,table3[ge1]);//在第2行第1列顯示讀回數據
  1131.     GETDS3231_DAT=DS3231_ReadByte(0x05);//讀取指定地址的數據月
  1132.     GETDS3231_DAT&=0x3f;
  1133.     stemp=BCD2HEX(GETDS3231_DAT);
  1134.     if(stemp>OPT1[7] & stemp<OPT1[6])
  1135.     {
  1136.       stemp2=1;
  1137.     }
  1138.     else
  1139.     {
  1140.       stemp2=0;
  1141.     }
  1142.     shi1=stemp/10;//取轉換十位
  1143.     ge1=stemp%10;//取轉換個位
  1144.     LCD1602_DIS_CHAR(1,3,table3[shi1]);//在第2行第0列顯示讀回數據   
  1145.     LCD1602_DIS_CHAR(1,4,table3[ge1]);//在第2行第1列顯示讀回數據
  1146.     GETDS3231_DAT=DS3231_ReadByte(0x06);//讀取指定地址的數據年
  1147.     GETDS3231_DAT&=0x3f;
  1148.     stemp=BCD2HEX(GETDS3231_DAT);
  1149.     shi1=stemp/10;//取轉換十位
  1150.     ge1=stemp%10;//取轉換個位
  1151.     LCD1602_DIS_CHAR(1,0,table3[shi1]);//在第2行第0列顯示讀回數據   
  1152.     LCD1602_DIS_CHAR(1,1,table3[ge1]);//在第2行第1列顯示讀回數據
  1153.     GETDS3231_DAT=DS3231_ReadByte(0x03);//讀取指定地址的數據星期
  1154.     stemp=BCD2HEX(GETDS3231_DAT);        
  1155.     ge1=stemp%10;//取轉換個位
  1156.     u8 week[4];//星期顯示數組
  1157.     switch(ge1)
  1158.     {
  1159.       case 1:
  1160.         week[0]='M';
  1161.         week[1]='o';
  1162.         week[2]='n';
  1163.         week[3]=' ';
  1164.         break;
  1165.       case 2:
  1166.         week[0]='T';
  1167.         week[1]='u';
  1168.         week[2]='e';
  1169.         week[3]='s';
  1170.         break;
  1171.       case 3:
  1172.         week[0]='W';
  1173.         week[1]='e';
  1174.         week[2]='d';
  1175.         week[3]=' ';
  1176.         break;
  1177.       case 4:
  1178.         week[0]='T';
  1179.         week[1]='h';
  1180.         week[2]='u';
  1181.         week[3]='r';
  1182.         break;
  1183.       case 5:
  1184.         week[0]='F';
  1185.         week[1]='r';
  1186.         week[2]='i';
  1187.         week[3]=' ';
  1188.         break;
  1189.       case 6:
  1190.         week[0]='S';
  1191.         week[1]='a';
  1192.         week[2]='t';
  1193.         week[3]=' ';
  1194.         break;
  1195.       case 7:
  1196.         week[0]='S';
  1197.         week[1]='u';
  1198.         week[2]='n';
  1199.         week[3]=' ';
  1200.         break;
  1201.         default: break;
  1202.     }
  1203.     LCD1602_DIS_CHAR(1,10,week[0]);//在第2行第0列顯示讀回數據   
  1204.     LCD1602_DIS_CHAR(1,11,week[1]);//在第2行第1列顯示讀回數據
  1205.     LCD1602_DIS_CHAR(1,12,week[2]);//在第2行第1列顯示讀回數據
  1206.     LCD1602_DIS_CHAR(1,13,week[3]);//在第2行第1列顯示讀回數據
  1207.     flag_time=1;
  1208.   }
  1209. }
  1210. /****************************************************************/
  1211. //上電讀取溫度判斷工作位標志函數read_18b20_flag(),無形參,無返回值
  1212. /****************************************************************/
  1213. void read_18b20_flag(void)
  1214. {
  1215.   DS18B20_init();       //初始化DS18B20設備
  1216.   delay(15);
  1217.   DS18B20_get_Temperature();//溫度取值和處理
  1218.   delay(15);//等待采樣轉換完成
  1219.   if(Tem_u16>OPT1[3] & Tem_u16<OPT1[2])
  1220.   {
  1221.     cj=1;         
  1222.   }
  1223.   if(Tem_u16>OPT1[1] | Tem_u16==OPT1[1])
  1224.   {
  1225.     cj=2;
  1226.   }
  1227.   if(Tem_u16<OPT1[0] | Tem_u16==OPT1[0])
  1228.   {
  1229.     cj=1;
  1230.   }
  1231. }
  1232. /****************************************************************/
  1233. //讀取OPT參數函數OPT_Load(),無形參,無返回值
  1234. /****************************************************************/
  1235. void OPT_Load(void)
  1236. {
  1237.   //讀取STM8EEPROM數據
  1238.     OPT[0]=*((u8*)0X4000);//配置低于多少溫度風機停機條件
  1239.     OPT[1]=*((u8*)0X4001);//配置大于多少溫度風機高速啟動條件
  1240.     OPT[2]=*((u8*)0X4002);//配置小于多少溫度風機中速啟動條件
  1241.     OPT[3]=*((u8*)0X4003);//配置大于多少溫度風機中速啟動條件
  1242.     OPT[4]=*((u8*)0X4004);//配置小于哪個小時風機允許啟動條件
  1243.     OPT[5]=*((u8*)0X4005);//配置大于哪個小時風機允許啟動條件
  1244.     OPT[6]=*((u8*)0X4006);//配置小于哪個月份風機允許啟動條件
  1245.     OPT[7]=*((u8*)0X4007);//配置大于哪個月份風機允許啟動條件
  1246.     OPT1[0]=BCD2HEX(OPT[0]);//配置低于多少溫度風機停機條件
  1247.     OPT1[1]=BCD2HEX(OPT[1]);//配置大于多少溫度風機高速啟動條件
  1248.     OPT1[2]=BCD2HEX(OPT[2]);//配置小于多少溫度風機中速啟動條件
  1249.     OPT1[3]=BCD2HEX(OPT[3]);//配置大于多少溫度風機中速啟動條件
  1250.     OPT1[4]=BCD2HEX(OPT[4]);//配置小于哪個小時風機允許啟動條件
  1251.     OPT1[5]=BCD2HEX(OPT[5]);//配置大于哪個小時風機允許啟動條件
  1252.     OPT1[6]=BCD2HEX(OPT[6]);//配置小于哪個月份風機允許啟動條件
  1253.     OPT1[7]=BCD2HEX(OPT[7]);//配置大于哪個月份風機允許啟動條件
  1254. }
  1255. /****************************************************************/
  1256. //繼電器邏輯控制函數K_OC(),無形參,無返回值
  1257. /****************************************************************/
  1258. void K_OC(void)
  1259. {
  1260.   if(Tem_u16>OPT1[3] & Tem_u16<OPT1[2] & cj==1)         
  1261.   {            
  1262.     cj=2;            
  1263.     K3=0;            
  1264.     delay_ms(500);            
  1265.     K1=1;            
  1266.     delay_ms(500);            
  1267.     K2=1;            
  1268.     LCD1602_DIS_CHAR(1,15,'M');//在第1行第15列顯示風機中速運轉狀態
  1269.   }            
  1270.   if(Tem_u16>OPT1[1] | Tem_u16==OPT1[1] & cj==2)         
  1271.   {            
  1272.     cj=1;            
  1273.     K2=0;            
  1274.     delay_ms(500);               
  1275.     K1=1;            
  1276.     delay_ms(500);               
  1277.     K3=1;            
  1278.     LCD1602_DIS_CHAR(1,15,'H');//在第1行第15列顯示風機高速運轉狀態           
  1279.   }         
  1280.   if(Tem_u16<OPT1[0] | Tem_u16==OPT1[0])         
  1281.   {                     
  1282.     cj=1;            
  1283.     K3=0;            
  1284.     K2=0;            
  1285.     K1=0;            
  1286.     LCD1602_DIS_CHAR(1,15,'S');//在第1行第15列顯示風機停止運轉狀態           
  1287.   }
  1288. }
  1289. /****************************************************************/
  1290. //鍵盤檢測函數key_Testing(),無形參,無返回值
  1291. /****************************************************************/
  1292. void key_Testing(void)
  1293. {  
  1294.   
  1295.   ADC_GET();//啟動AD轉換獲取AD采樣數據AD_val
  1296.   AVG_AD_Vtemp();//求6次平均值(去掉2個最低去掉2個最高)
  1297.   delay(50);//延時
  1298.   GETvoltage=(u16)(AD_val*4.92);//4.8828125);//計算對應電壓(mV)
  1299.   AD_val=0;//清零ADC轉換數據
  1300.   qian=GETvoltage/1000;//取轉換電壓千位
  1301.   bai=GETvoltage%1000/100;//取轉換電壓百位
  1302.   if(qian==0)
  1303.   {         
  1304.     if(bai<1){KS=1;KEY_NO='1';}//S1按鍵電壓0判斷低于0.1
  1305.     else if(bai<5){KS=1;KEY_NO='2';}//S2按鍵電壓0.31判斷0.1至0.5之間
  1306.     else if(bai<8){KS=1;KEY_NO='3';}//S3按鍵電壓0.622判斷0.5至0.8之間
  1307.     else {KS=1;KEY_NO='A';}//S4按鍵電壓0.938判斷0.8至1.0之間
  1308.         
  1309.   }        
  1310.   else if(qian==1)        
  1311.   {         
  1312.     if(bai<1){KS=1;KEY_NO='A';}//S4按鍵電壓0.938判斷1.0至1.1之間         
  1313.     else if(bai<5){KS=1;KEY_NO='4';}//S5按鍵電壓1.243判斷1.1至1.5之間         
  1314.     else if(bai<7){KS=1;KEY_NO='5';}//S6按鍵電壓1.554判斷1.5至1.7之間         
  1315.     else {KS=1;KEY_NO='6';}//S7按鍵電壓1.863判斷1.7至2.0之間        
  1316.   }        
  1317.   else if(qian==2)        
  1318.   {         
  1319.     if(bai<3){KS=1;KEY_NO='B';}//S8按鍵電壓2.185判斷2.0至2.3之間         
  1320.     else if(bai<7){KS=1;KEY_NO='7';}//S9按鍵電壓2.495判斷2.3至2.7之間         
  1321.     else {KS=1;KEY_NO='8';}//S10按鍵電壓2.814判斷2.7至3.0之間        
  1322.   }        
  1323.   else if(qian==3)        
  1324.   {         
  1325.     if(bai<3){KS=1;KEY_NO='9';}//S11按鍵電壓3.133判斷3.0至3.2之間         
  1326.     else if(bai<6){KS=1;KEY_NO='C';}//S12按鍵電壓3.428判斷3.2至3.6之間         
  1327.     else {KS=1;KEY_NO='E';}//S13按鍵電壓3.734判斷3.6至4.0之間         
  1328.   }        
  1329.   else if(qian==4)        
  1330.   {         
  1331.     if(bai<2){KS=1;KEY_NO='0';}//S14按鍵電壓4.057判斷4.0至4.2之間         
  1332.     else if(bai<5){KS=1;KEY_NO='K';}//S15按鍵電壓4.375判斷4.2至4.5之間         
  1333.     else if(bai<9){KS=1;KEY_NO='D';}//S16按鍵電壓4.691判斷4.5至4.8之間         
  1334.     else KS=0;//無按鍵按下        
  1335.   }        
  1336.   delay(200);//延時等待
  1337.   if(KEY_NO==KEY_NO1)
  1338.   {
  1339.     KS=0;   
  1340.   }
  1341.   if(KS==1)//判斷是否有按鍵按下
  1342.   {
  1343.     if(KEY_NO=='A')//控制屏幕背景燈
  1344.     {
  1345.       K4=!K4;
  1346.     }
  1347.     if(flag_DIS==1)//只有在正常工作界面是這些案件操作功能有效
  1348.     {
  1349.       if(KEY_NO=='B')//時間設置界面
  1350.       {
  1351.         LCD1602_DIS(3);
  1352.       }
  1353.       if(KEY_NO=='C')//溫度控制參數設置界面
  1354.       {
  1355.         LCD1602_DIS(2);
  1356.       }
  1357.       if(KEY_NO=='D')//風機允許運行時間參數設置界面
  1358.       {
  1359.         LCD1602_DIS(4);
  1360.       }   
  1361.     }
  1362.     if(flag_DIS==3)//時間設置參數輸入
  1363.     {      
  1364.       switch(flag_save)
  1365.       {      
  1366.       case 0://年數據輸入
  1367.         if(KEY_NO=='K')
  1368.         {            
  1369.           LCD1602_DIS_CHAR_S(2,1,1);//在設定地址顯示光標閃爍            
  1370.           flag_save++;
  1371.           break;         
  1372.         }         
  1373.         mt=KEY_NO;         
  1374.         mt=mt<<4;         
  1375.         if(KEY_NO!='B')         
  1376.         {            
  1377.           LCD1602_DIS_CHAR(2,0,KEY_NO);            
  1378.           LCD1602_DIS_CHAR_S(2,0,1);//在設定地址顯示光標閃爍         
  1379.         }         
  1380.         break;
  1381.       case 1:         
  1382.         if(KEY_NO=='K')         
  1383.         {            
  1384.           year=mt+lt;            
  1385.           LCD1602_DIS_CHAR_S(2,2,1);//在設定地址顯示光標閃爍            
  1386.           flag_save++;            
  1387.           break;         
  1388.         }         
  1389.         lt=KEY_NO;
  1390.         lt&=0x0f;         
  1391.         if(KEY_NO!='K')         
  1392.         {
  1393.           LCD1602_DIS_CHAR(2,1,KEY_NO);            
  1394.           LCD1602_DIS_CHAR_S(2,1,1);//在設定地址顯示光標閃爍         
  1395.         }
  1396.         break;      
  1397.       case 2://月數據輸入
  1398.         if(KEY_NO=='K')
  1399.         {            
  1400.           LCD1602_DIS_CHAR_S(2,3,1);//在設定地址顯示光標閃爍            
  1401.           flag_save++;
  1402.           break;         
  1403.         }         
  1404.         mt=KEY_NO;         
  1405.         mt=mt<<4;         
  1406.         if(KEY_NO!='K')         
  1407.         {            
  1408.           LCD1602_DIS_CHAR(2,2,KEY_NO);            
  1409.           LCD1602_DIS_CHAR_S(2,2,1);//在設定地址顯示光標閃爍         
  1410.         }         
  1411.         break;
  1412.       case 3:         
  1413.         if(KEY_NO=='K')         
  1414.         {            
  1415.           month=mt+lt;            
  1416.           LCD1602_DIS_CHAR_S(2,4,1);//在設定地址顯示光標閃爍            
  1417.           flag_save++;            
  1418.           break;         
  1419.         }         
  1420.         lt=KEY_NO;         
  1421.         lt&=0x0f;         
  1422.         if(KEY_NO!='K')         
  1423.         {            
  1424.           LCD1602_DIS_CHAR(2,3,KEY_NO);            
  1425.           LCD1602_DIS_CHAR_S(2,3,1);//在設定地址顯示光標閃爍         
  1426.         }
  1427.         break;        
  1428.       case 4://日數據輸入
  1429.         if(KEY_NO=='K')
  1430.         {            
  1431.           LCD1602_DIS_CHAR_S(2,5,1);//在設定地址顯示光標閃爍            
  1432.           flag_save++;
  1433.           break;         
  1434.         }         
  1435.         mt=KEY_NO;         
  1436.         mt=mt<<4;         
  1437.         if(KEY_NO!='K')         
  1438.         {            
  1439.           LCD1602_DIS_CHAR(2,4,KEY_NO);            
  1440.           LCD1602_DIS_CHAR_S(2,4,1);//在設定地址顯示光標閃爍         
  1441.         }         
  1442.         break;
  1443.       case 5:         
  1444.         if(KEY_NO=='K')         
  1445.         {            
  1446.           day=mt+lt;            
  1447.           LCD1602_DIS_CHAR_S(2,7,1);//在設定地址顯示光標閃爍            
  1448.           flag_save++;            
  1449.           break;         
  1450.         }         
  1451.         lt=KEY_NO;         
  1452.         lt&=0x0f;         
  1453.         if(KEY_NO!='K')         
  1454.         {            
  1455.           LCD1602_DIS_CHAR(2,5,KEY_NO);            
  1456.           LCD1602_DIS_CHAR_S(2,5,1);//在設定地址顯示光標閃爍         
  1457.         }
  1458.         break;      
  1459.       case 6://星期數據輸入
  1460.         if(KEY_NO=='K')
  1461.         {      
  1462.           week=mt;  
  1463.           LCD1602_DIS_CHAR_S(2,9,1);//在設定地址顯示光標閃爍            
  1464.           flag_save++;
  1465.           break;         
  1466.         }         
  1467.         mt=KEY_NO;         
  1468.         mt&=0x0f;;         
  1469.         if(KEY_NO!='K')         
  1470.         {            
  1471.           LCD1602_DIS_CHAR(2,7,KEY_NO);            
  1472.           LCD1602_DIS_CHAR_S(2,7,1);//在設定地址顯示光標閃爍         
  1473.         }         
  1474.         break;              
  1475.       case 7://小時數據輸入
  1476.         if(KEY_NO=='K')
  1477.         {            
  1478.           LCD1602_DIS_CHAR_S(2,10,1);//在設定地址顯示光標閃爍            
  1479.           flag_save++;
  1480.           break;         
  1481.         }         
  1482.         mt=KEY_NO;         
  1483.         mt=mt<<4;         
  1484.         if(KEY_NO!='K')         
  1485.         {            
  1486.           LCD1602_DIS_CHAR(2,9,KEY_NO);            
  1487.           LCD1602_DIS_CHAR_S(2,9,1);//在設定地址顯示光標閃爍         
  1488.         }         
  1489.         break;
  1490.       case 8:         
  1491.         if(KEY_NO=='K')         
  1492.         {            
  1493.           hour=mt+lt;            
  1494.           LCD1602_DIS_CHAR_S(2,11,1);//在設定地址顯示光標閃爍            
  1495.           flag_save++;            
  1496.           break;         
  1497.         }         
  1498.         lt=KEY_NO;         
  1499.         lt&=0x0f;         
  1500.         if(KEY_NO!='K')         
  1501.         {            
  1502.           LCD1602_DIS_CHAR(2,10,KEY_NO);            
  1503.           LCD1602_DIS_CHAR_S(2,10,1);//在設定地址顯示光標閃爍         
  1504.         }
  1505.         break;         
  1506.       case 9://分數據輸入
  1507.         if(KEY_NO=='K')
  1508.         {            
  1509.           LCD1602_DIS_CHAR_S(2,12,1);//在設定地址顯示光標閃爍            
  1510.           flag_save++;
  1511.           break;         
  1512.         }         
  1513.         mt=KEY_NO;         
  1514.         mt=mt<<4;         
  1515.         if(KEY_NO!='K')         
  1516.         {            
  1517.           LCD1602_DIS_CHAR(2,11,KEY_NO);            
  1518.           LCD1602_DIS_CHAR_S(2,11,1);//在設定地址顯示光標閃爍         
  1519.         }         
  1520.         break;
  1521.       case 10:         
  1522.         if(KEY_NO=='K')         
  1523.         {            
  1524.           branch=mt+lt;            
  1525.           LCD1602_DIS_CHAR_S(2,13,1);//在設定地址顯示光標閃爍            
  1526.           flag_save++;            
  1527.           break;         
  1528.         }
  1529.         lt=KEY_NO;         
  1530.         lt&=0x0f;         
  1531.         if(KEY_NO!='K')         
  1532.         {            
  1533.           LCD1602_DIS_CHAR(2,12,KEY_NO);            
  1534.           LCD1602_DIS_CHAR_S(2,12,1);//在設定地址顯示光標閃爍         
  1535.         }
  1536.         break;         
  1537.       case 11://秒數據輸入
  1538.         if(KEY_NO=='K')
  1539.         {            
  1540.           LCD1602_DIS_CHAR_S(2,14,1);//在設定地址顯示光標閃爍            
  1541.           flag_save++;
  1542.           break;         
  1543.         }         
  1544.         mt=KEY_NO;         
  1545.         mt=mt<<4;         
  1546.         if(KEY_NO!='K')         
  1547.         {            
  1548.           LCD1602_DIS_CHAR(2,13,KEY_NO);            
  1549.           LCD1602_DIS_CHAR_S(2,13,1);//在設定地址顯示光標閃爍         
  1550.         }         
  1551.         break;
  1552.       case 12:         
  1553.         if(KEY_NO=='K')         
  1554.         {            
  1555.           second=mt+lt;            
  1556.           LCD1602_DIS_CHAR_S(2,15,1);//在設定地址顯示光標閃爍
  1557.           DS3231_WriteByte(0x00,second);//秒
  1558.           DS3231_WriteByte(0x01,branch);//分
  1559.           DS3231_WriteByte(0x02,hour);//小時
  1560.    
  1561.           DS3231_WriteByte(0x03,week);//星期
  1562.          
  1563.           DS3231_WriteByte(0x04,day);//天
  1564.           DS3231_WriteByte(0x05,month);//月
  1565.           DS3231_WriteByte(0x06,year);//年
  1566.           KEY_NO='E';//模擬取消按鍵,進入正常工作界面            
  1567.           break;         
  1568.         }
  1569.         lt=KEY_NO;         
  1570.         lt&=0x0f;         
  1571.         if(KEY_NO!='K')
  1572.         {            
  1573.           LCD1602_DIS_CHAR(2,14,KEY_NO);            
  1574.           LCD1602_DIS_CHAR_S(2,14,1);//在設定地址顯示光標閃爍         
  1575.         }
  1576.         break;
  1577.     default:
  1578.       break;
  1579.       }
  1580.       if(KEY_NO=='E')
  1581.       {
  1582.         flag_time=0;//第一次讀全日期時間標志位
  1583.         flag_save=0;//參數儲存標志位
  1584.         LCD1602_DIS(1);//正常運行界面
  1585.       }
  1586.     }
  1587.     if(flag_DIS==2)//溫度參數設置輸入
  1588.     {      
  1589.       switch(flag_save)
  1590.       {      
  1591.       case 0://低于多少溫度,風機停機
  1592.         if(KEY_NO=='K')
  1593.         {            
  1594.           LCD1602_DIS_CHAR_S(1,5,1);//在設定地址顯示光標閃爍            
  1595.           flag_save++;
  1596.           break;         
  1597.         }
  1598.         mt=KEY_NO;
  1599.         mt=mt<<4;         
  1600.         if(KEY_NO!='C')
  1601.         {            
  1602.           LCD1602_DIS_CHAR(1,4,KEY_NO);            
  1603.           LCD1602_DIS_CHAR_S(1,4,1);//在設定地址顯示光標閃爍
  1604.         }         
  1605.         break;
  1606.       case 1:         
  1607.         if(KEY_NO=='K')
  1608.         {            
  1609.           OPT[0]=mt+lt;            
  1610.           LCD1602_DIS_CHAR_S(1,12,1);//在設定地址顯示光標閃爍            
  1611.           flag_save++;            
  1612.           break;         
  1613.         }         
  1614.         lt=KEY_NO;         
  1615.         lt&=0x0f;         
  1616.         if(KEY_NO!='K')         
  1617.         {            
  1618.           LCD1602_DIS_CHAR(1,5,KEY_NO);            
  1619.           LCD1602_DIS_CHAR_S(1,5,1);//在設定地址顯示光標閃爍         
  1620.         }
  1621.         break;
  1622.       case 2://大于多少溫度風機高速運行
  1623.         if(KEY_NO=='K')
  1624.         {            
  1625.           LCD1602_DIS_CHAR_S(1,13,1);//在設定地址顯示光標閃爍            
  1626.           flag_save++;
  1627.           break;         
  1628.         }         
  1629.         mt=KEY_NO;         
  1630.         mt=mt<<4;         
  1631.         if(KEY_NO!='K')         
  1632.         {            
  1633.           LCD1602_DIS_CHAR(1,12,KEY_NO);            
  1634.           LCD1602_DIS_CHAR_S(1,12,1);//在設定地址顯示光標閃爍         
  1635.         }         
  1636.         break;
  1637.       case 3:         
  1638.         if(KEY_NO=='K')         
  1639.         {            
  1640.           OPT[1]=mt+lt;            
  1641.           LCD1602_DIS_CHAR_S(2,2,1);//在設定地址顯示光標閃爍            
  1642.           flag_save++;            
  1643.           break;         
  1644.         }         
  1645.         lt=KEY_NO;         
  1646.         lt&=0x0f;         
  1647.         if(KEY_NO!='K')         
  1648.         {            
  1649.           LCD1602_DIS_CHAR(1,13,KEY_NO);            
  1650.           LCD1602_DIS_CHAR_S(1,13,1);//在設定地址顯示光標閃爍         
  1651.         }
  1652.         break;        
  1653.       case 4://小于多少溫度風機中速運行
  1654.         if(KEY_NO=='K')
  1655.         {            
  1656.           LCD1602_DIS_CHAR_S(2,3,1);//在設定地址顯示光標閃爍            
  1657.           flag_save++;
  1658.           break;         
  1659.         }         
  1660.         mt=KEY_NO;         
  1661.         mt=mt<<4;         
  1662.         if(KEY_NO!='K')         
  1663.         {            
  1664.           LCD1602_DIS_CHAR(2,2,KEY_NO);            
  1665.           LCD1602_DIS_CHAR_S(2,2,1);//在設定地址顯示光標閃爍         
  1666.         }         
  1667.         break;
  1668.       case 5:         
  1669.         if(KEY_NO=='K')         
  1670.         {            
  1671.           OPT[2]=mt+lt;            
  1672.           LCD1602_DIS_CHAR_S(2,7,1);//在設定地址顯示光標閃爍            
  1673.           flag_save++;            
  1674.           break;         
  1675.         }         
  1676.         lt=KEY_NO;         
  1677.         lt&=0x0f;         
  1678.         if(KEY_NO!='K')         
  1679.         {            
  1680.           LCD1602_DIS_CHAR(2,3,KEY_NO);            
  1681.           LCD1602_DIS_CHAR_S(2,3,1);//在設定地址顯示光標閃爍         
  1682.         }
  1683.         break;
  1684.       case 6://大于多少溫度風機中速運行
  1685.         if(KEY_NO=='K')
  1686.         {            
  1687.           LCD1602_DIS_CHAR_S(2,8,1);//在設定地址顯示光標閃爍            
  1688.           flag_save++;
  1689.           break;         
  1690.         }         
  1691.         mt=KEY_NO;         
  1692.         mt=mt<<4;         
  1693.         if(KEY_NO!='K')         
  1694.         {            
  1695.           LCD1602_DIS_CHAR(2,7,KEY_NO);            
  1696.           LCD1602_DIS_CHAR_S(2,7,1);//在設定地址顯示光標閃爍         
  1697.         }
  1698.         break;
  1699. ……………………

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

附件里包含源代碼(IAR)和控制器的詳細說明書



全部資料51hei下載地址:
散熱風機控制.zip (5.76 MB, 下載次數: 49)


評分

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

查看全部評分

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

使用道具 舉報

沙發
ID:386877 發表于 2018-8-16 14:11 | 只看該作者
本帖最后由 13931582522 于 2018-8-16 14:30 編輯

源碼,行行都有注釋,采用的寄存器編程
回復

使用道具 舉報

板凳
ID:387394 發表于 2018-8-17 20:04 | 只看該作者
THANKS
回復

使用道具 舉報

地板
ID:67041 發表于 2019-12-6 11:23 | 只看該作者
不錯,感謝分享。本人雖然年紀大點,還是想學習一下STM8
回復

使用道具 舉報

5#
ID:71535 發表于 2020-1-9 22:06 | 只看該作者

初學的好教材,謝謝分享。!
回復

使用道具 舉報

6#
ID:23844 發表于 2020-1-12 08:46 | 只看該作者
這個全帶注釋的不錯,得下載一個學習學習
回復

使用道具 舉報

7#
ID:71535 發表于 2020-9-4 19:32 | 只看該作者
帶注釋的寄存器操作易于初學者學習理解,值得初學者學習學習、
回復

使用道具 舉報

8#
ID:98396 發表于 2020-9-7 09:14 | 只看該作者
/****************************************************************/
//設備初始化時序產生函數DS18B20_reset(),無形參和返回值
/****************************************************************/
void DS18B20_reset(void)
{
  u8 x;//變量x用于取回總線電平狀態
  DS18B20_DQ_DDR(1);//改變DQ引腳方向性為輸出方式
  DS18B20_DQ=1;//控制器首先應為高電平狀態
  delay_u(910);//延時大約800us
  DS18B20_DQ=0;//控制器拉低總線發送復位脈沖
  delay_u(910);//拉低時間大約800us
  DS18B20_DQ=1;//控制器釋放總線
  delay_u(30);//DS18B20等待大約30us
  DS18B20_DQ_DDR(0);//改變DQ引腳方向性為輸入方式
  delay_u(30);//等待DS18B20應答脈沖大約30us

  x=PA_IDR_IDR3;//取回總線電平狀態                        <------ 這裡有問題!
  while(x);//等待應答脈沖出現低電平                           <------


  delay_u(900);//控制器等待至少480us
}

應該改為 :
  do {
  x=PC_IDR_IDR3;//取回總線電平狀態
  } while(x);//等待應答脈沖出現低電平  


回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕 在线观看 | 亚洲一区成人 | 青青99| 欧美一区二区三区小说 | 天天爱天天操 | 久久www免费视频 | 久久99精品久久久97夜夜嗨 | 亚洲精品在线视频 | 99小视频| 久久亚洲综合 | 久久精品欧美一区二区三区麻豆 | 国产精品国产成人国产三级 | 国产高清毛片 | 久久美女网 | 国产99小视频 | 2019天天干夜夜操 | 日本三级电影在线看 | 日韩免费一区 | 久草.com| 欧美日韩国产一区二区三区 | 日本在线观看视频 | 日本午夜免费福利视频 | 中文字幕av一区二区三区 | 一区二区免费在线观看 | 国产精品日韩在线观看 | 国产亚洲高清视频 | 亚洲性视频 | 亚洲精品视频在线播放 | 羞羞视频在线观看网站 | av在线播放网址 | 欧美日韩中文字幕在线 | 久草电影网 | 成人夜晚看av| 中文字幕第90页 | 成人在线免费电影 | 日本亚洲精品成人欧美一区 | 日本欧美视频 | 成人精品区 | 中文字幕在线观看一区二区 | 91视频入口| 在线一级片 |