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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 35293|回復: 21
收起左側

單片機智能溫控風扇的設計與實現 資料下載

  [復制鏈接]
ID:188484 發表于 2017-4-11 15:34 | 顯示全部樓層 |閱讀模式
以下是部分內容預覽:
到目前,我已經將軟件程序燒入單片機并完成了實物的焊接 ,結果并不是讓人很滿意。溫控風扇的DS18B20傳感器可能有一些問題,因為數碼管所顯示的溫度和實際溫度相差很大,而我檢查了幾遍數碼管及單片機引腳的焊接、軟件程序的編排,并仿真了好幾遍,仿真結果十分好,所以我覺得可能是溫度傳感器出了一些問題。
  
從開始著手做智能溫控風扇到現在,我遇到了很多問題和麻煩。比如說,在線路焊接的時候特別容易將太多引腳的單片機與其他組件焊接錯誤。再比如說,溫度顯示不準確的時候我還曾懷疑是不是焊接錯誤而想把線路全拆了重新開始焊接,是室友在那時候提醒我可以嘗試用仿真去解決這個問題。而目前存在的問題,我覺得文檔方面沒有太多,只是溫度顯示錯誤方面我得多用一些心思了。
  
下一步我準備再買一個DS18B20傳感器回來重新裝上去試一下,如果真的是傳感器的問題那就太好了,如果不是我還要仔細、反復的檢查幾遍。

擬采取的方式、方法及計劃進程、方案(主要技術路線):
系統設計基于單片機的風扇溫控儀采用DS18B20傳感器,將檢測到的溫度轉化為數字信號,單片機對輸入的數字信號進行分析處理,當溫度高于上限值時,風扇全速旋轉;當溫度低于下限時,風扇停轉;當溫度處于上限值與下限之間時,風扇轉速越慢。硬件方面,首先我得購買DS18B20傳感器、89C51單片機、驅動風扇、數碼顯示管、按鍵等,緊接著就是設計電路并將軟件程序燒入單片機內,最后再焊接并進行反復的調試。其中,軟件程序方面,我將采取分塊編程的思想,先將各個模塊編寫調試,最后進行整機連調。其中,圖1所示為硬件設計結構框圖圖2所示為軟件流程圖。
0.png



本設計作為一種智能溫控風扇系統,用戶設置出兩個檔位的高、低溫度值,溫度傳感器DS18B20測出靈敏的溫度變化并用數碼管顯示出來,作為控制平臺的AT89C52單片機芯片對風扇開關以及轉速進行控制,當實際溫度在兩檔之間時打開弱風檔,當實際溫度高于高溫度設定值時自動切換到強風檔,當實際溫度低于低溫度設定值時自動關閉風扇,風扇狀態隨外界實際溫度而改變。

溫控風扇系統,是根據當時溫度情況去自動開通和關閉電風扇,能很好的節約電能,同時也方便用戶們的使用更具人性化。而且溫控風扇系統在工業生產、日常生活中都有廣泛的應用,如在工業生產中大型機械設備的散熱系統,或限制筆記本電腦上的智能CPU風扇等基于單片機的溫控風扇都能夠根據環境溫度的高低自動啟動或停止轉動,并能夠根據溫度的變化實現轉速的自動調節,在現實生活中具非常廣泛的用途,因此它的設計具有一定的價值意義。



目    錄

緒  論              5
一  系統概述              6
1.1  AT89C52單片機簡介              6
1.2  本設計任務和主要內容              6
二  系統原理及其硬件設計              7
2.1 系統總體設計
2.2 控制裝置原理              7
2.3 溫度檢測和顯示電路              8
2.3.1 DS18B20的溫度處理方法              8
2.3.2 溫度傳感器和顯示電路組成              9
2.4 電機調速電路              10
2.4.1  電機調速原理              11
2.4.2  電機控制模塊設計
三  控制器軟件設計
3.1  主程序
3.2  數字溫度傳感器模塊和顯示子模塊
3.3  電機調速與控制子模塊
結 束 語
參考文獻              18
附錄一              19

緒  論


近些年來,隨著空調行業的迅速發展,空調價格的大幅度“跳水”,電風扇行業曾被普遍認為是“夕陽產業”。其實并非如此,市場人士稱,家用電風扇并沒有隨著空調的普及而淡出市場,近兩年反而出現了市場銷售復蘇的態勢。其主要原因:一是風扇和空調的降溫效果不同;(空調有強大的制冷功能,可以快速有效地降低環境溫度,但電風扇的風更溫和,更加適合老人兒童和體質較弱的人使用。)二是電風扇有價格優勢,價格便宜而且相對省電,安裝和使用都非常簡單。

傳統電風扇多采用機械方式進行控制,功能少,噪音大,各檔的風速變化大。隨著科技的發展和人們生活水平的提高,家用電器產品趨向于自動化、智能化、環保化和人性化,使得由微機控制的智能電風扇得以出現。

