此電阻爐溫度控制器主要是以單片機STC89C52為核心,通過S型熱電偶采集熱端溫度并進行冷端溫度補償?shù)玫綄嶋H溫度T,然后經(jīng)放大電路和ADC0832模數(shù)轉換,并進行線性化處理,之后經(jīng)單片機STC89C52進行PID控制,并加入PID參數(shù)的調(diào)整,最后通過液晶顯示器LCD1602實現(xiàn)溫度值和PID輸出值及參數(shù)值的顯示。它用最簡單的硬件單元和軟件編程實現(xiàn)了溫度采集、溫度PID控制、溫度顯示、上下限報警、PID參數(shù)顯示、PID參數(shù)修改等功能。
目 錄
摘 要
目 錄
第一章 前言
1.1熱電偶
1.1.1熱電偶及其工作原理
1.1.2 熱電偶的冷端溫度補償
1.1.3 熱電偶的分類
1.2 PID
1.2.1 PID簡介
1.2.2 PID算法介紹
1.2.3 位置式PID算法
第二章 電阻爐溫度控制器總體設計
2.1功能需求
2.2 硬件設計
2.3 軟件設計
第三章 電阻爐溫度控制器硬件設計
3.1 S型熱電偶
3.1.1 S型熱電偶及其分度表
3.1.2 S型熱電偶線性化處理
3.2 單片機STC89C52及其外圍接口電路
3.2.1 單片機STC89C52
3.2.2 單片機STC89C52外圍接口電路
3.3 ADC0832
3.4 LCD1602顯示器
第四章 軟件設計
4.1電阻爐溫度控制器主程序
4.2 ADC0832數(shù)據(jù)采集子程序
4.3熱電偶線性化標度變換程序
4.4 PID控制程序
4.5 PID參數(shù)修改子程序
4.6 LCD顯示子程序
第五章 總結
參考文獻
附錄 A
第一章 前言在使用電阻爐溫度控制器之前,我們有必要了解其制作工藝和一些關鍵器件的概況,以便我們能夠自己處理它所出現(xiàn)的一些小問題或者為愛好者學習提供幫助。因此這一章我們就關于電阻爐溫度控制器運用的基本知識作一介紹。 1.1熱電偶1.1.1熱電偶及其工作原理熱電偶是溫度測量儀表中得關鍵性元件,因其具有結構簡單,性質穩(wěn)定,測溫范圍寬,測量精度高、動態(tài)性能好、使用方便以及容易維護等優(yōu)點,現(xiàn)已經(jīng)被用于各種行業(yè)。特別是由于其性質穩(wěn)定,在高溫環(huán)境的測量中,熱電偶測溫占有相當重要的地位。 熱電偶的工作原理主要是利用了熱電效應,所謂熱電效應,就是指兩種不同成份的導體(稱為熱電偶絲材或熱電極)兩端接合成回路,當兩個接合點的溫度不同時,在回路中就會產(chǎn)生電動勢。直接測量介質的一端稱為工作端,另一端稱為冷端。 1.1.2 熱電偶的冷端溫度補償由熱電偶的測溫原理可知,熱電勢的大小不僅與熱端溫度有關,而且與冷端溫度有關,只有當冷端溫度恒定時,才能通過熱電勢的大小去判斷熱端溫度的高低。 冷端溫度補償方法有冰點法,恒溫遷移法,計算修正法,電橋補償法,軟件補償法。我們這里采用計算修正法: 計算修正法基于中間溫度定律,其計算公式如式1.1 EAB(T,0)=EAB(T,T0)+EAB(T0,0) (1.1) 1.1.3 熱電偶的分類按照工業(yè)標準化的要求,熱電偶可以分為標準化熱電偶和非標準化熱電偶兩種。 標準化熱電偶指工藝成熟、能批量生產(chǎn)、性能穩(wěn)定、應用廣泛,且具有統(tǒng)一分度表并已列入國際和國家標準文件的熱電偶。非標準化熱電偶是指研究還不夠成熟,雖然已有產(chǎn)品,也能夠使用但是沒有統(tǒng)一的分度表,需要個別標定,給我們的使用帶來不便,因此我們?nèi)粘2蛔鍪褂煤脱芯俊?/p> 標準化熱電偶包括鉑銠10-鉑熱電偶(S型)、鉑銠30-鉑銠6熱電偶(B型)、鎳鎘-鎳硅熱電偶(K型)、鎳鎘-銅鎳熱電偶(E型)、銅-銅鎳熱電偶(T型)。我們著重介紹K型和S型熱電偶: S型熱電偶為貴重金屬熱電偶,其正極導體的化學成分為鉑銠合金,其中,含銠10%,含鉑90%。負極為純鉑。 S型熱電偶具有準確度高、測溫區(qū)寬、使用壽命長和穩(wěn)定性好等優(yōu)點。特別是其在高溫下抗氧化性能好,因此我們的產(chǎn)品電阻爐溫度控制器選用熱電偶作為溫度傳感器。 K型熱電偶為目前用量最大的廉價金屬熱電偶。其正極的化學成分為:Ni:Cr=90:10;負極的化學成分為:Ni:Si=97:3,測量溫度為-200℃~1300℃。 1.2 PID1.2.1 PID簡介PID控制是工程應用中最廣泛的控制規(guī)律,它的主要特點是其結構簡單、穩(wěn)定性好、工作可靠、調(diào)整方便。其各種參數(shù)的特征如下: 比例調(diào)節(jié)的作用是按比例反映系統(tǒng)的偏差,系統(tǒng)一旦出現(xiàn)了偏差,比例調(diào)節(jié)立即產(chǎn)生調(diào)節(jié)作用以減小偏差。比例作用大,可以加快調(diào)節(jié),減小誤差,但是過大的比例作用會使系統(tǒng)的穩(wěn)定性下降,甚至造成系統(tǒng)不穩(wěn)定。積分調(diào)節(jié)的作用是使系統(tǒng)消除穩(wěn)態(tài)誤差,因為一旦有誤差,積分調(diào)節(jié)就起作用,直至無誤差,積分調(diào)節(jié)的輸出維持常量。微分調(diào)節(jié)的作用是反映系統(tǒng)偏差信號的變化率,具有預見性,能預見偏差變化的趨勢,因此能產(chǎn)生超前的控制作用,使偏差還沒有形成即被微分調(diào)節(jié)作用消除,因此微分作用可以改善系統(tǒng)的動態(tài)性能。 1.2.2 PID算法介紹PID算法有位置式和增量式輸出兩種。增量式PID算法輸出得到的結果是增量,也就是說,在上一次的控制量的基礎上需要增加(負值意味著減少)的控制量。例如,在晶閘管電動機調(diào)速系統(tǒng)中,控制量的增量意味著晶閘管的觸發(fā)相位在原有的基礎上需要提前或滯后的量。位置式算法輸出則表現(xiàn)為當前的觸發(fā)相位應該在什么位置。又如在溫度控制系統(tǒng)中,增量式算法表現(xiàn)為在上次通電時間比例的基礎上,還需要增加或減少的通電時間比例;位置式算法輸出則直接指明本周期內(nèi)要通電多長時間 1.2.3 位置式PID算法位置式PID算法可以直接指出需要通電多長時間,因此其受到廣泛應用。其計算公式如式1.2下: (1.2)
式中 ,為基本偏差,表示當前測量值與設定目標值之間的差值,結果可以是正或負。當設定目標作為被減數(shù)時,正數(shù)表示還沒有達到設定值。負數(shù)表示已經(jīng)超過了設定值。累計偏差 ,它是每次偏差值的代數(shù)和。 , 和 是PID算法的3個控制參數(shù),分別稱為比例常數(shù)、積分常數(shù)和微分常數(shù),對不同的控制對象選擇不同的數(shù)值,需要經(jīng)過現(xiàn)場整定才能獲得較好的效果。 第二章 電阻爐溫度控制器總體設計此電阻爐溫度控制器主要是以單片機STC89C52為核心,通過熱電偶采集熱端溫度并進行冷端溫度補償?shù)玫綄嶋H溫度T,然后經(jīng)放大電路和ADC0832模數(shù)轉換,并進行線性化處理,之后經(jīng)單片機STC89C52進行PID控制,并加入PID參數(shù)的調(diào)整,最后通過液晶顯示器LCD1602實現(xiàn)溫度值和PID輸出值及參數(shù)值的顯示。它用最簡單的硬件單元和軟件編程實現(xiàn)了溫度采集、溫度PID控制、溫度顯示、上下限報警、PID參數(shù)顯示、PID參數(shù)修改等功能。 2.1功能需求電阻爐溫度控制器實際上是以單片機為核心,根據(jù)設定溫度值與采集溫度值進行比較求出偏差然后PID運算對電阻爐溫度進行控制。 此控制系統(tǒng)可實現(xiàn)以下功能: 溫度采集: 溫度控制: 溫度顯示: 上下限報警顯示: 參數(shù)顯示: PID控制參數(shù)設定修改: 其單回路控制系統(tǒng)圖2.1如下所示:

