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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10036|回復: 8
收起左側

基于單片機PID控制的自動電阻爐溫度控制器設計

  [復制鏈接]
ID:458245 發(fā)表于 2018-12-29 18:49 | 顯示全部樓層 |閱讀模式
此電阻爐溫度控制器主要是以單片機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 標度變換表

溫度值(℃)
分度表值(mv)
A/D采樣值(v)
轉換值
0
0
0
0
300
2.323
0.883
45
600
5.237
1.99
101
900
8.448
3.211
164
1300
13.155
5
255
3.2 單片機STC89C52及其外圍接口電路3.2.1 單片機STC89C52

STC89C52是一種低功耗、高性能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引腳介紹表

編號
符號
引腳說明
編號
符號
引腳說明
1
VSS
電源地
9
D2
雙向數(shù)據(jù)線
2
VDD
5v電源正極
10
D3
雙向數(shù)據(jù)線
3
VL
液晶顯示偏壓
11
D4
雙向數(shù)據(jù)線
4
RS
數(shù)據(jù)/命令選擇
12
D5
雙向數(shù)據(jù)線
5
R/W
讀/寫選擇
13
D6
雙向數(shù)據(jù)線
6
E
使能信號
14
D7
雙向數(shù)據(jù)線
7
D0
雙向數(shù)據(jù)線
15
BLA
背光源正極
8
D1
雙向數(shù)據(jù)線
16
BLK
背光源負極

其主要技術參數(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)上的知識,目的就是學會學習,高效做事。