生活中,我們經常會使用一些與溫度有關的設備。比如,現在雖然不少城市家庭用上了空調,但在占中國大部分人口的農村地區依舊使用電風扇作為降溫防暑設備,春夏(夏秋)交替時節,白天溫度依舊很高,電風扇應高轉速、大風量,使人感到清涼;到了晚上,氣溫降低,當人入睡后,應該逐步減小轉速,以免使人感冒。雖然電風扇都有調節不同檔位的功能,但必須要人手動換檔,睡著了就無能為力了,而普遍采用的定時器關閉的做法,一方面是定時時間長短有限制,一般是一兩個小時;另一方面可能在一兩個小時后氣溫依舊沒有降低很多,而風扇就關閉了,使人在睡夢中熱醒而不得不起床重新打開風扇,增加定時器時間,非常麻煩,而且可能多次定時后最后一次定時時間太長,在溫度降低以后風扇依舊繼續吹風,使人感冒;第三方面是只有簡單的到了定時時間就關閉風扇電源的單一功能,不能滿足氣溫變化對風扇風速大小的不同要求。又比如在較大功率的電子產品散熱方面,現在絕大多數都采用了風冷系統,利用風扇引起空氣流動,帶走熱量,使電子產品不至于發熱燒壞。要使電子產品保持較低的溫度,必須用大功率、高轉速、大風量的風扇,而風扇的噪音與其功率成正比。如果要低噪音,則要減小風扇轉速,又會引起電子設備溫度上升,不能兩全其美。為解決上述問題,我們設計了這套溫控自動風扇系統。本系統采用高精度集成溫度傳感器,用單片機控制,能顯示實時溫度,并根據使用者設定的溫度自動在相應溫度時作出小風、大風、停機動作,精確度高,動作準確。


一、系統概述


1.1  AT89C52單片機簡介

AT89C52是美國ATMEL公司生產的低電壓、高性能CMOS8位單片機,片內4bytes的可反復擦寫的只讀程序存儲器(PEROM)和128 bytes的隨機存取數據存儲器(RAM),器件采用ATMEL公司的高密度、非易失性存儲技術生產,兼容標準MCS-51指令系統,片內置用8位中央處理器(CPU)和Flash存儲單元,功能強大。STC89C52單片機可靈活應用于各種控制領域。

STC89C52單片機提供以下標準功能:4K字節Flash閃速存儲器,128字節內部RAM,32個I/O口線,兩個16位定時、計數器,一個5向量兩級中斷結構,一個全雙工串行通信口,片內振蕩器及時鐘電路。同時,STC89C52單片機可降至0Hz的靜態邏輯操作,并支持兩種軟件可選的節電工作模式。空閑方式停止CPU的工作,但允許RAM,定時、計數器,串行通行口及中斷系統繼續工作。掉電方式保存RAM中的內容,但振蕩器停止工作并禁止其它所有部件工作直到下一個硬件復位。


1. 2  本設計任務和主要內容

本文以STC89C52單片機為核心,通過數字溫度傳感器對外界環境溫度進行數據采集,從而建立一個控制系統,使電風扇隨溫度的變化而自動調節檔位,實現“溫度高、風力大、溫度低、風力弱”的性能。另外,通過紅外發射和接收裝置及按鍵實現各種功能的啟動與關閉,并且可對各種功能實現遙控,用戶可以在一定范圍內設置電風扇的最低工作溫度,當溫度低于所設置溫度時,電風扇將自動關閉,當高于此溫度時電風扇又將重新啟動。

本設計主要內容如下:

(1)風速設為從低到高共2個檔位,可由用戶通過鍵盤設定。

(2)每當溫度低于下限值時,則電風扇風速關閉。

(3)每當溫度在下限和上限之間時,則電風扇轉速緩慢。

(4))每當溫度高于上限值時,則電風扇風速全速運轉。





二、系統原理


2.1  系統總體設計

1.005.jpg
圖1 系統總體結構框圖


2.2  控制裝置原理

傳統電風扇供電采用的是220V交流電,電機轉速分為幾個檔位,通過人工手動調整電機轉速達到改變風速的目的,亦即,每改變一次風力,必然有人參與操作,這樣就會帶來諸多不便。

本文介紹了一種基于AT89C52單片機的智能電風扇調速器的設計,該設計巧妙利用紅外線遙控技術、單片機控制技術、無級調速技術和溫度傳感技術,把智能控制技術應用于家用電器的控制中,將電風扇的電機轉速作為被控制量,由單片機分析采集到的數字溫度信號,再通過可控硅對風扇電機進行調速。從而達到無須人為控制便可自動調整風速的效果。



23  溫度檢測和顯示電路

可以選用LM324A運算放大器作為溫度傳感器,將其設計成比例控制調節器,輸出電壓與熱敏電阻的阻值成正比,但這種方案需要多次檢測后方可使采樣精確,過于煩瑣。所以我采用更為優秀的DS18B20數字溫度傳感器,它可以直接將模擬溫度信號轉化為數字信號,降低了電路的復雜程度,提高了電路的運行質量。


2.3.1  DS18B20的溫度處理方法

DS18B20是美國DALLAS半導體公司繼DS1820之后最新推出的一種改進型智能溫度傳感器。與傳統的熱敏電阻相比,它能夠直接讀出被測溫度并且可根據實際要求通過簡單的編程實現9~12位的數字值讀數方式。可以分別在93.75 ms和750 ms內完成9位和12位的數字量,并且從DS18B20讀出的信息或寫入DS18B20的信息僅需要一根口線(單線接口)讀寫,溫度變換功率來源于數據總線,總線本身也可以向所掛接的DS18B20供電,而無需額外電源,因而使用DS18B20可使系統結構更趨簡單可靠性更高。他在測溫精度、轉換時間、傳輸距離、分辨率等方面較DS1820有了很大的改進,給用戶帶來了更方便的使用和更令人滿意的效果。

DS18B20簡介:

(1)獨特的單線接口方式:DS18B20與微處理器連接時僅需要一條口線即可實現微處理器與DS18B20的雙向通訊。