圖2.1 單片機單回路控制系統(tǒng) 2.2 硬件設計電阻爐溫度控制器主要有單片機AT89C52、A/D轉換器、按鍵、LCD顯示、加熱爐、傳感器、SSR輸出控制組成的控制系統(tǒng)。其組成框圖如圖2.2所示:

圖2.2 硬件組成框圖 2.3 軟件設計該電阻爐溫度控制器采用模塊 化的結構設計。其主程序流程圖如 圖2.3所示: 其軟件部分的的設計由ADC0832 采樣子程序、中斷子程序、LCD初 始化子程序、PID控制子程序、PID 參數(shù)按鍵修改子程序。ADC0832采 集溫度信號,信號經(jīng)A/D轉換后送 至單片機STC89C52進行PID處理, 用戶可以根據(jù)自身條件對PID參數(shù) 進行調(diào)整,之后LCD顯示器顯示溫 度值和PID處理值,從而控制電阻 爐溫度。
圖2.3 主程序流程圖 第三章 電阻爐溫度控制器硬件設計3.1 S型熱電偶3.1.1 S型熱電偶及其分度表S型熱電偶首先是標準化熱電偶,偶絲直徑規(guī)定為0.5mm,允許偏差-0.015mm,其正極(SP)的名義化學成分為鉑銠合金,其中含銠為10%,含鉑為90%,負極(SN)為純鉑,故俗稱單鉑銠熱電偶。該熱電偶長期最高使用溫度為1300℃,短期最高使用溫度為1600℃。而且S型熱電偶在正常長期使用溫度為800~1300℃左右時測量的精度最高,而在800℃以內(nèi)的測溫準確度不高,而長期使用溫度在1300℃以上就很容易損壞熱電偶。因此我們在對其分度表的計算時溫度設定為0~1300℃,因為電阻爐正符合其要求,并為長期使用電器。 S型熱電偶分度表如下表3.1所示:
表3.1 S型熱電偶分度表 
3.1.2 S型熱電偶線性化處理此電阻爐溫度傳感器中S型熱電偶溫度傳感器采集0-1300℃的溫度進行顯示控制,根據(jù)S型熱電偶分度表列出其對應的mv電壓,由于所用單片機STC89C52能夠控制的電壓信號為0-5V,以及編程轉換值,因此根據(jù)以上進行標度變換處理得表3.2所示:
表3.2 標度變換表 3.2 單片機STC89C52及其外圍接口電路3.2.1 單片機STC89C52STC89C52是一種低功耗、高性能CMOS8位微控制器,具有 8K 在系統(tǒng)可編程Flash 存儲器。在單芯片上,擁有靈巧的8 位CPU 和在系統(tǒng)可編程Flash,使得STC89C52為眾多嵌入式控制應用系統(tǒng)提供高靈活、超有效的解決方案 STC89C52的引腳分布如圖3.1所示,各部分引腳功能如下 1. P0.0~P0.7引腳:作為I/O引腳使用時,P0口是漏極開路雙向口,向口鎖存器寫入1時,I/O引腳將懸空,是高阻輸入引腳;在讀寫外部存儲器時P0口作低8位數(shù)據(jù)/地址總線。 2. P1.0—P1.7引腳:內(nèi)部帶有弱上拉的準雙向I/O口,作輸入引腳使用前,先向P1口鎖存器寫入1,使P1口引腳上拉至高電平;另外,P1.0與P1.1還有第二功能:T2(P1.0)—定時器T2的計數(shù)輸入端或定時器T2的時鐘輸出端,T2EX(P1.1)—定時器T2的外部觸發(fā)輸入端。

