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

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

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

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

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

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

圖4.3 線性標(biāo)度變換子程序 4.4 PID控制程序單片機(jī)對(duì)A/D采集的溫度需要進(jìn)行 與設(shè)定溫度值進(jìn)行比較,然后經(jīng)過(guò) PID控制,其PID控制流程圖如圖4.4所示 首先,定義偏差et= Indat-Tedat (Indat表示測(cè)量值,Tedat表示設(shè)定 值),偏差之和sumet,連續(xù)兩偏差之 差et_temp;然后判斷20ms標(biāo)志flag2 是否為1,若是,進(jìn)行PID計(jì)算,算出 pout,若否,輸出上次pout。此PID 為了顯示方便,保證輸出為正,因 此判定pout是否為負(fù)。
圖4.4 PID控制程序 4.5 PID參數(shù)修改子程序為了能夠滿足用戶的需要,電阻爐溫度控制器能偶調(diào)整不同的PID參數(shù),以便控制溫度。其PID參數(shù)修改子程序流程圖如圖4.5所示: 簡(jiǎn)單介紹這幾個(gè)按鍵功能: 1鍵—功能鍵:選擇修改kp、ki、kd 2鍵—加1鍵 3鍵—減1鍵 4鍵—確定鍵 
圖4.5 PID參數(shù)修改子程序 4.6 LCD顯示子程序根據(jù)設(shè)計(jì)要求,進(jìn)行LCD顯示 程序的編寫,流程如圖4.6所示。 液晶顯示模塊是一個(gè)慢顯示器 件,所以在執(zhí)行每條指令之前一定 要確認(rèn)模塊的忙標(biāo)志為低電平,表 示不忙,否則此指令失效。設(shè)置顯 示的字符模式,顯示字符時(shí)要先輸 入顯示字符地址,也就是告訴模塊 在哪里顯示字符,最后將字符碼寫 入到指定位置。
圖4.6 LCD顯示程序
第五章 總結(jié)這次智能儀器設(shè)計(jì),我們?cè)谕趵蠋煹闹笇?dǎo)下,做了關(guān)于自制電阻爐溫度控制器的設(shè)計(jì)。雖然,由于某些硬件的短缺,沒能做成一個(gè)完整的電阻爐溫度控制器,但是基本上做出了溫度的采集、PID控制、顯示等。在這次設(shè)計(jì)中,我們通過(guò)自己查閱資料,和同學(xué)老師交流辯論,加深了對(duì)熱電偶、A/D轉(zhuǎn)換器、PID控制、單片機(jī)中斷等好多理論知識(shí)理解。同時(shí),再做這個(gè)設(shè)計(jì)我們需要學(xué)會(huì)protel99 畫原理圖、visio畫流程圖、如鵬版Keil進(jìn)行軟件編程、STC_ISP_V4.7.9軟件下載.這些東西對(duì)于我來(lái)說(shuō)是第一次接觸,但是通過(guò)這次設(shè)計(jì)的親自完成,雖然不敢說(shuō)已經(jīng)全部掌握,但至少我能夠自己在以后的運(yùn)用的輕松操縱。 對(duì)于我們所做得這個(gè)電阻爐溫度控制器的設(shè)計(jì),首先,在硬件方面我們選的是STC89C52作為單片機(jī)對(duì)溫度進(jìn)行PID控制,ADC0832作為A/D轉(zhuǎn)換器進(jìn)行A/D采樣,熱電偶作為溫度傳感器,LCD顯示器作為溫度和其他參數(shù)顯示。對(duì)于硬件的連接不成問題。其次,在軟件方面,我們用到了ADC0832采集子程序、線性標(biāo)注變換子程序、PID控制子程序、PID參數(shù)修改子程序、LCD顯示子程序、以及最重要的主程序。這些程序經(jīng)過(guò)我們的努力基本上實(shí)現(xiàn)了其各自的功能,也和主程序密切連接。最后,我們的設(shè)計(jì)基本上符合了老師規(guī)定的要求,但是在細(xì)節(jié)方面也許有許多的不足和漏洞,我們會(huì)不斷的改進(jìn),也希望大家給我們指正,我們將會(huì)不斷完善我們的作品。 總的來(lái)說(shuō),這次設(shè)計(jì)讓我學(xué)習(xí)了不少東西。第一、理論學(xué)習(xí)是必須的,我們必須一直注重自己的理論學(xué)習(xí),踏踏實(shí)實(shí)把理論知識(shí)學(xué)習(xí)好,才能順利實(shí)踐。第二、理論固然重要,但是沒有實(shí)踐的演練,理論永遠(yuǎn)只是一紙空文,學(xué)習(xí)理論的最終目的是為了實(shí)踐,因此我們應(yīng)該不斷實(shí)踐。第三、在這個(gè)網(wǎng)絡(luò)發(fā)達(dá)的時(shí)代,我們應(yīng)該學(xué)會(huì)運(yùn)用網(wǎng)上的知識(shí),目的就是學(xué)會(huì)學(xué)習(xí),高效做事。
單片機(jī)源碼:
- #include<reg52.h> //包含頭文件,一般情況不需要改動(dòng),頭文件包含特殊功能寄存器的定義
- #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轉(zhuǎn)換回來(lái)的值
- 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轉(zhuǎn)換,返回結(jié)果
- {
- 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;//控制命令結(jié)束
- _nop_();
- _nop_();
- dat=0;
- for(i=0;i<8;i++)
- {
- dat|=ADDO;//收數(shù)據(jù)
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0;//形成一次時(shí)鐘脈沖
- _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;//形成一次時(shí)鐘脈沖
- _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í)函數(shù) */
- /******************************************************************/
- void delay_us(unsigned int n) //延時(shí) 如果需要高精度延時(shí) 請(qǐng)嵌入?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); /*顯示模式設(shè)置*/
- 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); /*顯示關(guān)閉*/
- LCD_write_com(0x01); /*顯示清屏*/
- LCD_write_com(0x06); /*顯示光標(biāo)移動(dòng)設(shè)置*/
- delay_ms(5);
- LCD_write_com(0x0C); /*顯示開及光標(biāo)設(shè)置*/
- }
- 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;
-
- }
-
- }
復(fù)制代碼
以上的Word格式文檔51黑下載地址:
爐溫.zip
(370.11 KB, 下載次數(shù): 337)
2018-12-29 18:48 上傳
點(diǎn)擊文件名下載附件
|