(2)在使用中不需要任何外圍元件。

(3)可用數據線供電,電壓范圍:+3.0~ +5.5 V。

(4)測溫范圍:-55 ~+125 ℃。固有測溫分辨率為0.5 ℃。

(5)通過編程可實現9~12位的數字讀數方式。

(6)用戶可自設定非易失性的報警上下限值。

(7)支持多點組網功能,多個DS18B20可以并聯在惟一的三線上,實現多點測溫。

(8)負壓特性,電源極性接反時,溫度計不會因發熱而燒毀,但不能正常工作。

單線(1—wire)技術:

該技術采用單根信號線,既可傳輸時鐘,也能傳輸數據,而且是雙向傳輸。適用于單主機系統,主機能夠控制一個或多個從機設備,通過一個漏極開路或三態端口連至該數據線,以允許設備在不發送數據時能釋放該線,而讓其他設備使用。單線通常要求外接一個5K的上拉電阻,這樣當該線空閑時,其狀態為高電平。

主機和從機之間的通訊分成三個步驟:初始化單線器件、識別單線器件和單線數據傳輸。

單線1—wire協議由復位脈沖、應答脈沖、寫0、寫1、讀0、讀1,這幾種信號類型實現,這些信號中除了應答脈沖其他都由主機發起,并且所有指令和數據字節都是低位在前。

DS18B20直接將測量溫度值轉化為數字量提交給單片機,工作時必須嚴格遵守單總線器件的工作時序。

溫度值/℃                 數字輸出(二進制)               數字輸出(十六進制)
   +125                     0000 0111 1101 0000                     07D0H
+85                      0000 0101 0101 0000                     0550H
+25.625                  0000 0001 1001 0001                     0191H
+10.125                  0000 0000 1010 0010                     00A2H
+0.5                    0000 0000 0000 1000                     0008H
0                       0000 0000 0000 0000                     0000H
-0.5                     1111 1111 1111 1000                     FFF8H
-10.125                  1111 1111 0110 1110                     FF5EH
-25.625                  1111 1111 0110 1111                     FF6FH
-55                     1111 1100 1001 0000                     FC90H
表1 部分溫度值與DS18B20輸出的數字量對照表


2.3.2  溫度傳感器和顯示電路組成

本模塊用更為優秀的DS18B20作為溫度傳感器,STC89C52單片機作為處理器,配以溫度顯示作為溫度控制輸出單元。整個系統力求結構簡單,功能完善。電路圖如圖2所示。

系統工作原理如下:

DS18B20數字溫度傳感器采集現場溫度,將測量到的數據送入STC89C52單片機的P2.4口,經過單片機處理后顯示當前溫度值,并與設定溫度值的上下限值作比較,若高于設定上限值或低于設定下限值則控制電機轉速進行自動調整。

對于顯示電路,我們本有兩種方案可以實施,方案一:采用五位共陽數碼管顯示溫度,動態掃描顯示方式;方案二:采用液晶顯示屏LCD顯示溫度。

對于方案一,該方案成本低廉,顯示溫度明確醒目,在夜間也能看見,功耗極低,顯示驅動程序的編寫也相對簡單,這種顯示方式得到廣泛應用。不足的地方是掃描顯示方式是使五個LED逐個點亮,因此會有閃爍,但是人眼的視覺暫留時間為20MS,當數碼管掃描周期小于這個時間時人眼將感覺不到閃爍,因此可以通過增大掃描頻率來消除閃爍感。

對于方案二,液晶體顯示屏具有顯示字符優美,不但能顯示數字還能顯示字符甚至圖形的優點,這是LED數碼管無法比擬的。但是液晶顯示模塊價格昂貴,驅動程序復雜,從簡單實用的原則考慮,本系統采用方案一。



1.006.jpg

圖2 DS18B20溫度計原理圖




2.4  電機調速電路


對于調速電路,也有兩種方案。其一:采用變壓器調節方式,運用電磁感應原理將220V電壓通過線圈降壓到不同的電壓,控制風扇電機接到不同電壓值的線圈上可控制電機的轉速,從而控制風扇風力大小;其二:采用晶閘管構成無級調速電路。

對于方案一,由于采用變壓器改變電壓調節,有風速級別限制,不能適應人性化要求。且在變壓過程中會有損耗發熱,效率不高,發熱有不安全因素。

對于方案二,以電位器控制晶閘管的導通角大小,可實現由最大風速到關閉的無級別調速,可將風力調節在關閉無風到最大風之間的任意風力,實現“自由風”。且在調速環節中基本無電力損耗。故本系統采用方案二。

電機調速是整個控制裝置中的一個相當重要的方面。通過控制改變三極翻出的導,使輸出端電壓發生改變,從而使施加在電風扇的輸入電壓發生改變,以調節風扇的轉速,實現各檔位風速的無級調速。


2.4.1  電機調速原理

雙向可控硅的導通條件如下:

(1)陽-陰極間加正向電壓;

(2)控制極-陰極間加正向觸發電壓;

(3)陽極電流IA 大于可控硅的最小維持電流IH。

電風扇的風速從高到低設為2、1檔,每檔風速都有一個限定值。在額定電壓、額定功率下,以最高轉速運轉時,要求風葉最大圓周上的線速度不大于2150m/min。且線速度可由下列公式求得

V=πDn×103                          (1)

式(1)中,V為扇葉最大圓周上的線速度(m/min),D為扇中的最大頂端掃出圓的直徑(mm),n為電風扇的最高轉速(r/min)。