單片機源碼:


  1. #include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
  2. #include "intrins.h"
  3. sbit RS = P1^0; //Pin4
  4. sbit RW = P1^1; //Pin5
  5. sbit EN = P1^2; //Pin6

  6. sbit key1 = P1^4; //Pin6
  7. sbit key2 = P1^5; //Pin6
  8. sbit key3 = P1^6; //Pin6
  9. sbit key4 = P1^7; //Pin6
  10. //ADC0832的引腳
  11. sbit ADCS =P2^0;  //ADC0832 chip seclect
  12. sbit ADDI =P3^7;  //ADC0832 k in
  13. sbit ADDO =P3^7;  //ADC0832 k out
  14. sbit ADCLK =P3^6;  //ADC0832 clock signal


  15. #define uchar  unsigned char
  16. #define uint  unsigned int

  17. #define date  P0
  18. #define RS_CLR RS=0
  19. #define RS_SET RS=1
  20. #define RW_CLR RW=0
  21. #define RW_SET RW=1
  22. #define EN_CLR EN=0
  23. #define EN_SET EN=1
  24. #define INIT_TEMP 800
  25. #define MIN_TEMP 100
  26. #define MAX_TEMP 900
  27. //#define MAX 1500
  28. uchar code Temp_Data[]={"0123456789"};
  29. uchar code Temp_Min[]={"Temp is most Min"};
  30. uchar code Temp_Max[]={"Temp is most Max"};
  31. uchar tem1[10]={0,45,101,164,255};
  32. uchar tem2[10]={0,300,600,900,1300};                                                                                                                                                                                                   
  33. uchar temp1[18]={"WD:     PID:    "},temp2[16]={"P=   I=   D=    "};
  34. uchar getdata; //獲取ADC轉換回來的值
  35. bit flag,flag2;
  36. uchar time_20ms,time_ms,time_1s,Bottem,data1,data2,kemp;
  37. char et,sumet,et_temp;
  38. int pout,OUT;
  39. char KP=5;KI=10;KD=15;
  40. int Init_PID( uchar Indat,uchar Tedat,char et_old);
  41. /************
  42. 讀ADC0832函數(shù)
  43. ************/
  44. //采集并返回
  45. unsigned int Adc0832(unsigned char channel)     //AD轉換,返回結果
  46. {
  47.     uchar i=0;
  48.     uchar j;
  49.     uint dat=0;
  50.     uchar ndat=0;

  51.     if(channel==0)channel=2;
  52.     if(channel==1)channel=3;
  53.     ADDI=1;
  54.     _nop_();
  55.     _nop_();
  56.     ADCS=0;//拉低CS端
  57.     _nop_();
  58.     _nop_();
  59.     ADCLK=1;//拉高CLK端
  60.     _nop_();
  61.     _nop_();
  62.     ADCLK=0;//拉低CLK端,形成下降沿1
  63.     _nop_();
  64.     _nop_();
  65.     ADCLK=1;//拉高CLK端
  66.     ADDI=channel&0x1;
  67.     _nop_();
  68.     _nop_();
  69.     ADCLK=0;//拉低CLK端,形成下降沿2
  70.     _nop_();
  71.     _nop_();
  72.     ADCLK=1;//拉高CLK端
  73.     ADDI=(channel>>1)&0x1;
  74.     _nop_();
  75.     _nop_();
  76.     ADCLK=0;//拉低CLK端,形成下降沿3
  77.     ADDI=1;//控制命令結束
  78.     _nop_();
  79.     _nop_();
  80.     dat=0;
  81.     for(i=0;i<8;i++)
  82.     {
  83.         dat|=ADDO;//收數(shù)據(jù)
  84.         ADCLK=1;
  85.         _nop_();
  86.         _nop_();
  87.         ADCLK=0;//形成一次時鐘脈沖
  88.         _nop_();
  89.         _nop_();
  90.         dat<<=1;
  91.         if(i==7)dat|=ADDO;
  92.     }
  93.     for(i=0;i<8;i++)
  94.     {
  95.         j=0;
  96.         j=j|ADDO;//收數(shù)據(jù)
  97.         ADCLK=1;
  98.         _nop_();
  99.         _nop_();
  100.         ADCLK=0;//形成一次時鐘脈沖
  101.         _nop_();
  102.         _nop_();
  103.         j=j<<7;
  104.         ndat=ndat|j;
  105.         if(i<7)ndat>>=1;
  106.     }
  107.     ADCS=1;//拉低CS端
  108.     ADCLK=0;//拉低CLK端
  109.     ADDO=1;//拉高數(shù)據(jù)端,回到初始狀態(tài)
  110.     dat<<=8;
  111.     dat|=ndat;
  112.     return(dat);            //return ad k
  113. }
  114. /**中斷**/
  115. void Init_Time()
  116. {
  117. TMOD=0X10;
  118. TH1=(65536-20000)/256;
  119. TL1=(65536-20000)%256;
  120. EA=1;
  121. ET1=1;
  122. TR1=1;
  123. }
  124. /******************************************************************/
  125. /*                    微秒延時函數(shù)                                */
  126. /******************************************************************/
  127. void delay_us(unsigned int n) //延時 如果需要高精度延時 請嵌入?yún)R編
  128. {
  129. if (n == 0)
  130.   {
  131.   return ;
  132.   }
  133.   while (--n);
  134. }
  135. /******************************************************************/
  136. /*                    毫秒函數(shù)聲明                                */
  137. /******************************************************************/
  138. void delay_ms(unsigned char i)
  139. {
  140. unsigned char a, b;
  141. for (a = 1; a < i; a++)
  142. {
  143.    for (b = 1; b; b++)
  144.    {   ;   }
  145.     }
  146. }
  147. /******************************************************************/
  148. /*                   寫入命令函數(shù)                                 */
  149. /******************************************************************/
  150. void LCD_write_com(unsigned char com)
  151. {
  152. RS_CLR;
  153. RW_CLR;
  154. EN_SET;
  155. date = com;
  156. delay_us(5);
  157. EN_CLR;
  158. }
  159. /******************************************************************/
  160. /*                   寫入數(shù)據(jù)函數(shù)                                 */
  161. /******************************************************************/
  162. void LCD_write_Data(unsigned char Data)
  163. {
  164. RS_SET;
  165. RW_CLR;
  166. EN_SET;
  167. date = Data;
  168. delay_us(5);
  169. EN_CLR;
  170. }                                                                                                                             
  171. /******************************************************************/
  172. /*                   寫入字符串函數(shù)                               */
  173. /******************************************************************/
  174. void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s)
  175. {   
  176. if (y == 0)
  177. {   
  178. LCD_write_com(0x80 + x);   
  179. }
  180. else
  181. {   
  182. LCD_write_com(0xC0 + x);   
  183. }      
  184. while (*s)
  185. {   
  186. LCD_write_Data( *s);   
  187. s ++;   
  188. }
  189. if(Bottem==1)
  190. {
  191.             
  192.               LCD_write_com(0x0f);            
  193.               LCD_write_com(0xC0);            
  194. }
  195. if(Bottem==2)
  196. {
  197.             
  198.               LCD_write_com(0x0f);            
  199.               LCD_write_com(0xC5);            
  200. }
  201. if(Bottem==3)
  202. {
  203.             
  204.               LCD_write_com(0x0f);            
  205.               LCD_write_com(0xCA);            
  206. }

  207. }
  208. /******************************************************************/
  209. /*                   初始化函數(shù)                                   */
  210. /******************************************************************/
  211. void LCD_init(void)
  212. {
  213.    LCD_write_com(0x38);    /*顯示模式設置*/
  214.    delay_ms(5);
  215.    LCD_write_com(0x38);
  216.    delay_ms(5);
  217.    LCD_write_com(0x38);
  218.    delay_ms(5);
  219.    LCD_write_com(0x38);
  220.    LCD_write_com(0x08);    /*顯示關閉*/
  221.    LCD_write_com(0x01);    /*顯示清屏*/
  222.    LCD_write_com(0x06);    /*顯示光標移動設置*/
  223.    delay_ms(5);
  224.    LCD_write_com(0x0C);    /*顯示開及光標設置*/
  225.    }
  226. int  spdat(uchar DAT)
  227. {
  228.               uchar i;
  229.               int MDAT;
  230.               for(i=0;i<5;i++)
  231.               {
  232.                             if(DAT>tem1[i]&&DAT<tem1[i+1])
  233.                             {
  234.                                           MDAT=tem2[i]+((float)DAT/tem1[i])*tem2[i];                                         
  235.                             }
  236.               }
  237.               return MDAT;
  238. }
  239. void Make_Data(uchar WDAT)
  240. {
  241.               int WD,i,k,j,n;
  242.               //WD=((float)WDAT/255)*MAX;
  243.               WD=spdat(WDAT);
  244.               if(WD<=MIN_TEMP)
  245.               kemp=1;
  246.               if(WD>=MAX_TEMP)
  247.               kemp=2;
  248.               if(WD>MIN_TEMP&&WD<MAX_TEMP)
  249.               kemp=0;
  250.               OUT=Init_PID(INIT_TEMP,WD,et);
  251.               temp1[3]=Temp_Data[WD/1000];
  252.               i=WD%1000;
  253.               temp1[4]=Temp_Data[i/100];
  254.               k=i%100;
  255.               temp1[5]=Temp_Data[k/10];
  256.               temp1[6]=Temp_Data[k%10];
  257.                                                                                                                   

  258.               temp1[12]=Temp_Data[OUT/1000];            
  259.               j=OUT%1000;
  260.               temp1[13]=Temp_Data[j/100];
  261.               n=j%100;
  262.               temp1[14]=Temp_Data[n/10];
  263.               temp1[15]=Temp_Data[n%10];
  264.             
  265.               temp2[2]=Temp_Data[KP/10];
  266.               temp2[3]=Temp_Data[KP%10];

  267.               temp2[7]=Temp_Data[KI/10];
  268.               temp2[8]=Temp_Data[KI%10];

  269.               temp2[12]=Temp_Data[KD/10];
  270.               temp2[13]=Temp_Data[KD%10];

  271.                            
  272. }
  273.    /****PID****/
  274. int Init_PID( uchar Indat,uchar Tedat,char et_old)
  275. {
  276.               et= Indat-Tedat;
  277.               sumet+=et;
  278.               et_temp=et-et_old;
  279.               if(flag2)
  280.               {                           
  281.                             flag2=0;
  282.                             pout=KP*et+KI*sumet+KD*et_temp;
  283.                             if(pout<0)
  284.                             pout=0-pout;
  285.                             return pout;
  286.               }
  287.               else
  288.               {                           
  289.                             return pout;
  290.               }                                                      
  291. }
  292. void Make_Key()
  293. {
  294.               if(key1==0)
  295.               {
  296.                             Bottem++;
  297.                             if(Bottem>=4)
  298.                             Bottem=1;
  299.               }
  300.               if(Bottem==1)
  301.               {
  302.                             if(key2==0)
  303.                             {
  304.                                           KP++;
  305.                                           if(KP>=50)
  306.                                           KP=50;
  307.                             }
  308.                             if(key3==0)
  309.                             {
  310.                                           KP--;
  311.                                           if(KP<=0)
  312.                                           KP=0;
  313.                             }
  314.               }
  315.               if(Bottem==2)
  316.               {
  317.                             if(key2==0)
  318.                             {
  319.                                           KI++;
  320.                                           if(KI>=50)
  321.                                           KI=50;
  322.                             }
  323.                             if(key3==0)
  324.                             {
  325.                                           KI--;
  326.                                           if(KI<=0)
  327.                                           KI=0;
  328.                             }
  329.               }
  330.               if(Bottem==3)
  331.               {
  332.                             if(key2==0)
  333.                             {
  334.                                           KD++;
  335.                                           if(KD>=50)
  336.                                           KD=50;
  337.                             }
  338.                             if(key3==0)
  339.                             {
  340.                                           KD--;
  341.                                           if(KD<=0)
  342.                                           KD=0;
  343.                             }
  344.               }
  345.               if(key4==0)
  346.               {
  347.                             Bottem=0;            
  348.               }
  349. }
  350. /******************************************************************/
  351. /*                   主函數(shù)                                       */
  352. /******************************************************************/  

  353. void main(void)
  354. {
  355.               LCD_init();
  356.               Init_Time();
  357.               while (1)
  358.               {                                                                       
  359.                             //Init_PID();
  360.                             if(time_ms==10)
  361.                             {
  362.                                           time_ms=0;
  363.                                           Make_Key();
  364.                                           LCD_write_str(0,0,temp1);                                         
  365.                                           LCD_write_str(0,1,temp2);
  366.                                           if(kemp==1)
  367.                                           LCD_write_str(0,1,Temp_Min);
  368.                                           if(kemp==2)
  369.                                           LCD_write_str(0,1,Temp_Max);                                         
  370.                                           Make_Data(getdata);
  371.                             }
  372.                             if(flag)
  373.                             {
  374.                                              flag=0;                                         
  375.                                           getdata=Adc0832(0);
  376.                                           Make_Data(getdata);
  377.                             }
  378.                            
  379.                                          
  380.               }
  381. }

  382. void T1_time() interrupt 3
  383. {
  384.               time_20ms++;
  385.               time_ms++;
  386.               TH1=(65536-20000)/256;
  387.               TL1=(65536-20000)%256;
  388.               if(time_20ms==50)
  389.               {
  390.                             time_20ms=0;
  391.                             time_1s++;
  392.                             if(time_1s==2)
  393.                             {
  394.                                           time_1s=0;
  395.                                           flag2=1;
  396.                             }
  397.                             flag=1;

  398.               }

  399. }