圖3.1 STC89C52引腳分布圖 3. P2.0—P2.7引腳: 內(nèi)部帶有弱上拉的準雙向I/O口,作輸入引腳使用前,先向P2口鎖存器寫入1,使P2口引腳上拉至高電平;在讀/寫外部存儲器時,P2口輸出高8位地址信號A15—A8。 4. P3.0—P3.7引腳:內(nèi)部帶有弱上拉的準雙向I/O口,作輸入引腳使用前,先向P3口鎖存器寫入1,使P3口引腳上拉至高電平;另外,P3口還有第二功能:RXD(P3.0)——串行數(shù)據(jù)接收(輸入)端; TXD(P3.1)——串行數(shù)據(jù)發(fā)送(輸出)端; (P3.2)——外中斷0輸入端;
(P3.3)——外中斷1輸入端;
T0(P3.4)——定時/計數(shù)T0的外部輸入端; T1(P3.5)——定時/計數(shù)T1的外部輸入端; (P3.6)——外部數(shù)據(jù)存儲器寫選通信號,低電平有效;
(P3.7)——外部數(shù)據(jù)存儲器讀選通信號,低電平有效;
5. 引腳:外部程序存儲器選擇信號,低電平有效;在復位期間CPU檢測并鎖存 引腳的電平狀態(tài),當讀引腳為高電平時,從片內(nèi)程序存儲器取指令,只有當程序計數(shù)器PC超出片內(nèi)程序存儲器地址編碼范圍時,才轉到外部程序存儲器中取指令;當該引腳位低電平時,一律從外部程序存儲器中取指令。 6. :外部程序存儲器讀選通信號,低電平有效。 7.ALE:低8位地址鎖存信號,在訪問外部程序存儲器時,ALE下降沿鎖存從P0口輸出的低8位地址信息A7—A0,以便隨后將P0口作為數(shù)據(jù)總線使用; 在正常情況下,ALE輸出信號為1/6振蕩頻率,并可用作外部時鐘或定時信號。 8. XTAL1:片內(nèi)晶振電路反向放大器輸入端,接CPU內(nèi)部時鐘電路; XTAL2:片內(nèi)晶振電路反向放大器輸出端; 9. RST:復位信號輸入端,高電平有效; 10. VCC:電源引腳,VSS:電源地。 STC89C52系列單片機屬于MCS—51型系列單片機,它們的存儲器在組織結構上有4個物理上相互獨立的空間:片內(nèi)程序存儲器和片外程序存儲器,內(nèi)部數(shù)據(jù)存儲器和片外數(shù)據(jù)存儲器。其中片外數(shù)據(jù)存儲區(qū)共64KB,相應的地址空間為0000F—FFFFH;片內(nèi)數(shù)據(jù)存儲區(qū)共256B,其中80H—FFH為SFR(特殊功能寄存器區(qū)),20H—2FH為位尋址區(qū),00H—1FH為R0—R7工作寄存器區(qū), 30H—7FH為用戶存儲數(shù)據(jù)用的存儲區(qū),共80個字節(jié);片內(nèi)程序存儲區(qū)有4KB,通過 =1進行選通;片外程序存儲區(qū)有64KB是通過 =0進行選通。 3.2.2 單片機STC89C52外圍接口電路該電阻爐溫度控制器中使用了STC89C52單片機,以及ADC0832A/D轉換器、晶振電路、復位電路、按鍵、LCD1602液晶顯示器。其連接原理圖如圖3.2: 3.3 ADC0832該電阻爐溫度控制器所用的A/D轉換器是ADC0832, ADC0832 為8位分辨率A/D轉換芯片,其最高分辨可達256級,可以適應一般的模擬量轉換要求。其內(nèi)部電源輸入與參考電壓的復用,使得芯片的模擬電壓輸入在0~5V之間。芯片轉換時間僅為32μS,據(jù)有雙數(shù)據(jù)輸出可作為數(shù)據(jù)校驗,以減少數(shù)據(jù)誤差,轉換速度快且穩(wěn)定性能強。獨立的芯片使能輸入,使多器件掛接和處理器控制變的更加方便。通過DI 數(shù)據(jù)輸入端,可以輕易的實現(xiàn)通道功能的選擇。 
圖3.2 STC89C52外圍接口電路圖 其封裝及引腳如圖3.3所示,引腳介紹如下:
CS_ 片選使能,低電平芯片使能 CH0 模擬輸入通道0,或作為IN+/-使用 CH1 模擬輸入通道1,或作為IN+/-使用 GND 芯片參考0 電位(地) DI 數(shù)據(jù)信號輸入,選擇通道控制 DO 數(shù)據(jù)信號輸出,轉換數(shù)據(jù)輸出 圖3.3 ADC0832引腳圖 3.4 LCD1602顯示器LCD,又稱液晶顯示器(Liquid Crystal Display),為平面超薄的顯示設備,它由一定數(shù)量的彩色或黑白像素組成,放置于光源或者反射面前方。LCD功耗很低,因此倍受工程師青睞,適用于使用電池的電子設備。它的主要原理是以電流刺激液晶分子產(chǎn)生點、線、面配合背部燈管構成畫面。 LCD與單片機連接如圖3.4所示