代入數據求得n5≤1555r/min,取n5=1250 r/min.又因為:

1.007.jpg

取n1=875r/min。則可得出五個檔位的轉速值:

n1=875r/min,n2=980r/min,n3=1063r/min,n4=1150 r/min,n5=1250r/min

又由于負載上電壓的有效值

u0=u1 1.008.jpg                                  (2)

式(2)中,u1為輸入交流電壓的有效值,α為控制角。解得:

  • α5=0°時,t=0ms
  • α4=23.5°時,t=1.70ms
  • α3=46.5°時,t=2.58ms
  • α2=61.5°時,t=3.43ms
  • α1=76.5°時,t=4.30ms

上述計算出的是控制角和觸發時間,當檢測到過零點時,按照所求得的觸發時間延時發脈沖,便可實現預期轉速。


2.4.2  電機控制模塊設計

本模塊電路中采用了過零雙向可控硅型光耦MOC3041M ,集光電隔離、過零檢測、過零觸發等功能于一身,避免了輸入輸出通道同時控制雙向可控硅觸發的缺陷, 簡化了輸出通道隔離2驅動電路的結構。所設計的可控硅觸發電路原理圖見圖3。其中RL即為電機負載,其工作原理是:單片機響應用戶的參數設置, 在I/ O 口輸出一個高電平, 經反向器反向后, 送出一個低電平,使光電耦合器導通, 同時觸發雙向可控硅, 使工作電路導通工作。給定時間內,負載得到的功率為:

1.009.jpg                              (3)

式中: P 為負載得到的功率( kW); n 為給定時間內可控硅導通的正弦波個數; N 為給定時間內交流正弦波的總個數; U為可控硅在一個電源周期全導通時所對應的電壓有效值(V); I 為可控硅在一個電源周期全導通時所對應的電流有效值(A)。由式(3) 可知,當U , I ,N 為定值時, 只要改變n 值的大小即可控制功率的輸出,從而達到調

節電機轉速的目的。


1.010.jpg


圖3 電機控制原理圖


三、控制器軟件設計


本系統的運行程序采用C語言編寫,采用模塊化設計,整體程序由主程序和顯示、鍵盤掃描、紅外線接收以及電機控制等子程序模塊組成。


3.1  主程序

在主程序進行初始化后,開始反復檢測各模塊相關部分的緩沖區的標志,如果緩沖區置位,說明相應的數據需要處理,然后主程序調用相應的處理子模塊。如圖7所示。

1.011.jpg 圖7 主程序模塊流程圖

3.2  數字溫度傳感器模塊和顯示子模塊

1.012.jpg 如圖8所示,主機控制DS18B20數字溫度傳感器完成溫度轉換工作必須經過三個步驟:初始化、ROM操作指令、存儲器操作指令。單片機所用的系統頻率為12MHz。

根據DS18B20數字溫度傳感器進行初始化時序、讀時序和寫時序分別可編寫3個子程序:初始化子程序、寫子程序、讀子程序。

圖8 數字溫度傳感器模塊程序流程圖




DS18B20芯片功能命令表如下:

命令                                         說明                        協議
READ ROM                                讀取激光ROM64位                  33H
MATCHROM                                   匹配ROM                     55H
SKIP ROM                                      跳過ROM                     CCH
SEARCH ROM                                   搜索ROM                     F0H
ALARM SEARCH                                告警搜索                      ECH
WRITE SCRATCHPAD                  把字節寫入暫存器的地址2和3            4EH
READ SCRATCHPAD                     讀取暫存器和CRC字節                 BEH
COPY SCRATCHPAD                 把暫存器內容拷貝到非易失性存儲器中        48H
CONVERT T                                  開始溫度轉換                    44H
RECALL E2                          把非易失性存儲器中的值召回暫存器          B8H
READ POWER SUPPLY           讀電源供電方式:0為寄生電源,1為外電源       B4H

表2  DS18B20功能命令表


3.3  電機調速與控制子模塊

本模塊采用雙向可控硅過零觸發方式,由單片機控制雙向可控硅的通斷,通過改變每個控制周期內可控硅導通和關斷交流完整全波信號的個數來調節負載功率,進而達到調速的目的。

因為INT0信號反映工頻電壓過零時刻,所以只要在外中斷0的中斷服務程序中完成控制門的開啟與關閉,并利用中斷服務次數對控制量n進行計數和判斷,即每中斷一次,對n進行減1計數,如果n不等于0,保持控制電平為“1”,繼續打開控制門;如n=0,則使控制電平復位為“0”,關閉控制門,使可控硅過零觸發脈沖不再通過。這樣就可以按照控制處理得到的控制量的要求,實現可控硅的過零控制,從而達到按控制量控制的效果,實現速度可調。

(1)中斷服務程序:執行中斷服務程序時,首先保護現場,INT0中斷標志置位,禁止主程序修改工作參數,然后開始減1計數,判斷是否關斷可控硅,最后INT0中斷標志位清零,還原初始化數據,恢復現場,中斷返回。(設1秒鐘通過波形數N=100)

(2)回路控制執行程序:主回路控制執行程序的任務是初始化數據存儲單元,確定

1.013.jpg 電機工作參數nmin/nmax,并將其換算成“有效過零脈沖”的個數;確定中斷優先級、開

中斷,為了保證正弦波的完整,工頻過零同步中斷INT0確定為高一級的中斷源。


圖9 電機控制模塊中斷響應流程圖