復制代碼

以上的Word格式文檔51黑下載地址:

爐溫.zip (370.11 KB, 下載次數(shù): 337)


評分

參與人數(shù) 3黑幣 +110 收起 理由
songhetai + 30 很給力!
zhangshanqiao + 30 真仔細。
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:553941 發(fā)表于 2020-12-11 14:03 | 顯示全部樓層
只有一個word文檔,沒有仿真,文檔中貼了源碼,也不是完整的pid程序。想學習的省省黑幣吧
回復

使用道具 舉報

ID:508509 發(fā)表于 2019-4-19 17:18 | 顯示全部樓層
不對嗎,怎么坑了
回復

使用道具 舉報

ID:626231 發(fā)表于 2019-10-18 15:48 | 顯示全部樓層
支持一下
回復

使用道具 舉報

ID:682979 發(fā)表于 2020-1-8 13:05 | 顯示全部樓層

你好  在嗎  里面東西全嗎
回復

使用道具 舉報

ID:226319 發(fā)表于 2020-5-10 12:47 | 顯示全部樓層
支持一下,感謝分享
回復

使用道具 舉報

ID:187802 發(fā)表于 2020-5-12 12:17 | 顯示全部樓層

很棒的資料,下載學習,謝謝提供
回復

使用道具 舉報