圖3.4 LCD1602與單片機連接圖
其引腳介紹如表3.3所示:
表3.3 LCD1602引腳介紹表
其主要技術參數(shù)如下: 顯示容量:16*2個字符 芯片工作電壓:4.5-5.5V 工作電流:2.0mA(5.0V) 模塊最佳工作電壓:5.0V 字符尺寸:2.95*4.35(W*H)mm
第四章 軟件設計4.1電阻爐溫度控制器主程序電阻爐溫度控制器主程序首先進行液晶初始化,然后判斷1s標志是否執(zhí)行;如果是,進行AD采樣,執(zhí)行AD處理子程序,ADC0832采集電壓信號;之后判斷是否有按鍵按下,執(zhí)行按鍵處理子程序;若沒有按鍵按下,計算PID值;隨后對數(shù)據(jù)顯示處理,顯示PID值,結束。其主程序流程圖如圖4.1所示

圖4.1 主程序流程圖 4.2 ADC0832數(shù)據(jù)采集子程序 按照ADC0832的工作方式
,可以得到如圖4.2所示的程序 流程圖。 在將ADC0832的端口定義 好后,用CS=0選通ADC0832, 之后,將DI端置1,開始AD 轉換,然后送入通道0或者1 的選擇信息,在DO端先輸出 D7-D0數(shù)據(jù),再輸出D0-D7數(shù) 據(jù),然后比較兩次輸出的數(shù)據(jù) 值是否相等,若不相等,繼續(xù) 采樣,若相等,返回采樣值。
圖4.2 ADC0832數(shù)據(jù)采集子程序 4.3熱電偶線性化標度變換程序性標度變換是熱電偶采集溫度與A/D轉換器之間的橋梁,是關鍵性環(huán)節(jié),流程圖如圖4.3所示 在程序中,DAT代表A/D線性標度變換值,首先DAT與轉換值進行比較,判斷其符合哪一個段內(nèi);MDAT表示顯示溫度值,當DAT判斷其處于哪一個段內(nèi),這樣根據(jù)線性標度變換公式,即可求出其采集的溫度值;之后返回溫度值MDAT,以備LCD顯示器顯示。