結 束 語

本系統以STC89C52單片機為核心,單片機主要完成對外界環境溫度信號的采集、處理、顯示等功能;用Altium Designer 6軟件繪制電路原理圖和PCB電路印刷板圖,由Protues軟件進行訪真測試,利用MCS-51 C語言編制。

運行程序該系統的主要特點是:

(1)適用性強,用戶只需對界面參數進行設置并啟動系統正常運行便可滿足不同用戶對最適合溫度的要求,實現對最適溫度的實時監控。

(2)隨時可以根據軟件編寫新的功能加入產品。操作界面可擴展性強,只要稍加改變,即可增加其他按鍵的使用功能。

本系統溫度控制采用DS18B20數字溫度傳感器作為感溫元件。可控硅串接在電源與負載電風扇,借改變定周期內可控硅的導通與截止時間之比來實現調速功能,其設計完使用方便就,適應人們睡辦公等不同場合的使用。

基于STC89C52單片機所設計與研制的電風扇智能調速系統,造價低且具有穩定性高、性能優越、節約電能等優點,在夜間無需定時,同樣能給人們帶來更多的方便。

本設計在模擬檢測中運行較好,但采樣據不太穩定。功能上的缺憾是對于兩個檔之間的臨界溫度處理不好,并且檔位太少,還有待改進。





附錄一