ID:462629 發(fā)表于 2021-12-28 09:55 | 顯示全部樓層
能補全電路原理圖,源碼嗎
回復

使用道具 舉報

ID:1002058 發(fā)表于 2022-7-1 17:20 | 顯示全部樓層
寫出來,總是好的。
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩欧美三区 | 99久久婷婷国产综合精品电影 | 狠狠天天| 国产成人黄色 | 国产日韩欧美一区二区 | 黄色骚片 | 亚洲精品一区在线观看 | 久草高清视频 | 免费观看色 | 欧美日韩久久精品 | 国产精品国产三级国产aⅴ无密码 | 国产精品theporn| 欧美区在线 | 国产超碰人人爽人人做人人爱 | 国产片网站 | 国产xxx在线观看 | 国内精品视频一区二区三区 | 亚洲字幕在线观看 | 精品综合久久 | 国产日韩精品久久 | 成人性视频免费网站 | 在线高清免费观看视频 | www.天天干.com| 国产精品区二区三区日本 | 欧美一区中文字幕 | 国产成人精品综合 | 成人免费视频网址 | 日本亚洲欧美 | 日本污视频 | 久久精品亚洲精品 | 国产成人一区二区三区精 | 欧美一级欧美三级在线观看 | 午夜免费观看体验区 | 欧美激情综合网 | 一区二区精品视频 | 国产小视频在线 | 国产一区不卡 | 国产一区二区精品在线观看 | 中文字幕第一页在线 | 亚洲一区二区三区视频免费观看 | 日韩免费一区二区 |