圖4.3 線性標度變換子程序 4.4 PID控制程序單片機對A/D采集的溫度需要進行 與設定溫度值進行比較,然后經(jīng)過 PID控制,其PID控制流程圖如圖4.4所示 首先,定義偏差et= Indat-Tedat (Indat表示測量值,Tedat表示設定 值),偏差之和sumet,連續(xù)兩偏差之 差et_temp;然后判斷20ms標志flag2 是否為1,若是,進行PID計算,算出 pout,若否,輸出上次pout。此PID 為了顯示方便,保證輸出為正,因 此判定pout是否為負。
圖4.4 PID控制程序 4.5 PID參數(shù)修改子程序為了能夠滿足用戶的需要,電阻爐溫度控制器能偶調(diào)整不同的PID參數(shù),以便控制溫度。其PID參數(shù)修改子程序流程圖如圖4.5所示: 簡單介紹這幾個按鍵功能: 1鍵—功能鍵:選擇修改kp、ki、kd 2鍵—加1鍵 3鍵—減1鍵 4鍵—確定鍵 
圖4.5 PID參數(shù)修改子程序 4.6 LCD顯示子程序根據(jù)設計要求,進行LCD顯示 程序的編寫,流程如圖4.6所示。 液晶顯示模塊是一個慢顯示器 件,所以在執(zhí)行每條指令之前一定 要確認模塊的忙標志為低電平,表 示不忙,否則此指令失效。設置顯 示的字符模式,顯示字符時要先輸 入顯示字符地址,也就是告訴模塊 在哪里顯示字符,最后將字符碼寫 入到指定位置。
圖4.6 LCD顯示程序
第五章 總結這次智能儀器設計,我們在王老師的指導下,做了關于自制電阻爐溫度控制器的設計。雖然,由于某些硬件的短缺,沒能做成一個完整的電阻爐溫度控制器,但是基本上做出了溫度的采集、PID控制、顯示等。在這次設計中,我們通過自己查閱資料,和同學老師交流辯論,加深了對熱電偶、A/D轉換器、PID控制、單片機中斷等好多理論知識理解。同時,再做這個設計我們需要學會protel99 畫原理圖、visio畫流程圖、如鵬版Keil進行軟件編程、STC_ISP_V4.7.9軟件下載.這些東西對于我來說是第一次接觸,但是通過這次設計的親自完成,雖然不敢說已經(jīng)全部掌握,但至少我能夠自己在以后的運用的輕松操縱。 對于我們所做得這個電阻爐溫度控制器的設計,首先,在硬件方面我們選的是STC89C52作為單片機對溫度進行PID控制,ADC0832作為A/D轉換器進行A/D采樣,熱電偶作為溫度傳感器,LCD顯示器作為溫度和其他參數(shù)顯示。對于硬件的連接不成問題。其次,在軟件方面,我們用到了ADC0832采集子程序、線性標注變換子程序、PID控制子程序、PID參數(shù)修改子程序、LCD顯示子程序、以及最重要的主程序。這些程序經(jīng)過我們的努力基本上實現(xiàn)了其各自的功能,也和主程序密切連接。最后,我們的設計基本上符合了老師規(guī)定的要求,但是在細節(jié)方面也許有許多的不足和漏洞,我們會不斷的改進,也希望大家給我們指正,我們將會不斷完善我們的作品。 總的來說,這次設計讓我學習了不少東西。第一、理論學習是必須的,我們必須一直注重自己的理論學習,踏踏實實把理論知識學習好,才能順利實踐。第二、理論固然重要,但是沒有實踐的演練,理論永遠只是一紙空文,學習理論的最終目的是為了實踐,因此我們應該不斷實踐。第三、在這個網(wǎng)絡發(fā)達的時代,我們應該學會運用網(wǎng)上的知識,目的就是學會學習,高效做事。
單片機源碼:
- #include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
- #include "intrins.h"
- sbit RS = P1^0; //Pin4
- sbit RW = P1^1; //Pin5
- sbit EN = P1^2; //Pin6
-
- sbit key1 = P1^4; //Pin6
- sbit key2 = P1^5; //Pin6
- sbit key3 = P1^6; //Pin6
- sbit key4 = P1^7; //Pin6
- //ADC0832的引腳
- sbit ADCS =P2^0; //ADC0832 chip seclect
- sbit ADDI =P3^7; //ADC0832 k in
- sbit ADDO =P3^7; //ADC0832 k out
- sbit ADCLK =P3^6; //ADC0832 clock signal
-
-
- #define uchar unsigned char
- #define uint unsigned int
-
- #define date P0
- #define RS_CLR RS=0
- #define RS_SET RS=1
- #define RW_CLR RW=0
- #define RW_SET RW=1
- #define EN_CLR EN=0
- #define EN_SET EN=1
- #define INIT_TEMP 800
- #define MIN_TEMP 100
- #define MAX_TEMP 900
- //#define MAX 1500
- uchar code Temp_Data[]={"0123456789"};
- uchar code Temp_Min[]={"Temp is most Min"};
- uchar code Temp_Max[]={"Temp is most Max"};
- uchar tem1[10]={0,45,101,164,255};
- uchar tem2[10]={0,300,600,900,1300};
- uchar temp1[18]={"WD: PID: "},temp2[16]={"P= I= D= "};
- uchar getdata; //獲取ADC轉換回來的值
- bit flag,flag2;
- uchar time_20ms,time_ms,time_1s,Bottem,data1,data2,kemp;
- char et,sumet,et_temp;
- int pout,OUT;
- char KP=5;KI=10;KD=15;
- int Init_PID( uchar Indat,uchar Tedat,char et_old);
- /************
- 讀ADC0832函數(shù)
- ************/
- //采集并返回
- unsigned int Adc0832(unsigned char channel) //AD轉換,返回結果
- {
- uchar i=0;
- uchar j;
- uint dat=0;
- uchar ndat=0;
-
- if(channel==0)channel=2;
- if(channel==1)channel=3;
- ADDI=1;
- _nop_();
- _nop_();
- ADCS=0;//拉低CS端
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿1
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- ADDI=channel&0x1;
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿2
- _nop_();
- _nop_();
- ADCLK=1;//拉高CLK端
- ADDI=(channel>>1)&0x1;
- _nop_();
- _nop_();
- ADCLK=0;//拉低CLK端,形成下降沿3
- ADDI=1;//控制命令結束
- _nop_();
- _nop_();
- dat=0;
- for(i=0;i<8;i++)
- {
- dat|=ADDO;//收數(shù)據(jù)
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次時鐘脈沖
- _nop_();
- _nop_();
- dat<<=1;
- if(i==7)dat|=ADDO;
- }
- for(i=0;i<8;i++)
- {
- j=0;
- j=j|ADDO;//收數(shù)據(jù)
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次時鐘脈沖
- _nop_();
- _nop_();
- j=j<<7;
- ndat=ndat|j;
- if(i<7)ndat>>=1;
- }
- ADCS=1;//拉低CS端
- ADCLK=0;//拉低CLK端
- ADDO=1;//拉高數(shù)據(jù)端,回到初始狀態(tài)
- dat<<=8;
- dat|=ndat;
- return(dat); //return ad k
- }
- /**中斷**/
- void Init_Time()
- {
- TMOD=0X10;
- TH1=(65536-20000)/256;
- TL1=(65536-20000)%256;
- EA=1;
- ET1=1;
- TR1=1;
- }
- /******************************************************************/
- /* 微秒延時函數(shù) */
- /******************************************************************/
- void delay_us(unsigned int n) //延時 如果需要高精度延時 請嵌入?yún)R編
- {
- if (n == 0)
- {
- return ;
- }
- while (--n);
- }
- /******************************************************************/
- /* 毫秒函數(shù)聲明 */
- /******************************************************************/
- void delay_ms(unsigned char i)
- {
- unsigned char a, b;
- for (a = 1; a < i; a++)
- {
- for (b = 1; b; b++)
- { ; }
- }
- }
- /******************************************************************/
- /* 寫入命令函數(shù) */
- /******************************************************************/
- void LCD_write_com(unsigned char com)
- {
- RS_CLR;
- RW_CLR;
- EN_SET;
- date = com;
- delay_us(5);
- EN_CLR;
- }
- /******************************************************************/
- /* 寫入數(shù)據(jù)函數(shù) */
- /******************************************************************/
- void LCD_write_Data(unsigned char Data)
- {
- RS_SET;
- RW_CLR;
- EN_SET;
- date = Data;
- delay_us(5);
- EN_CLR;
- }
- /******************************************************************/
- /* 寫入字符串函數(shù) */
- /******************************************************************/
- void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s)
- {
- if (y == 0)
- {
- LCD_write_com(0x80 + x);
- }
- else
- {
- LCD_write_com(0xC0 + x);
- }
- while (*s)
- {
- LCD_write_Data( *s);
- s ++;
- }
- if(Bottem==1)
- {
-
- LCD_write_com(0x0f);
- LCD_write_com(0xC0);
- }
- if(Bottem==2)
- {
-
- LCD_write_com(0x0f);
- LCD_write_com(0xC5);
- }
- if(Bottem==3)
- {
-
- LCD_write_com(0x0f);
- LCD_write_com(0xCA);
- }
-
- }
- /******************************************************************/
- /* 初始化函數(shù) */
- /******************************************************************/
- void LCD_init(void)
- {
- LCD_write_com(0x38); /*顯示模式設置*/
- delay_ms(5);
- LCD_write_com(0x38);
- delay_ms(5);
- LCD_write_com(0x38);
- delay_ms(5);
- LCD_write_com(0x38);
- LCD_write_com(0x08); /*顯示關閉*/
- LCD_write_com(0x01); /*顯示清屏*/
- LCD_write_com(0x06); /*顯示光標移動設置*/
- delay_ms(5);
- LCD_write_com(0x0C); /*顯示開及光標設置*/
- }
- int spdat(uchar DAT)
- {
- uchar i;
- int MDAT;
- for(i=0;i<5;i++)
- {
- if(DAT>tem1[i]&&DAT<tem1[i+1])
- {
- MDAT=tem2[i]+((float)DAT/tem1[i])*tem2[i];
- }
- }
- return MDAT;
- }
- void Make_Data(uchar WDAT)
- {
- int WD,i,k,j,n;
- //WD=((float)WDAT/255)*MAX;
- WD=spdat(WDAT);
- if(WD<=MIN_TEMP)
- kemp=1;
- if(WD>=MAX_TEMP)
- kemp=2;
- if(WD>MIN_TEMP&&WD<MAX_TEMP)
- kemp=0;
- OUT=Init_PID(INIT_TEMP,WD,et);
- temp1[3]=Temp_Data[WD/1000];
- i=WD%1000;
- temp1[4]=Temp_Data[i/100];
- k=i%100;
- temp1[5]=Temp_Data[k/10];
- temp1[6]=Temp_Data[k%10];
-
-
- temp1[12]=Temp_Data[OUT/1000];
- j=OUT%1000;
- temp1[13]=Temp_Data[j/100];
- n=j%100;
- temp1[14]=Temp_Data[n/10];
- temp1[15]=Temp_Data[n%10];
-
- temp2[2]=Temp_Data[KP/10];
- temp2[3]=Temp_Data[KP%10];
-
- temp2[7]=Temp_Data[KI/10];
- temp2[8]=Temp_Data[KI%10];
-
- temp2[12]=Temp_Data[KD/10];
- temp2[13]=Temp_Data[KD%10];
-
-
- }
- /****PID****/
- int Init_PID( uchar Indat,uchar Tedat,char et_old)
- {
- et= Indat-Tedat;
- sumet+=et;
- et_temp=et-et_old;
- if(flag2)
- {
- flag2=0;
- pout=KP*et+KI*sumet+KD*et_temp;
- if(pout<0)
- pout=0-pout;
- return pout;
- }
- else
- {
- return pout;
- }
- }
- void Make_Key()
- {
- if(key1==0)
- {
- Bottem++;
- if(Bottem>=4)
- Bottem=1;
- }
- if(Bottem==1)
- {
- if(key2==0)
- {
- KP++;
- if(KP>=50)
- KP=50;
- }
- if(key3==0)
- {
- KP--;
- if(KP<=0)
- KP=0;
- }
- }
- if(Bottem==2)
- {
- if(key2==0)
- {
- KI++;
- if(KI>=50)
- KI=50;
- }
- if(key3==0)
- {
- KI--;
- if(KI<=0)
- KI=0;
- }
- }
- if(Bottem==3)
- {
- if(key2==0)
- {
- KD++;
- if(KD>=50)
- KD=50;
- }
- if(key3==0)
- {
- KD--;
- if(KD<=0)
- KD=0;
- }
- }
- if(key4==0)
- {
- Bottem=0;
- }
- }
- /******************************************************************/
- /* 主函數(shù) */
- /******************************************************************/
-
- void main(void)
- {
- LCD_init();
- Init_Time();
- while (1)
- {
- //Init_PID();
- if(time_ms==10)
- {
- time_ms=0;
- Make_Key();
- LCD_write_str(0,0,temp1);
- LCD_write_str(0,1,temp2);
- if(kemp==1)
- LCD_write_str(0,1,Temp_Min);
- if(kemp==2)
- LCD_write_str(0,1,Temp_Max);
- Make_Data(getdata);
- }
- if(flag)
- {
- flag=0;
- getdata=Adc0832(0);
- Make_Data(getdata);
- }
-
-
- }
- }
-
- void T1_time() interrupt 3
- {
- time_20ms++;
- time_ms++;
- TH1=(65536-20000)/256;
- TL1=(65536-20000)%256;
- if(time_20ms==50)
- {
- time_20ms=0;
- time_1s++;
- if(time_1s==2)
- {
- time_1s=0;
- flag2=1;
- }
- flag=1;
-
- }
-
- }
復制代碼
以上的Word格式文檔51黑下載地址:
爐溫.zip
(370.11 KB, 下載次數(shù): 337)
2018-12-29 18:48 上傳
點擊文件名下載附件
|