數字溫度傳感器模塊和顯示子模塊程序:

  1. #include<reg52.h>                        //調用單片機頭文件

  2. #define uchar unsigned char  //無符號字符型 宏定義              變量范圍0~255

  3. #define uint  unsigned int              //無符號整型 宏定義              變量范圍0~65535

  4. #include "eeprom52.h"



  5. //數碼管段選定義      0     1    2    3    4    5              6              7                8                 9            

  6. uchar code smg_du[]={0x28,0xee,0x42,0x52,0xe5,0xa8,0x41,0xe7,0x20,0xa0,

  7.                                                                         0x60,0x25,0x39,0x26,0x31,0x71,0xff};              //斷碼

  8. //數碼管位選定義

  9. uchar code smg_we[]={0xef,0xdf,0xbf,0x7f};

  10. uchar dis_smg[8] = {0x28,0xee,0x32,0xa2,0xe4,0x92,0x82,0xf8};            

  11. uchar smg_i = 3;    //顯示數碼管的個位數

  12. sbit dq   = P2^4;              //18b20 IO口的定義



  13. bit flag_lj_en;                            //按鍵連加使能

  14. bit flag_lj_3_en;              //按鍵連3次連加后使能  加的數就越大了

  15. uchar key_time,key_value;      //用做連加的中間變量

  16. bit key_500ms  ;

  17. sbit pwm = P2^3;

  18. uchar f_pwm_l ;                //越小越暗



  19. uint temperature ;  //

  20. bit flag_300ms ;

  21. uchar menu_1;       //菜單設計的變量

  22. uint t_high = 300,t_low = 100;                 //溫度上下限報警值



  23. /***********************1ms延時函數*****************************/

  24. void delay_1ms(uint q)

  25. {

  26.               uint i,j;

  27.               for(i=0;i<q;i++)

  28.                             for(j=0;j<120;j++);

  29. }



  30. /***********************小延時函數*****************************/

  31. void delay_uint(uint q)

  32. {

  33.               while(q--);

  34. }





  35. /***********************數碼顯示函數*****************************/

  36. void display()

  37. {

  38.               static uchar i;  

  39.               i++;

  40.               if(i >= smg_i)

  41.                             i = 0;            

  42.               P1 = 0xff;                                          //消隱

  43.               P3 = smg_we[i];                                          //位選

  44.               P1 = dis_smg[i];                            //段選                     



  45. }



  46. /******************把數據保存到單片機內部eepom中******************/

  47. void write_eeprom()

  48. {

  49.               SectorErase(0x2000);

  50.               byte_write(0x2000, t_high % 256);

  51.               byte_write(0x2001, t_high / 256);

  52.               byte_write(0x2002, t_low % 256);

  53.               byte_write(0x2003, t_low / 256);

  54.               byte_write(0x2055, a_a);            

  55. }



  56. /******************把數據從單片機內部eepom中讀出來*****************/

  57. void read_eeprom()

  58. {

  59.               t_high  = byte_read(0x2001);

  60.               t_high <<= 8;

  61.               t_high  |= byte_read(0x2000);

  62.               t_low   = byte_read(0x2003);

  63.               t_low <<= 8;

  64.               t_low   |= byte_read(0x2002);

  65.               a_a      = byte_read(0x2055);

  66. }



  67. /**************開機初始化保存的數據*****************/

  68. void init_eeprom()

  69. {

  70.               read_eeprom();                            //先讀

  71.               if(a_a != 22)                            //新的單片機初始單片機內問eeprom

  72.               {

  73.                             t_high = 320;

  74.                             t_low  = 280;

  75.                             a_a = 22;

  76.                             write_eeprom();                 //保存數據

  77.               }            

  78. }





  79. /***********************18b20初始化函數*****************************/

  80. void init_18b20()

  81. {

  82.               bit q;

  83.               dq = 1;                                                        //把總線拿高

  84.               delay_uint(1);                  //15us

  85.               dq = 0;                                                        //給復位脈沖

  86.               delay_uint(80);                            //750us

  87.               dq = 1;                                                        //把總線拿高 等待

  88.               delay_uint(10);                            //110us

  89.               q = dq;                                                        //讀取18b20初始化信號

  90.               delay_uint(20);                            //200us

  91.               dq = 1;                                                        //把總線拿高 釋放總線

  92. }



  93. /*************寫18b20內的數據***************/

  94. void write_18b20(uchar dat)

  95. {

  96.               uchar i;

  97.               for(i=0;i<8;i++)

  98.               {                                                                      //寫數據是低位開始

  99.                             dq = 0;                                          //把總線拿低寫時間隙開始

  100.                             dq = dat & 0x01; //向18b20總線寫數據了

  101.                             delay_uint(5);              // 60us

  102.                             dq = 1;                                          //釋放總線

  103.                             dat >>= 1;

  104.               }            

  105. }



  106. /*************讀取18b20內的數據***************/

  107. uchar read_18b20()

  108. {

  109.               uchar i,value;

  110.               for(i=0;i<8;i++)

  111.               {

  112.                             dq = 0;                                          //把總線拿低讀時間隙開始

  113.                             value >>= 1;              //讀數據是低位開始

  114.                             dq = 1;                                          //釋放總線

  115.                             if(dq == 1)                            //開始讀寫數據

  116.                                           value |= 0x80;

  117.                             delay_uint(5);              //60us              讀一個時間隙最少要保持60us的時間

  118.               }

  119.               return value;                            //返回數據

  120. }



  121. /*************讀取溫度的值 讀出來的是小數***************/

  122. uint read_temp()

  123. {

  124.               uint value;

  125.               uchar low;                                             //在讀取溫度的時候如果中斷的太頻繁了,就應該把中斷給關了,否則會影響到18b20的時序

  126.               init_18b20();                               //初始化18b20

  127.               EA = 0;

  128.               write_18b20(0xcc);                 //跳過64位ROM

  129.               write_18b20(0x44);                 //啟動一次溫度轉換命令

  130.               EA = 1;

  131.               delay_uint(50);                               //500us



  132.               init_18b20();                               //初始化18b20

  133.             

  134.               EA = 0;

  135.               write_18b20(0xcc);                 //跳過64位ROM

  136.               write_18b20(0xbe);                 //發出讀取暫存器命令

  137.             

  138.               low = read_18b20();                 //讀溫度低字節

  139.               value = read_18b20();  //讀溫度高字節

  140.               EA = 1;

  141.               value <<= 8;                               //把溫度的高位左移8位

  142.               value |= low;                               //把讀出的溫度低位放到value的低八位中

  143.               value *= 0.625;                     //轉換到溫度值 小數

  144.               return value;                               //返回讀出的溫度 帶小數

  145. }



  146. /*************定時器0初始化程序***************/

  147. void time_init()               

  148. {

  149.               EA   = 1;                              //開總中斷

  150.               TMOD = 0X11;                //定時器0、定時器1工作方式1

  151.               ET0  = 1;                              //開定時器0中斷

  152.               TR0  = 1;                              //允許定時器0定時



  153.               ET1  = 1;                              //開定時器0中斷

  154.               TR1  = 0;                              //允許定時器0定時

  155. }



  156. /********************獨立按鍵程序*****************/

  157. uchar key_can;              //按鍵值



  158. void key()              //獨立按鍵程序

  159. {

  160.               static uchar key_new;

  161.               key_can = 20;                   //按鍵值還原

  162.               P2 |= 0x07;

  163.               if((P2 & 0x07) != 0x07)                            //按鍵按下

  164.               {

  165.                             if(key_500ms == 1)              //連加

  166.                             {

  167.                                           key_500ms = 0;

  168.                                           key_new = 1;

  169.                             }

  170.                             delay_1ms(1);                                 //按鍵消抖動

  171.                             if(((P2 & 0x07) != 0x07) && (key_new == 1))

  172.                             {                                                                                    //確認是按鍵按下

  173.                                           key_new = 0;

  174.                                           switch(P2 & 0x07)

  175.                                           {

  176.                                                         case 0x06: key_can = 3; break;                 //得到k2鍵值

  177.                                                         case 0x05: key_can = 2; break;                 //得到k3鍵值

  178.                                                         case 0x03: key_can = 1; break;                 //得到k4鍵值

  179.                                           }

  180.                                           flag_lj_en = 1;              //連加使能

  181.                             }                                         

  182.               }

  183.               else

  184.               {

  185.                             if(key_new == 0)

  186.                             {

  187.                                           key_new = 1;

  188.                                           write_eeprom();                            //保存數據

  189.                                           flag_lj_en = 0;                            //關閉連加使能

  190.                                           flag_lj_3_en = 0;              //關閉3秒后使能

  191.                                           key_value = 0;                            //清零

  192.                                           key_time = 0;

  193.                                           key_500ms = 0;

  194.                             }

  195.               }            

  196. }



  197. /****************按鍵處理數碼管顯示函數***************/

  198. void key_with()

  199. {

  200.               if(key_can == 1)                //設置鍵

  201.               {

  202.                             f_pwm_l = 30;

  203.                             menu_1 ++;

  204.                             if(menu_1 >= 3)

  205.                             {

  206.                                           menu_1 = 0;

  207.                                           smg_i = 3;                              //數碼管顯示3位

  208.                             }

  209.               }

  210.               if(menu_1 == 1)                                          //設置高溫報警

  211.               {

  212.                             smg_i = 4;                              //數碼管顯示4位

  213.                             if(key_can == 2)

  214.                             {

  215.                                           if(flag_lj_3_en == 0)

  216.                                                         t_high ++ ;                            //按鍵按下未松開自動加三次            

  217.                                           else

  218.                                                         t_high += 10;              //按鍵按下未松開自動加三次之后每次自動加10

  219.                                           if(t_high > 990)

  220.                                                         t_high = 990;

  221.                             }

  222.                             if(key_can == 3)

  223.                             {

  224.                                           if(flag_lj_3_en == 0)

  225.                                                         t_high -- ;                            //按鍵按下未松開自動減三次            

  226.                                           else

  227.                                                         t_high -= 10;              //按鍵按下未松開自動減三次之后每次自動減10

  228.                                           if(t_high <= t_low)

  229.                                                         t_high = t_low + 1;

  230.                             }

  231.                             dis_smg[0] = smg_du[t_high % 10];                         //取小數顯示

  232.                             dis_smg[1] = smg_du[t_high / 10 % 10] & 0xdf;  //取個位顯示

  233.                             dis_smg[2] = smg_du[t_high / 100 % 10] ;                 //取十位顯示

  234.                             dis_smg[3] = 0x64;              //H

  235.               }            

  236.               if(menu_1 == 2)                                          //設置低溫報警

  237.               {

  238.                             smg_i = 4;                              //數碼管顯示4位

  239.                             if(key_can == 2)

  240.                             {

  241.                                           if(flag_lj_3_en == 0)

  242.                                                         t_low ++ ;                                          //按鍵按下未松開自動加三次            

  243.                                           else

  244.                                                         t_low += 10;                            //按鍵按下未松開自動加三次之后每次自動加10

  245.                                           if(t_low >= t_high)

  246.                                                         t_low = t_high - 1;

  247.                             }

  248.                             if(key_can == 3)

  249.                             {

  250.                                           if(flag_lj_3_en == 0)

  251.                                                         t_low -- ;                                          //按鍵按下未松開自動減三次            

  252.                                           else

  253.                                                         t_low -= 10;                            //按鍵按下未松開自動加三次之后每次自動加10

  254.                                           if(t_low <= 10)

  255.                                                         t_low = 10;

  256.                             }

  257.                             dis_smg[0] = smg_du[t_low % 10];                         //取小數顯示

  258.                             dis_smg[1] = smg_du[t_low / 10 % 10] & 0xdf;   //取個位顯示

  259.                             dis_smg[2] = smg_du[t_low / 100 % 10] ;                     //取十位顯示

  260.                             dis_smg[3] = 0x3D;                //L

  261.               }            

  262. }



  263. /****************風扇控制函數***************/

  264. void fengshan_kz()

  265. {

  266. //              static uchar value;

  267.               if(temperature >= t_high)                //風扇全開

  268.               {            

  269.                             TR1 = 1;

  270.                             pwm = 0;

  271.               }

  272.               else if((temperature < t_high)              && (temperature >= t_low))                               //風扇緩慢

  273.               {

  274.                             f_pwm_l = 60;              

  275.                             TR1 = 1;

  276.               }

  277.               else if(temperature < t_low)              //關閉風扇

  278.               {

  279.                             TR1 = 0;

  280.                             pwm = 1;

  281.               }                                         

  282. }

  283.                            



  284. /****************主函數***************/

  285. void main()

  286. {

  287.               time_init();                    //初始化定時器

  288.               temperature = read_temp();                            //先讀出溫度的值            

  289.               init_eeprom();  //開始初始化保存的數據

  290.               delay_1ms(650);                                                      

  291.               temperature = read_temp();                                     //先讀出溫度的值

  292.               dis_smg[0] = smg_du[temperature % 10];              //取溫度的小數顯示

  293.               dis_smg[1] = smg_du[temperature / 10 % 10] & 0xdf; //取溫度的個位顯示

  294.               dis_smg[2] = smg_du[temperature / 100 % 10] ;                 //取溫度的十位顯示

  295.               f_pwm_l = 50;

  296.               while(1)

  297.               {                           

  298.                             key();                                                                      //按鍵程序

  299.                             if(key_can < 10)

  300.                             {

  301.                                           key_with();                                          //設置報警溫度            

  302.                             }

  303.                             if(flag_300ms == 1)                  //300ms 處理一次溫度程序

  304.                             {               

  305.                                           flag_300ms = 0;            

  306.                                           temperature = read_temp();              //先讀出溫度的值

  307.                                           if(menu_1 == 0)

  308.                                           {            

  309.                                                         smg_i = 3;

  310.                                                         dis_smg[0] = smg_du[temperature % 10];              //取溫度的小數顯示

  311.                                                         dis_smg[1] = smg_du[temperature / 10 % 10] & 0xdf; //取溫度的個位顯示

  312.                                                         dis_smg[2] = smg_du[temperature / 100 % 10] ;                 //取溫度的十位顯示

  313.                                           }

  314.                             }

  315.                             fengshan_kz();        //風扇控制函數

  316.               }

  317. }



  318. /*************定時器0中斷服務程序***************/

  319. void time0_int() interrupt 1

  320. {            

  321.               static uchar value;                                          //定時2ms中斷一次

  322.               TH0 = 0xf8;

  323.               TL0 = 0x30;     //2ms

  324.               display();                            //數碼管顯示函數

  325.               value++;               

  326.               if(value >= 150)

  327.               {

  328.                             value = 0;               

  329.                             flag_300ms = 1;

  330.               }

  331.               if(flag_lj_en == 1)                 //按下按鍵使能

  332.               {

  333.                             key_time ++;

  334.                             if(key_time >= 250) //500ms

  335.                             {

  336.                                           key_time = 0;

  337.                                           key_500ms = 1; //500ms

  338.                                           key_value ++;

  339.                                           if(key_value > 3)

  340.                                           {

  341.                                                         key_value = 10;

  342.                                                         flag_lj_3_en = 1; //3次后1.5秒連加大些

  343.                                           }                                                                                   

  344.                             }

  345.               }

  346. }



  347. /*******************定時器1用做單片機模擬PWM 調節***********************/

  348. void Timer1() interrupt 3  //調用定時器1

  349. {

  350.               static uchar value_l;

  351.               TH1=0xfe;    //    定時10ms中斷一次

  352.               TL1=0x0c;              //500us

  353.               if(pwm==1)

  354.               {

  355.                             value_l+=3;

  356.                             if(value_l > f_pwm_l)   //高電平



  357. …………限于本文篇幅 余下代碼請從51黑下載附件…………
  358. }
復制代碼
word文檔下載: 1308441054 錢子健 智能溫控風扇的設計與實現.rar (1.28 MB, 下載次數: 381)
回復

使用道具 舉報

ID:1 發表于 2018-3-7 23:09 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

無效樓層,該帖已經被刪除
ID:365127 發表于 2018-7-4 20:09 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

ID:354902 發表于 2018-7-5 20:56 | 顯示全部樓層

58行這里提示 SectorErase(0x2000);  有錯怎么回事?
回復

使用道具 舉報

ID:414431 發表于 2018-10-24 09:14 | 顯示全部樓層

好資料,51黑有你更精彩
回復

使用道具 舉報

ID:424564 發表于 2018-11-11 16:44 | 顯示全部樓層
真棒,謝謝分享
回復

使用道具 舉報

ID:428097 發表于 2018-11-17 11:39 | 顯示全部樓層
666,大神
回復

使用道具 舉報

ID:453635 發表于 2018-12-24 18:37 | 顯示全部樓層
寫的很詳細,謝謝樓主分享。對我很有啟發
回復

使用道具 舉報

10#
無效樓層,該帖已經被刪除
ID:338103 發表于 2018-12-27 18:16 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

ID:463362 發表于 2019-1-6 22:47 | 顯示全部樓層
贊一個!
回復

使用道具 舉報

ID:476354 發表于 2019-2-15 11:48 | 顯示全部樓層

寫的很詳細,謝謝樓主分享。對我很有啟發
回復

使用道具 舉報

14#
無效樓層,該帖已經被刪除
ID:492803 發表于 2019-3-17 21:21 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

ID:475713 發表于 2019-3-18 00:08 | 顯示全部樓層
厲害厲害
回復

使用道具 舉報

ID:503706 發表于 2019-4-2 22:39 | 顯示全部樓層
十分感謝啊,很好的資料
回復

使用道具 舉報

ID:507829 發表于 2019-4-9 14:00 | 顯示全部樓層
十分感謝啊,很好的資料
回復

使用道具 舉報

ID:490858 發表于 2019-4-10 17:00 | 顯示全部樓層
沒有電路圖嗎
回復

使用道具 舉報

ID:56665 發表于 2019-4-10 18:21 | 顯示全部樓層
好資料,51黑有你更精彩!!!
回復

使用道具 舉報

ID:506152 發表于 2019-4-10 22:28 | 顯示全部樓層
厲害了!
回復

使用道具 舉報

ID:515501 發表于 2019-4-18 15:07 | 顯示全部樓層
好資料,51黑有你更精彩
回復

使用道具 舉報

ID:515501 發表于 2019-4-18 15:12 | 顯示全部樓層
上傳附件

廣東海洋大學數電歷年考題-答案.pdf

641.65 KB, 下載次數: 3, 下載積分: 黑幣 -5

回復

使用道具 舉報

ID:513536 發表于 2019-4-18 16:55 來自觸屏版 | 顯示全部樓層
謝謝分享
回復

使用道具 舉報

25#
無效樓層,該帖已經被刪除
ID:706683 發表于 2020-3-12 08:57 來自觸屏版 | 顯示全部樓層
666,樓主太厲害了
回復

使用道具 舉報

27#
無效樓層,該帖已經被刪除
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产69| 日韩在线小视频 | 国产一区在线免费 | 操久久 | 欧美国产一区二区 | 欧美日本在线 | 精国产品一区二区三区四季综 | 亚州一区二区三区 | 久久国产区 | 国产精品视频网站 | www久久| 亚洲国产区 | 最新黄色在线观看 | 日韩在线精品 | 日韩av最新网址 | 亚洲成人一级片 | 亚洲九九色 | 中文字幕 在线观看 | 亚洲第一av | 国产精品自产拍在线观看蜜 | av毛片免费 | 久久精品性视频 | 精品久久久久久久久久 | 七七婷婷婷婷精品国产 | 天天操天天天干 | 久久久久黑人 | 国产精品久久久久aaaa | 国产黄色麻豆视频 | 中文字幕亚洲区一区二 | 亚洲永久免费观看 | www.一区二区三区 | 久久高清国产视频 | 欧美性一区二区三区 | 久久99精品久久久久婷婷 | 96av麻豆蜜桃一区二区 | 91精品国产麻豆 | 国产成人精品一区二区三区网站观看 | 亚洲欧洲日韩 | 欧美精品一区二区三区在线播放 | 福利片在线观看 | 中文字幕一区二区在线观看 |