標題: 基于STM32+GPRS的智能家居控制系統(tǒng)程序源碼+設計論文分享 [打印本頁]

作者: tanyu761224047    時間: 2018-10-25 09:20
標題: 基于STM32+GPRS的智能家居控制系統(tǒng)程序源碼+設計論文分享
基于STM32的智能家居系統(tǒng)設計

摘要
本文設計介紹一種以stm32 單片機為核心,設計了一套基于GPRS無線網絡的智能家居控制系統(tǒng)。該系統(tǒng)以GPRS通信為基礎、能通過無線通信技術實時監(jiān)控家居的溫濕度狀態(tài),并能自由控制家居的電器的開關操作。同時集成光強采集電路,能自動開關窗簾的功能。

本設計硬件電路結構簡單,分為控制器模塊,GPRS模塊,繼電器控制模塊,步進電機控制模塊等五大電路模塊,其中控制器選用基于cotex-m3內核的32位微控制器STM32F103R8T6。GPRS模塊選用SIM900模塊,人機交互模塊選用OLED12864模塊顯示數(shù)據,獨立鍵盤作為輸入設備,繼電器控制輸出控制家電電路開關。最終通過系統(tǒng)的測試,本設計實現(xiàn)的功能包括:窗簾電機檢測當前光照強度或者濕度情況實現(xiàn)自動開閉以及本地按鍵控制開閉、GSM短信遠程控制繼電器的開閉、室內溫度異常時的GSM短信通知。

Design of Intelligent Home System Based on STM32
Abstract:This paper introduces a kind of intelligent home control system based on GPRS wireless network with stm32 single chip as the core. The system based on GPRS communication, wireless communication technology can be real-time monitoring of home temperature and humidity status, and can freely control the home electrical switch operation, the use of stm32 internal calendar to achieve effective time management of household appliances, while integrated light Acquisition circuit, can automatically switch the function of the window.
The design of the hardware circuit is simple, divided into controller module, GPRS module, relay control module, stepper motor control module and other five circuit modules, including controller based on cotex-m3 core 32-bit microcontroller STM32F103R8T6. GPRS module selection SIM900 module, human-computer interaction module selection OLED12864 module display data, independent keyboard as input device, relay control output control home appliance circuit switch. Finally, through the system test, the design of the realization of the functions include: the curtain motor to detect the current light intensity or humidity to achieve automatic opening and closing and local key control open and close, GSM SMS remote control relay opening and closing, indoor temperature abnormal GSM SMS notification

目錄
第1章  前言
1.1 課題研究的背景和實際意義
1.1.1課題背景
1.1.2實際意義
1.2國內外發(fā)展現(xiàn)狀、存在問題以及前景
1.2.1發(fā)展現(xiàn)狀
1.2.2存在問題
1.2.3發(fā)展前景
1.3 主要工作、內容安排及預期成果
1.3.1主要研究工作
1.3.2預期成果
第2章 總體設計方案
2.1 系統(tǒng)總體方案設計
2.2 系統(tǒng)方案選擇
2.2.1 無線通訊方案選擇
2.2.2              顯示器方案選擇
第3章 系統(tǒng)硬件設計
3.1 控制單元模塊
3.2 人機交互模塊
3.3 GPRS電路設計
3.4 溫濕度傳感器電路設計
3.5 光強檢測電路設計
3.6 窗簾控制電路設計
3.6.1 步進電機的選用
3.6.2 步進電機28BYJ-48介紹
3.6.3 步進電機驅動
3.7 繼電器驅動電路設計
3.8 電源電路設計
第4章 系統(tǒng)軟件設計
4.1 軟件開發(fā)環(huán)境介紹
4.2 軟件總體設計
4.2.1 程序結構分析
4.2.2 主程序設計
4.2.3 OLED驅動程序分析
4.2.4 SIM900通信程序設計
第5章  系統(tǒng)調試與結果分析
5.1 程序仿真設計
5.2 實物調試
結論
致謝
參考文獻

第1章 前 言
1.1 課題研究的背景和實際意義

1.1.1 課題背景

智能家居是在以原有傳統(tǒng)住宅為基礎,添加了網絡通信、智控家電、大規(guī)模傳感網絡等模塊設施的新型居住環(huán)境。這種新型家居環(huán)境的特點是集服務、系統(tǒng)控制、設施為一體,優(yōu)點是舒適便捷、安全環(huán)保。系統(tǒng)既包含分布家居各個部位和設備上的傳感器網絡系統(tǒng),還包括中央控制系統(tǒng)、計算機網絡系統(tǒng)和網絡通信系統(tǒng)。用戶通過手機、電腦等終端設備以及網絡通信系統(tǒng)實現(xiàn)對室內家電進行本地或遠程控制。智能家居系統(tǒng)通常可以實現(xiàn)監(jiān)控功能:室內煙霧、煤氣檢測及門窗監(jiān)控等;遠程控制功能:開閉家電、遠程收水電費等。智能家居具有可定制性,即可根據不同客戶的家居需求、預算及住房條件來設計不同的設計方案。
在20世紀80年代初,在美國業(yè)內就提出了Smart Home的概念,即智能家居的原型。然而在很長一段時間內沒有具體的建筑案例問世。直到1984年,在建設美國康涅狄格州(Connecticut)哈特佛市(Hartford)的CityPlaceBuilding時,美國聯(lián)合科技公司(United Technologies Building System)把建筑設備信息化、智控化應用于這項工程,才出現(xiàn)了第一項的“智能化建筑”工程,由此將智能家居行業(yè)的發(fā)展和需求推到了全世界面前。
1.1.2 實際意義

經濟的飛速發(fā)展使人們對家居環(huán)境的要求日趨上漲與當前智能家居所產生的發(fā)展瓶頸形成尖銳的矛盾,將迫切地驅使智能家居技術有進一步的飛躍。本課題的實際意義就在于通過對智能家居控制系統(tǒng)的了解及基礎應用,有助于讀者的智能家居概念啟蒙和深入理解,激發(fā)讀者對智能家居控制系統(tǒng)的研究興趣。其次,從工程意義上講,本文所介紹的基于stm32控制器的和GPRS網絡通信控制的家居環(huán)境監(jiān)測及家居電器開關控制系統(tǒng)是在一定程度可用于實踐的,以此來滿足人們生活的多樣化需要,提升人們的生活質量。
1.2 國內外發(fā)展現(xiàn)狀、存在問題以及前景

1.2.1 發(fā)展現(xiàn)狀

國際市場上看,由于發(fā)展開始較早且大量的研發(fā)資源投入,美國以及一些歐洲國家在智能家居研發(fā)技術和市場比例一直走在世界前列。而發(fā)展近期,歐美一些頂尖研發(fā)公司投入到智能家居市場中來,極大地推動了智能家居的發(fā)展進程,同時也上線了一些可規(guī)模生產的實用項目。如“夢幻之家”、“居所之門”、“家庭主任”等。除此之外,亞太地區(qū)日、韓、新等國的相關前沿企業(yè)也正為智能家居研發(fā)作大規(guī)模投入。
而國內,信息化的春風走進了千家萬戶為中國智能家居的發(fā)展能追上國際發(fā)展腳步提供了可能。進年來,國家也越來越注重國內智能家居的發(fā)展。但由于我國智能家居發(fā)展起步較晚,還尚未形成合理統(tǒng)一的國家標準,所以還需克服很多標準上技術上的難關。目前,國內智能家居市場也開發(fā)出了以海爾企業(yè)的e家庭和清華同方企業(yè)的e-home為代表的智能家居產品。
1.2.2 存在問題

目前存在的智能家居系統(tǒng)產品自身性能與消費者的要求相去甚遠,這樣的矛盾在很大程度阻礙了智能家居的發(fā)展。具體情況如下:
①人們對于智能家居的期望過大導致智能家居功能過于理想化。而廣告商對智能家居不切實際的宣傳加劇了這一現(xiàn)象。在技術落后的發(fā)展現(xiàn)狀面前,這就形成了一個形式大于實際效果的尖銳矛盾。
②智能家居行業(yè)還沒有建立起統(tǒng)一的標準和協(xié)議。智能家居的各個研發(fā)行業(yè)均開發(fā)了屬于自己產品的協(xié)議標準,這樣導致各產品整合、關聯(lián)時出現(xiàn)不兼容的現(xiàn)象。所以,要綜合各研發(fā)行業(yè)的成果來進一步推進智能家居的發(fā)展必須建立統(tǒng)一的標準協(xié)議。
③作為新穎的研發(fā)行業(yè),智能家居的發(fā)展是建立在大量科研前沿的技術和成果上的,所以要大規(guī)模發(fā)展智能家居必然導致巨額的推廣和普及成本。要想使智能家居大規(guī)模普及實用,價格問題不同忽視。
1.2.3 發(fā)展前景

曾幾何時,智能家居僅僅是一個寄托了人們對未來生活想象的抽象概念。而時至今日,在科技發(fā)展的推動下,人們生活品質在一波又一波的智能浪潮中獲得提升。如今,智能家居行業(yè)已經處于快速發(fā)展軌道且效用日益在人們生活中擴大化,但前文中提到的當下出現(xiàn)的問題決定了智能家居行業(yè)還有很長的路要走,并且這條路會越走越寬,前景大好。
放眼于國內,自從引入智能家居以來,由于諸多原因,國內智能家居行業(yè)發(fā)展一直不慍不火。目前國內行業(yè)正進入了一個發(fā)展期的臨界點,領頭企業(yè)所推出的相關智能產品一直處于爭議狀態(tài),而市場消費觀念還尚未形成。但在未來發(fā)展中,消費者認知的提高和觀念的轉變以及相關政策的鼓勵一定會大大地推進智能家居的發(fā)展。除此之外,現(xiàn)代網絡技術、電子信息科學技術及物聯(lián)網技術的發(fā)展與成熟,也將給傳統(tǒng)智能家居提供源源不斷的發(fā)展動力,為其指明發(fā)展變革的道路。
1.3 主要工作、內容安排及預期成果

1.3.1 主要研究工作

消費者們對于智能家居呈現(xiàn)出一種多樣化的迫切性需求,一方面是居住環(huán)境的安全性,體現(xiàn)在門窗安全、煤氣泄漏及火災隱患自動報警等要求;另一方面是居住環(huán)境的舒適便捷性,體現(xiàn)在無線通信的控制方式、室內燈光以及直觀性人機交互操作等方面。
在了解到消費者對智能家居實質性需求的基礎上,結合本人自身的開發(fā)能力,本課題最終確定研究的簡易智能家居控制系統(tǒng)涵蓋了如下幾個模塊:傳感器模塊、控制器模塊,GPRS通訊模塊,繼電器輸出控制模塊,顯示器模塊等五大電路模塊。本系統(tǒng)主要是側重點是在遠程報警(室內溫度異常時,通過GPRS通訊模塊向手機發(fā)送報警短信)和遠程控制(需要時,遠程終端通過GPRS通訊模塊向本地控制器發(fā)送控制指令,控制繼電器開閉)方面。除此之外,還有窗簾根據光照強度自動開閉以及本地按鍵執(zhí)行中斷控制(應用于特殊情況,如自動控制出錯時)。
1.3.2預期成果

通過本系統(tǒng)設計各個模塊的搭建,預計能夠實現(xiàn)如下功能:
1、本地溫度濕度報警器實時監(jiān)測室內情況,當溫度異常時發(fā)送室內實時數(shù)據到設定手機上;測量范圍為濕度:20~90%RH;溫度:0~50℃。所以本設計使用范圍廣泛,既可用于氣候干燥的北方,也可用于較為濕潤的南方;既可適用于工地環(huán)境,也可用于嬰兒房環(huán)境;
2、窗簾的自動控制和按鍵控制(本設計中用電機正反轉表示窗簾的開閉),這個功能解決了用戶頻繁手動打開窗簾的麻煩。日常生活中,當遇到有強光的晴天,本設計的窗簾則能自動關閉,減少用戶親自打開窗簾的麻煩,遇到相反情況則相反處理。此外設計的按鍵控制窗簾,也可減少用戶手撥窗簾的不便;
3、手機發(fā)送控制指令的短信到GPRS通訊模塊,實現(xiàn)繼電器的開閉。本設計用兩個發(fā)光二極管代替所控制的家電,實際應用中,可通過繼電器控制空調、電飯煲等家用電器。例如炎炎夏季,空調制冷需要一定時間,用戶在回家前提前遠程控制空調打開,回家即可享受到冰爽的體驗。

第2章 總體設計方案2.1 系統(tǒng)總體方案設計
本設計硬件電路結構包含6個部分,分別是STM32控制器、輸入部分、輸出部分、電源模塊、環(huán)境探測、SIM900無線通訊。其中控制器選用32位微控制器STM32F103R8T6OLED顯示器;輸入部分包含按鍵輸入、SMS指令輸入;輸出部分包含0.96寸12864 OLED顯示器、繼電器輸出、窗簾控制輸出;環(huán)境探測包含一體化溫濕度檢測模塊DHT11、光強檢測4線制光敏傳感器模塊。結構框圖如下圖1.1所示。
光強檢測選用的是光感電阻傳感器模塊,可輸出模擬量(電壓)至STM32控制器處理后由OLED顯示器顯示出當前光照強度,同時輸出經比較器LM393比較后輸出的開關量(0或1)至STM32來控制窗簾的開關從而控制家居的通光率。在系統(tǒng)接通電源開始運行后,控制器通過串口訪問SIM900通訊模塊,不斷判斷是否收到綁定手機發(fā)送的短信指令,若接受到有效命令則解析指令控制繼電器的開閉,從而達到控制家電開閉的目的。在系統(tǒng)工作過程中,溫濕度傳感器DHT11不斷采集環(huán)境的實時溫濕度并通過串口送入控制器。設置閾值來判別正常和異常情況,當發(fā)現(xiàn)異常時觸發(fā)SIM900模塊向設定手機號發(fā)送狀態(tài)信息。此外,系統(tǒng)通過按鍵掃描的方式實現(xiàn)人機交互,控制器響應按鍵輸入同時控制OLED顯示各類相關數(shù)據信息。
2.2 系統(tǒng)方案選擇2.2.1 遠程通信方案選擇
方案一、以太網,F(xiàn)如今,光纖和寬帶的大規(guī)模建設和普及使無線網絡幾乎已經覆蓋了城市絕大部分區(qū)域。所以使用智能終端直接通過wifi網絡通信實現(xiàn)遠程控制家居電器不得不算是一種可行的方法。
方案二、GPRS網絡。利用已建立的GPRS通信網絡,通過收發(fā)短信訊息和指令來完成遠程的人機交互。
相較之下,互聯(lián)網絡明顯的弊端是是節(jié)點的生產成本高;其次,單一wifi網絡覆蓋十分有限,且網絡穩(wěn)定性并不確定,會給系統(tǒng)帶來不穩(wěn)定因素;再者,由于互聯(lián)網涉及的控制環(huán)節(jié)較多,實現(xiàn)的技術要求更高、難度更大。相較于互聯(lián)網絡,支持手機通訊的GPRS網絡有著更為廣泛的覆蓋率。根據中國移動公司公示的統(tǒng)計數(shù)據,中國的GPRS網絡覆蓋率已經達到98%以上。所以,借由GPRS為載體網絡的家居控制更具可行性和可推廣性。而且GPRS成本更低,技術水平要求更低。因此本設計選擇以GPRS網絡的方式實現(xiàn)無線通信。
2.2.2 顯示器方案選擇
方案一:七段數(shù)碼管顯示;
方案二:OLED液晶屏顯示。
相較之下,LED的優(yōu)點是硬件設計簡單,成本相對較低,但缺點是只能顯示數(shù)字而不能顯示字符,不能實現(xiàn)更為復雜多樣的功能。當顯示大數(shù)據時,需要使用另外的編碼器進行設計,占用了大量的軟件資源。而OLED的優(yōu)點是節(jié)省電能、顯示功能廣泛、攜帶方便易封裝、可視角度大。最大支持64個字符顯示,4行顯示,每行16字符。自帶字體庫,并且支持所有ASCII碼。一般采用SPI數(shù)據通訊方式,可將主控器的I/O端直接接入OLED的端口即可實現(xiàn)數(shù)據顯示,并保存當前顯示狀態(tài)。因此綜合考慮到本設計的實用性,選用OLED作為顯示器。

第3章 系統(tǒng)硬件設計
本設計的硬件部分包括控制單元模塊、人機交互模塊、無線通信模塊(GPRS)、執(zhí)行模塊(步進電機)、傳感器模塊(溫濕度檢測、光照檢測)
本章主要內容是將各個模塊進行拆分闡述和基本介紹。
3.1 控制單元模塊
本設計采用的控制器是一款基于arm核和cotex-m3架構技術的32位控制器。支持傳統(tǒng)Thumb和新型Thumb-2指令的譯碼器,采用三級流水線指令作業(yè)方式,內部PLL技術,最高運行頻率達72MHZ。并且內部資源豐富,內置有128K的flash,多達20K的運行RAM,集成多路定時器,12位的AD轉換器,多達9個通信接口和USB2.0接口,內嵌經出廠調教的8MHz的RC振蕩器。支持串行單線調試(SWD)和JTAG接口技術,支持睡眠、停機和待機模式,其采用ECOPACK封裝。被告廣泛應用于便攜式穿戴設備上。
主控制器及其電路是整個電路的核心,負責著整個系統(tǒng)的資源調度和計算控制。如圖3-1所示為主控制器模塊電路圖,其中主控制器型號為STM32F103R8T6,按鍵S1為復位按鍵,Y1為晶振。
本設計的晶振選用8MHz無源外部晶振,選用22P的C11,C13為起振電筒。整個外部時鐘電路為控制器提供一個8MHz的穩(wěn)定的時鐘源。再經內部配置PLL,使控制器運行在72MHZ工作頻率。為了方便起振,起振電容選用22pF。圖中Y2為萬年歷時鐘電路,BT1為萬年歷備用電池,當主機電源關閉時,自動切換到電池供電,以保證萬年歷數(shù)據不丟失。雖然本設計使用控制器的萬年歷,但硬件上留有設置口,為日常升級使用。R18為0歐電阻,可以適應吸取一些微小信號。濾除低頻噪聲使用10uF的大電容C15,濾除高頻噪聲使用104的小電容C16,電容C15,C16構成退耦濾波電路,減小電路的波動從而提高電路穩(wěn)定性。BOOT0,和BOOT1引腳均通過下拉電阻至地,使主控制器工作在用戶閃存啟動模式。復位電路由104的小電容C10和10k電阻R11構成:上電后,電容充電,STM32的RESET復位引腳高電平;充電結束,復位端RESET低電平,充電過程在STM32復位端形成下降沿脈沖實現(xiàn)復位。當按鍵S1按下后,電容端的電壓對釋放,RESET端重新出現(xiàn)高電平,松開后,C10電容重新被充電,因此RESET再次出現(xiàn)一低電平脈沖,使得MCU復位
3.2 人機交互模塊
顯示原理圖如下圖2-2所示。
人機交互模塊有按鍵和顯示分別作為輸入輸出。由于需要設定萬年歷時間,溫濕度異常報警,主機手機號等參數(shù),系統(tǒng)設定三個按鍵完成人機輸出。R20,R21,R22為上拉電阻,當按鍵彈開為,輸入至MCU引腳為高電平,當按鍵按下,由于S2另一端接地,輸入至MCU引腳變低電平。控制器通過采集輸入引腳PB8,PB9,PB10可以獲知按鍵輸入狀態(tài)。
OLED顯示器是本次設計輸出器的重要部分,采用四行顯示,顯示內容包括實時光照強度、年月時間、實時溫濕度指數(shù)、短信接受號碼、繼電器開關狀態(tài)。
OLED顯示器采用SPI數(shù)據通訊方式一共有7個引腳,1,2腳為供電引腳,3號腳為SDI腳接到MCU,PB15腳(亦為SPI2_MOSI腳),4號腳為SCL腳接至MCU的P14腳(亦為SPI2_MISO腳),5號腳為SCK接至MCU的P12腳(亦為SPI2_SCK腳),6號腳為RESET腳,由于復位電平方式與主控制器兼容,直接接至主控制器RESET端。7號腳為A0腳為數(shù)據/命令選擇口腳接至MCU的PB11腳。
3.3 GPRS電路設計
作為整個設計的無線通信模塊,GSM模塊的完備對是否能實現(xiàn)遠程控制功能有著至關重要的影響。本設計選用集成化的GSM模塊,型號是SIM900。采用標準的AT指令操作接受和發(fā)送短信指令,模塊解碼后發(fā)送至STM32主控制器執(zhí)行控制操作。本設計中最為核心的功能即是短信指令控制繼電器的開關,繼而達到遠程操控家電的目的。(本設計硬件電路中用發(fā)光二級管的開閉代替家電的開關)。
GSM使用短信指令實現(xiàn)控制,操作便捷,發(fā)送短信僅需要3條指令。GSM通信應用廣泛,目前應用短信控制開關、氣象數(shù)據監(jiān)測、全球遠距離無線通訊。本模塊支持900~1800頻段,包括中國移動與中國聯(lián)通。SIM900模塊與STM32控制器采用串口直連的方式,方便美觀。SIM900模塊包含六個引腳:GND(電源負極)、RX(模塊接收端:對應STM32的TX 端口)、TX(模塊發(fā)射端)、KEY(啟動引腳:接地釋放啟動和一直接地實現(xiàn)上電自啟)、VCC(模塊供電端:電壓范圍3.7~4.2V)。SIM900模塊連接圖見圖3-3。
3.4 溫濕度傳感器電路設計
溫濕度采集是主要的輸入信號之一,通過設定閾值來觸發(fā)GSM模塊向設定手機發(fā)送報警短信。本設計默認設定溫度閾值為40℃,默認濕度閾值為60RH。此外,可根據具體情況,通過電路板上的設置按鍵設定所需溫濕度閾值。
查閱DHT11官方數(shù)據手冊可知此檢測模塊封裝形式采用4針單排直插;測量范圍是:濕度(20-90%)、溫度(0-50℃);濕度檢測精度可到到±5%RH,溫度檢測精度可達±2℃;分辨力位1。
傳感器包含4個引腳,分別是電源引腳、串行數(shù)據總線、懸空引腳、接地引腳,其電路圖如下圖3-4所示。溫濕度傳感器供電電壓范圍為3.3V~5.5V。由于是單總線數(shù)據傳輸方式,并且通過判斷高電平時間來區(qū)分高低電平,所以此檢測模塊的優(yōu)點是數(shù)據傳輸距離長,現(xiàn)場溫濕度監(jiān)控有良好的應用效果。采用數(shù)字輸出接口經上拉電阻R22后接入STM32的PB5引腳。上拉電阻的大小是由信號線的長度來決定的,兩者呈反比關系,即信號線越長時,電阻越;信號線越短,電阻越大。
3.5 光強檢測電路設計
光強檢測電路是實現(xiàn)窗簾自動開閉重要的前端電路,本次設計采用光敏電阻式模塊化傳感器,原理圖見下圖3-5。
集成化模塊-輸出可以直接與主控制器或者A/D連接。光照強度較低時(低于預設值),傳感器的D0端輸出高電平;光照強度較高(高于預設值),傳感器的D1端輸出低電平。本設計將可采集到的光照強度劃分成20個光強等級,采集范圍從0 Lux開始,1000Lux為一個跨度,超過20000Lux只顯示等級20。本設計默認設定光強閾值為16個光強等級單位。
3.6 窗簾控制電路設計3.6.1 步進電機的選用
對步進電機和直流電機簡單比較有如下結論:
①當步進電機鎖定位置時,電機不再耗電;
②步進電機體積小、壽命長;
③步進電機成本低廉、驅動簡單;
④步進電機定位控制精確,直流電機定位控制誤差較大;
⑤驅動方式不同:步進電機驅動方法的分類主要有恒電壓驅動方式,直流電機驅動方法是有刷驅動和無刷驅動;
⑥控制方式不同:步進電機開環(huán)操作、直接控制,直流電機加反饋間接控制;
綜合分析直流電機和交流電機的優(yōu)缺點以及本設計的高精度要求,選用步進電機。且確定型號為28BYJ-48。
3.6.2 步進電機28BYJ-48介紹
首先了解型號中各位數(shù)字字母包含的具體含義:28——步進電機的有效最大外徑是 28 毫米;B——表示是步進電機;Y——表示是永磁式;J——表示是減速型;48——表示四相八拍。參數(shù)見表3-1。

表格3-1 步進電機參數(shù)

電機型號
電壓V
相數(shù)
相電阻Ω
±10%
步距角度
減速比
起動轉矩
100P.P.S
g.cm
起動頻率P.P.S
定位轉矩g.cm
摩擦轉矩g.cm
噪聲dB
絕緣介電強度
28BYJ-48
5
4
300
5.625/64
1:64
≥300
≥550
≥300
≤35
600VAC1S

3.6.3 步進電機驅動
本設計采用小型步進電機進行模擬?紤]到窗簾需要打開和關閉。其執(zhí)行電機必須實現(xiàn)正反轉控制。因此采用步進電機構成的開環(huán)控制系統(tǒng)實現(xiàn)。采用5V供電的四相步進電機作為執(zhí)行機構。采用ULN2004作為驅動器件,組成窗簾控制電路。步進電機驅動方法如下表3-2,驅動原理如下圖3-6。

表格3-2 步進電機的驅動方法

導線顏色
1
2
3
4
5
6
7
8
6紅
4橙






3黃





2粉





1藍






3.7 繼電器驅動電路設計
繼電器作為本設計的輸出控制模塊,接收STM主控制器傳輸來的高低電平信號來控制家電。設計用L1和L3的亮滅表示繼電器的開閉。驅動電路如圖3-7所示。
由于繼電器的功率較大,本設計中采用8050和8550組成達林頓管方式來驅動,它的最大集電極電流可以達到1A。繼電器線圈從通電到斷開電感電流不能突變,所以需要一個電流泄放回路。二極管Q1,Q3采用二極管IN4007對繼電器的線圈進行續(xù)流。R13,R17為限流電阻,使三極管工作在放大區(qū)。R9,L2,R14,L3構成繼電器工作指示電路。
3.8 電源電路設計
電源模塊的主要作用是為整個系統(tǒng)供電,保證系統(tǒng)工作穩(wěn)定。本系統(tǒng)需要兩種電壓:SIM900模塊工作的3.7V~4.2V、MCU的3.3V工作電壓。因此系統(tǒng)直接采用12V電壓輸入,由LM2596-ADJ芯片構成的固定頻率開關降壓穩(wěn)壓電路后,得到4.2V直流電壓,為SIM900模塊提供工作電壓. 電路中通過調節(jié)R2電阻,可調節(jié)輸出電壓。主機電源模塊電路如圖3-8所示。
線性低壓差三端穩(wěn)壓器LM1117的作用是將4.2V電壓轉換成3.3V電壓,繼而給STM32控制器、各部分傳感模塊、OLED顯示模塊等供電。大電容C5、C6的作用是濾除低頻電源紋波,小電容C7、C8的作用是濾除高頻噪聲,外加0歐電阻,使得電源抗干擾能力更強。BT1為電池,為另一種系統(tǒng)供電方式。電阻R8和二極管D2構成電源指示電路。


第4章 系統(tǒng)軟件設計
4.1 軟件開發(fā)環(huán)境介紹
本設計中選用KEIL公司推出名為MDK的編譯器。其主要指向是arm核控制器開發(fā)的集成開發(fā)環(huán)境作為主機程序設計。Keil MDK軟件為基于Cortex-M、Cortex-R4、ARM7、ARM9處理器的設備創(chuàng)造了完整的開發(fā)環(huán)境。
MDK的功能特點:
●支持的器件庫豐富,包括Cortex-M、Cortex-R4、ARM7等系列;
●可使用C/C++語言編程,使用受眾廣泛易于上手;
●小封裝實時操作系統(tǒng);
●μVision4 IDE集成開發(fā)環(huán)境,調試器和仿真環(huán)境;
●TCP/IP網絡套件提供多種的協(xié)議和各種應用;
●提供帶標準驅動類的USB 設備和USB 主機棧;
●完善的GUI庫支持;
●符合CMSIS (Cortex微控制器軟件接口標準)。
4.2 軟件總體設計4.2.1 程序結構分析
軟件設計的主要任務有:
1)從SIM900 GPRS模塊讀取短信,并進行判斷,從而對家用電器進行開關控制;
2)采集光照強度,實現(xiàn)家居光照率自動控制;
3)采集溫濕度值,判斷發(fā)生異常時,觸發(fā)短息報警通知主機;
4)讀取主控器萬年歷時鐘,對家用電器進行時間段開關管理;
5)按鍵掃描,將實時的數(shù)據信息和操作消息顯示在OLED屏上。
4.2.2 主程序設計
為了使溫濕度以及光照采集新的信息能實時地進行傳輸和處理,本設計的程序通過循環(huán)掃描對光敏電阻傳感模塊和DHT11傳感模塊進行數(shù)據采集。主程序功能實現(xiàn)系統(tǒng)的初始化,之后再進行功能模塊的運行。因而主程序需要完成的設置任務是系統(tǒng)各部分初始化、進行人機交互。主程序流程圖如圖4-1所示。
系統(tǒng)開始運行后,首先進行系統(tǒng)的初始化,包括相關系統(tǒng)參數(shù)的初始化、OLED模塊的初始化、I/O串口的配置和初始化、RTC及ADC的初始化。完成初始化后,程序開始循環(huán)掃描,首先讀取DHT11傳感器采集處理的溫濕度數(shù)據,STM32控制器進行數(shù)據分析后邏輯判斷溫濕度情況是否正常。若判斷出異常,控制器置異常標志位,控制SIM900模塊周期性向設定手機發(fā)送提醒短信。程序不斷訪問SIM900模塊,隨時準備接受短信并解碼,解碼到有效指令則控制相關模塊輸出。若對指令不予處理,程序開始進行掃描響應按鍵。程序中設置有五個按鍵輸入,其中兩個執(zhí)行中斷操作,實現(xiàn)中斷控制窗簾的開閉,其余三個按鍵輸入用于參數(shù)、模式的設置,包括溫濕度閾值設置、光照強度閾值設置。接著程序獲取萬年歷時間,若到達設定開機時間或者關機時間,則控制繼電器輸出變化。最后程序指令STM32控制器根據采集的信息控制顯示器顯示實時溫濕度值、預設定手機號碼、繼電器狀態(tài)、萬年歷時間及GSM模塊工作狀態(tài)。
4.2.3 OLED驅動分析
OLED采用SPI數(shù)據通訊協(xié)議。驅動程序關鍵在于OLED讀寫時序。本設計功能中,程序只需要實現(xiàn)實時寫入數(shù)據,用于OLED顯示,達到人機交互的目的。OLED的時序圖如圖4-2所示,對時序圖詳細分析后再模擬時序編程就能驅動顯示器了。
4.2.4 SIM900通信程序設計
SIM900模塊支持AT串口指令集,對SIM900進行訪問相當于對STM32 I/O口的訪問。所以通過AT指令,即可以實現(xiàn)控制SIM900的短信發(fā)送和讀取。下面介紹與短信發(fā)送和讀取的AT命令:AT+CMGF=?——選擇模式;AT+CMGS——發(fā)送一條SMS;AT+CMGR——讀取一條SMS;AT+CMGD ——刪除一條SMS;
在本設計中,SIM900串口通訊協(xié)議為9600波特率,8位數(shù)據位,無校驗,1位停止位。系統(tǒng)啟動后先初始化SIM900 模塊,內容包括設置短信模式、接收短信模式方式等。運行過程中,程序不斷掃描串口,當串口接收到由于接收到含有“+CMTI”字符的短信后,程序則會進入讀取短信的過程。這是由于當模塊接收到短信后,SIM900會經過串口向主控制器傳送“+CMTI: "SM",1”的命令,通過接收指令即可判斷是否接收到短信。讀取短信時,SIM900又會發(fā)送字符為“AT+CMGR=1”的指令,將信息讀出并根據信息內容判斷對繼電器的開閉操作,以此實現(xiàn)遠程家電的控制功能。

第5章  系統(tǒng)調試與結果分析
通過實際測試,本次設計出的基于stm32的智能家居系統(tǒng)能接收短息,并響應有效的命令,對繼電器進行控制,實現(xiàn)家用電器的開關控制,并且能夠根據光照強度,實現(xiàn)窗簾的自動開關,并切確地對時間響應,在設定時間段打開繼電器。
5.1 程序仿真設計
1、系統(tǒng)仿真采用仿真軟件Proteus7.0。仿真開始測試圖(lcd屏顯示初始,溫濕度感測值,狀態(tài)值)如圖5-1所示。
2、調整濕度值,濕度過高,電機反轉關窗測試圖,見下圖5-2。
5.2 實物調試
實物圖通電后,等待各個模塊啟動,在OLED顯示器上顯示當前室內環(huán)境的實時數(shù)據。
1、報警調試:用打火機提高檢測環(huán)境溫度,超過預設閾值(35℃),STM32控制GPRS模塊向設定手機(184****5651)發(fā)送報警短信,見下圖5-3。
2、窗簾控制調試:打開閃光燈增強光照傳感器探測環(huán)境光強,電機正轉表示窗簾關閉,OLED顯示器顯示窗簾關閉,見圖5-4。

3、家電開光調試:用設定手機(184****5651)向GPRS通訊模塊的手機號(155****3582)發(fā)送指令短信“2 Open”,打開繼電器2的發(fā)光二極管,見圖5-5所示。
結論

本次設計完成了一個基于STM32控制芯片的簡易智能家居系統(tǒng),其核心功能主要是實現(xiàn)實時的環(huán)境監(jiān)測并顯示,當環(huán)境溫度或者濕度超過設定值時判定為異常情況并向設定手機發(fā)送報警信息,其次實現(xiàn)光控窗簾的自動控制和按鍵控制功能,再次實現(xiàn)設定手機向GSM模塊發(fā)送控制指令打開繼電器。由于設計中所用到的核心主控制器STM32芯片以及GSM模塊都是本科期間未學習的課程,所以是本次設計工作需要大量重零學習的過程,也遇到了很多的困難。

通過本次設計, 本人不僅將以前學習的理論知識應用于實際,還對自己的動手能力有較大提升。除此之外,本人還深深意識到查閱其他相關論文文獻對于豐富自身知識和建立設計思路的重要性。所以,檢索文獻資料對于我們也是相當重要的技能。而經過這次畢業(yè)設計,也學會了利用網絡和圖書館等資源來幫助自己完成作品。


致謝

時間如白駒過隙,悄無聲息地從指縫中溜走。在四年大學生活的末尾,我完成了能夠證明四年青春的畢業(yè)設計和論文。至此,衷心地感謝一如既往支持我學習的家人、陪伴我成長的同學們以及孜孜不倦地指導我學習的老師們。

其次,特別感謝高雪菲老師。從選定課題開始到畢業(yè)論文定稿,高老師的嚴格要求和監(jiān)督都激勵我不斷學習和進步。在做畢業(yè)設計過程中,遇到了很多的問題,甚至曾好幾次因理解不了器件的使用方法我都萌生放棄的念頭,這時高雪菲老師不僅提供給我專業(yè)知識的幫助和設計方面的建議,還不斷鼓勵我克服困難,把遇到的困難最后轉化成工程設計的經驗。

接著,是學校和學院給提供了畢業(yè)設計這樣一個平臺來讓大家有機會綜合整理自己大學四年所學的知識并用于實踐中,所以在此也要向學校表達我的感謝。在同學們即將步入社會之際,這樣一個過程能夠提高我們的學習能力和適應工程設計開發(fā)的能力。

最后,還要感謝那些共同為畢業(yè)設計挑燈奮戰(zhàn)的同學們,你們不單單是在畢業(yè)設計中給我提供了很多寶貴意見和實質幫助。更多的是在我沮喪的時候給予的鼓勵。沒有大家,我很難獨立完成這次設計,在此真誠的感謝你們。


單片機程序源碼如下:


  1. //頭文件調用
  2. #include "usually.h"
  3. #include "usart.h"
  4. #include "oled.h"
  5. #include "dht11.h"
  6. #include "rtc.h"
  7. #include "delay.h"
  8. #include "stm32f10x_adc.h"
  9. #include <string.h>
  10. #include "BSP_Config.h"
  11. #include "gpio.h"
  12. #include "gsm.h"


  13. //宏定義
  14. #define ADC_CH0  0 //通道0
  15. #define ADC_CH1  1 //通道1
  16. #define ADC_CH2  2 //通道2
  17. #define ADC_CH3  3 //通道3        


  18. #define SEC 0
  19. #define MIN 1
  20. #define HOUR 2
  21. #define DATE 3
  22. #define MON 4
  23. #define YEAR 6

  24. #define MODE_NORMAL 0
  25. #define MODE_SET_HOUR 1
  26. #define MODE_SET_MIN 2
  27. #define MODE_SET_SEC 3
  28. #define MODE_SET_YEAR 4
  29. #define MODE_SET_MON 5
  30. #define MODE_SET_DATE 6
  31. #define MODE_SET_HUMI_HIGH 8
  32. #define MODE_SET_TEMP_HIGH 7
  33. #define MODE_SET_LIGHT 9


  34. #define KEY_MENU_IN PBin(0)
  35. #define KEY_ADD_IN PBin(1)
  36. #define KEY_SUB_IN PBin(2)

  37. //步進控制 A-AB-B-BC-C-CD-D-DA
  38. #define Motor1_A_run  { GPIO_SetBits(GPIOB,GPIO_Pin_8);  GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_ResetBits(GPIOB,GPIO_Pin_11);}
  39. #define Motor1_AB_run { GPIO_SetBits(GPIOB,GPIO_Pin_8);  GPIO_SetBits(GPIOB,GPIO_Pin_9);  GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_ResetBits(GPIOB,GPIO_Pin_11);}
  40. #define Motor1_B_run  { GPIO_ResetBits(GPIOB,GPIO_Pin_8);GPIO_SetBits(GPIOB,GPIO_Pin_9);  GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_ResetBits(GPIOB,GPIO_Pin_11);}
  41. #define Motor1_BC_run { GPIO_ResetBits(GPIOB,GPIO_Pin_8);GPIO_SetBits(GPIOB,GPIO_Pin_9);  GPIO_SetBits(GPIOB,GPIO_Pin_10);  GPIO_ResetBits(GPIOB,GPIO_Pin_11);}
  42. #define Motor1_C_run  { GPIO_ResetBits(GPIOB,GPIO_Pin_8);GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_SetBits(GPIOB,GPIO_Pin_10);  GPIO_ResetBits(GPIOB,GPIO_Pin_11);}
  43. #define Motor1_CD_run { GPIO_ResetBits(GPIOB,GPIO_Pin_8);GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_SetBits(GPIOB,GPIO_Pin_10);  GPIO_SetBits(GPIOB,GPIO_Pin_11);}
  44. #define Motor1_D_run  { GPIO_ResetBits(GPIOB,GPIO_Pin_8);GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_SetBits(GPIOB,GPIO_Pin_11);}
  45. #define Motor1_DA_run { GPIO_SetBits(GPIOB,GPIO_Pin_8);  GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_SetBits(GPIOB,GPIO_Pin_11);}
  46. #define Motor1_STOP_run { GPIO_ResetBits(GPIOB,GPIO_Pin_8);  GPIO_ResetBits(GPIOB,GPIO_Pin_9);GPIO_ResetBits(GPIOB,GPIO_Pin_10);GPIO_ResetBits(GPIOB,GPIO_Pin_11);}


  47. #define motorSpdDelayUs  1100
  48. //聲明變量
  49. extern struct Data_Time  timer;
  50. unsigned char *pUart1_Rxd;//接收數(shù)據指針
  51. unsigned int  uart1_RxNum=0;//串口1接收字數(shù)
  52. unsigned char Num_TXD=0;//串口1發(fā)送緩沖區(qū)的字節(jié)數(shù)
  53. unsigned char Uart1_TxBuf[256]={0,2,3,};//串口1發(fā)送緩沖區(qū)
  54. unsigned char Uart1_RxBuf[256]; //串口1接收緩沖區(qū)

  55. unsigned char *pUart2_Rxd;                        //串口2接收數(shù)據指針
  56. unsigned int  uart2_RxNum=0;         //串口2接收字數(shù)
  57. unsigned char uart2_TxNum=0;         //串口2發(fā)送緩沖區(qū)的字節(jié)數(shù)
  58. unsigned char Uart2_TxBuf[256]={0,2,3,};//串口2發(fā)送緩沖區(qū)
  59. unsigned char Uart2_RxBuf[256]; //串口2接收緩沖區(qū)

  60. //變量聲明
  61. //extern struct tm  timer;
  62. char line1str[17]="Welcome to use!";
  63. char line2str[17]="Wating gsm... ";
  64. char line3str[17]="              ";
  65. char line4str[17]="              ";
  66. uint8_t dht11_buf[5];
  67. uint8_t nowtemp,nowhumi;//當前溫濕度值
  68. uint8_t thalmflg;  //溫濕度過高報警
  69. uint16_t adtemp[12]={0};  //連續(xù)采集12點算平均值
  70. uint16_t light_adc,set_lit_high,lit_high;
  71. uint8_t almtmp_high,almhumi_high;
  72. uint8_t mode_status; //模式
  73. uint8_t flashflg; //模式
  74. uint8_t settimeflg;        //時間被設置標志位
  75. uint8_t solid1flg,solid2flg,winflg;
  76. unsigned char settime[8]={0x00,30,12,0x6,10,0x01,15};//??sec,min,hour,date,month,week,year
  77. char recephonenum[12]="13538510586";
  78. char phonenum_flash;
  79. uint8_t adci=0;
  80. char strLs[32];
  81. //按鍵輸入初始化
  82. void Key_init(void){
  83.         
  84.   GPIO_InitTypeDef  GPIO_InitStructure;
  85.         
  86.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);         //使能PB端口時鐘
  87.         //Configure pin Pb1 as output
  88.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                //PA13,PA14,PA15按鍵輸入
  89.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  90.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         //上拉輸入        
  91.         GPIO_Init(GPIOB,&GPIO_InitStructure);        
  92.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  93.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  94.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         //上拉輸入
  95.         GPIO_Init(GPIOB,&GPIO_InitStructure);        
  96.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  97.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  98.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         //上拉輸入
  99.         GPIO_Init(GPIOB,&GPIO_InitStructure);        

  100. }

  101. //繼電器輸出IO初始化
  102. void Solid_Init(){
  103.         
  104.   GPIO_InitTypeDef  GPIO_InitStructure;
  105.         //Configure pin Pb0 as output
  106.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  107.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  108.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽輸出
  109.         GPIO_Init(GPIOB,&GPIO_InitStructure);

  110.         //Configure pin Pb1 as output
  111.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  112.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  113.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽輸出
  114.         GPIO_Init(GPIOB,&GPIO_InitStructure);
  115. /*        GPIO_SetBits(GPIOB,GPIO_Pin_5);
  116.         GPIO_SetBits(GPIOB,GPIO_Pin_6);        
  117.         GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  118.         GPIO_ResetBits(GPIOB,GPIO_Pin_6);        */
  119. }

  120. //步進輸出IO初始化
  121. void Motor_Init(){
  122.         
  123.   GPIO_InitTypeDef  GPIO_InitStructure;
  124.         //Configure pin Pb0 as output
  125.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  126.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  127.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽輸出
  128.         GPIO_Init(GPIOB,&GPIO_InitStructure);

  129.         //Configure pin Pb1 as output
  130.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  131.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  132.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽輸出
  133.         GPIO_Init(GPIOB,&GPIO_InitStructure);
  134.                 //Configure pin Pb0 as output
  135.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  136.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  137.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽輸出
  138.         GPIO_Init(GPIOB,&GPIO_InitStructure);

  139.         //Configure pin Pb1 as output
  140.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  141.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  142.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽輸出
  143.         GPIO_Init(GPIOB,&GPIO_InitStructure);
  144.         
  145.         
  146. /*        GPIO_SetBits(GPIOB,GPIO_Pin_5);
  147.         GPIO_SetBits(GPIOB,GPIO_Pin_6);        
  148.         GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  149.         GPIO_ResetBits(GPIOB,GPIO_Pin_6);        */
  150. }

  151. //初始化ADC
  152. //這里我們僅以規(guī)則通道為例
  153. //我們默認將開啟通道0~3                                                                                                                                          
  154. void  Adc_Init(void)
  155. {   
  156.         //先初始化IO口
  157.          RCC->APB2ENR|=1<<2;    //使能PORTA口時鐘
  158.         GPIOA->CRL&=0XFFFF0000;//PA0 1 2 3 anolog輸入
  159.         //通道10/11設置                        
  160.         RCC->APB2ENR|=1<<9;    //ADC1時鐘使能         
  161.         RCC->APB2RSTR|=1<<9;   //ADC1復位
  162.         RCC->APB2RSTR&=~(1<<9);//復位結束            
  163.         RCC->CFGR&=~(3<<14);   //分頻因子清零        
  164.         //SYSCLK/DIV2=12M ADC時鐘設置為12M,ADC最大時鐘不能超過14M!
  165.         //否則將導致ADC準確度下降!
  166.         RCC->CFGR|=2<<14;               

  167.         ADC1->CR1&=0XF0FFFF;   //工作模式清零
  168.         ADC1->CR1|=0<<16;      //獨立工作模式  
  169.         ADC1->CR1&=~(1<<8);    //非掃描模式         
  170.         ADC1->CR2&=~(1<<1);    //單次轉換模式
  171.         ADC1->CR2&=~(7<<17);           
  172.         ADC1->CR2|=7<<17;           //軟件控制轉換  
  173.         ADC1->CR2|=1<<20;      //使用用外部觸發(fā)(SWSTART)!!!        必須使用一個事件來觸發(fā)
  174.         ADC1->CR2&=~(1<<11);   //右對齊         
  175.         ADC1->SQR1&=~(0XF<<20);
  176.         ADC1->SQR1&=0<<20;     //1個轉換在規(guī)則序列中 也就是只轉換規(guī)則序列1                           
  177.         //設置通道0~3的采樣時間
  178.         ADC1->SMPR2&=0XFFFFF000;//通道0,1,2,3采樣時間清空         
  179.         ADC1->SMPR2|=7<<9;      //通道3  239.5周期,提高采樣時間可以提高精確度         
  180.         ADC1->SMPR2|=7<<6;      //通道2  239.5周期,提高采樣時間可以提高精確度         
  181.         ADC1->SMPR2|=7<<3;      //通道1  239.5周期,提高采樣時間可以提高精確度         
  182.         ADC1->SMPR2|=7<<0;      //通道0  239.5周期,提高采樣時間可以提高精確度         

  183.         ADC1->CR2|=1<<0;            //開啟AD轉換器         
  184.         ADC1->CR2|=1<<3;        //使能復位校準  
  185.         while(ADC1->CR2&1<<3);  //等待校準結束                          
  186.     //該位由軟件設置并由硬件清除。在校準寄存器被初始化后該位將被清除。                  
  187.         ADC1->CR2|=1<<2;        //開啟AD校準           
  188.         while(ADC1->CR2&1<<2);  //等待校準結束
  189.         //該位由軟件設置以開始校準,并在校準結束時由硬件清除  
  190. }                                 
  191. //獲得ADC值
  192. //ch:通道值 0~3
  193. u16 Get_Adc(u8 ch)   
  194. {
  195.         //設置轉換序列                           
  196.         ADC1->SQR3&=0XFFFFFFE0;//規(guī)則序列1 通道ch
  197.         ADC1->SQR3|=ch;                                             
  198.         ADC1->CR2|=1<<22;       //啟動規(guī)則轉換通道
  199.         while(!(ADC1->SR&1<<1));//等待轉換結束                    
  200.         return ADC1->DR;                //返回adc值        
  201. }


  202. //
  203. uint16_t adc_avg(void)
  204. {
  205.   uint8_t i;
  206.         uint32_t sum=0;
  207.         uint16_t ret=0;
  208.         for(i=0;i<12;i++)  sum+=adtemp[i];
  209.         ret= sum/12;
  210.         
  211.         return ret;  
  212. }
  213. //馬達正轉開窗簾
  214. void motor_Foreward(void)
  215. {
  216.     Motor1_A_run;
  217.     delay_us(motorSpdDelayUs);
  218.     Motor1_AB_run;
  219.     delay_us(motorSpdDelayUs);
  220.     Motor1_B_run;
  221.     delay_us(motorSpdDelayUs);
  222.     Motor1_BC_run;
  223.     delay_us(motorSpdDelayUs);
  224.     Motor1_C_run;
  225.     delay_us(motorSpdDelayUs);
  226.     Motor1_CD_run;
  227.     delay_us(motorSpdDelayUs);
  228.     Motor1_D_run;
  229.     delay_us(motorSpdDelayUs);
  230.     Motor1_DA_run;
  231.     delay_us(motorSpdDelayUs);
  232. }


  233. //馬達反轉關窗簾
  234. void motor_Backward(void)
  235. {
  236.     Motor1_DA_run;
  237.     delay_us(motorSpdDelayUs);   
  238.     Motor1_D_run;
  239.     delay_us(motorSpdDelayUs);
  240.     Motor1_CD_run;
  241.     delay_us(motorSpdDelayUs);
  242.     Motor1_C_run;
  243.     delay_us(motorSpdDelayUs);
  244.     Motor1_BC_run;
  245.     delay_us(motorSpdDelayUs);
  246.     Motor1_B_run;
  247.     delay_us(motorSpdDelayUs);
  248.     Motor1_AB_run;
  249.     delay_us(motorSpdDelayUs);
  250.     Motor1_A_run;
  251.     delay_us(motorSpdDelayUs);   
  252. }



  253. //顯示設置頁面
  254. void Show_Normal(void){
  255.         //顯示溫濕度
  256.         strncpy(line1str,"tmp:99C/hm:99%RH",16);
  257.         line1str[4]=0x30+nowtemp/10;
  258.         line1str[5]=0x30+nowtemp%10;
  259.         line1str[11]=0x30+nowhumi/10;
  260.         line1str[12]=0x30+nowhumi%10;
  261.         OLED_8x16Str(0,0,line1str);        
  262.         //顯示光照強度及窗簾狀態(tài)
  263.         if(winflg){
  264.           strncpy(line2str,"lit:99 /wn:open ",16);
  265.         }else{
  266.                 strncpy(line2str,"lit:99 /wn:close",16);
  267.   }
  268.         line2str[4]=0x30+light_adc/41/10; //100%顯示
  269.         line2str[5]=0x30+light_adc/41%10;
  270.         OLED_8x16Str(0,2,line2str);        
  271.         
  272.         //顯示繼電器輸出狀態(tài)
  273.         strncpy(line3str, "s1:open s2:open ",16);
  274.         if(solid1flg) {
  275.           line3str[3]='o';line3str[4]='p';line3str[5]='e';line3str[6]='n';line3str[7]=' ';
  276.   }else{
  277.           line3str[3]='c';line3str[4]='l';line3str[5]='o';line3str[6]='s';line3str[7]='e';
  278.   }
  279.         if(solid2flg) {
  280.           line3str[11]='o';line3str[12]='p';line3str[13]='e';line3str[14]='n';line3str[15]=' ';
  281.   }else{
  282.           line3str[11]='c';line3str[12]='l';line3str[13]='o';line3str[14]='s';line3str[15]='e';
  283.   }        
  284.         
  285.         OLED_8x16Str(0,4,line3str);
  286.         
  287.         //顯示時間
  288.         //line4str[0]= 0x30+ timer.w_year%1000%100/10;        
  289.         line4str[0]= 0x30+ timer.w_year%1000%100%10;        
  290.         line4str[1]= '/';
  291.         line4str[2]= 0x30+timer.w_month/10;        
  292.         line4str[3]= 0x30+ timer.w_month%10;        
  293.         line4str[4]= '/';        
  294.         line4str[5]= 0x30+timer.w_date/10;        
  295.         line4str[6]= 0x30+ timer.w_date%10;        
  296.         line4str[7]= ' ';               
  297.         line4str[8]= 0x30+ timer.hour/10;        
  298.         line4str[9]= 0x30+ timer.hour%10;        
  299.         line4str[10]= ':';
  300.         line4str[11]= 0x30+timer.min/10;        
  301.         line4str[12]= 0x30+ timer.min%10;        
  302.         line4str[13]= ':';        
  303.         line4str[14]= 0x30+timer.sec/10;        
  304.         line4str[15]= 0x30+timer.sec%10;        
  305.         OLED_8x16Str(0,6,line4str);

  306. }
  307. /*
  308.    顯示設置頁面

  309. */
  310. void Show_SetPage(void){
  311.         uint8_t i;
  312.         //顯示溫濕度
  313.         strncpy(line1str,"tH:99C/hH:99%RH ",16);
  314.         
  315.         if(MODE_SET_TEMP_HIGH== mode_status && flashflg){
  316.                 line1str[3]=' ';
  317.                 line1str[4]=' ';
  318.         }else{
  319.                 line1str[3]=0x30+almtmp_high/10;
  320.                 line1str[4]=0x30+almtmp_high%10;
  321.   }
  322.         if(MODE_SET_HUMI_HIGH== mode_status && flashflg){
  323.                 line1str[10]=' ';
  324.                 line1str[11]=' ';
  325.   }else{
  326.                 line1str[10]=0x30+almhumi_high/10;
  327.                 line1str[11]=0x30+almhumi_high%10;
  328.         }
  329.         OLED_8x16Str(0,0,line1str);        
  330.         
  331.         //設置光強度
  332.         strncpy(line2str,"litH:99 15/04/25",16);
  333.         
  334.         if(MODE_SET_LIGHT== mode_status && flashflg){
  335.           line2str[5]=' '; //100%顯示
  336.           line2str[6]=' ';

  337.   }else{
  338.           line2str[5]=0x30+set_lit_high/10; //100%顯示
  339.           line2str[6]=0x30+set_lit_high%10;
  340.         }
  341.         if(MODE_SET_YEAR== mode_status && flashflg){
  342.           line2str[8]=' '; //100%顯示
  343.           line2str[9]=' ';

  344.   }else{
  345.           line2str[8]=0x30+settime[YEAR]/10; //100%顯示
  346.           line2str[9]=0x30+settime[YEAR]%10;
  347.         }        
  348.         
  349.         if(MODE_SET_MON== mode_status && flashflg){
  350.           line2str[11]=' '; //100%顯示
  351.           line2str[12]=' ';

  352.   }else{
  353.           line2str[11]=0x30+settime[MON]/10; //100%顯示
  354.           line2str[12]=0x30+settime[MON]%10;
  355.         }               
  356.         
  357.         if(MODE_SET_DATE== mode_status && flashflg){
  358.           line2str[14]=' '; //100%顯示
  359.           line2str[15]=' ';

  360.   }else{
  361.           line2str[14]=0x30+settime[DATE]/10; //100%顯示
  362.           line2str[15]=0x30+settime[DATE]%10;
  363.         }        
  364.         OLED_8x16Str(0,2,line2str);        
  365.         

  366.         //設置時間
  367.         strncpy(line3str," 10/59/00       ",16);
  368.         
  369.         if(MODE_SET_HOUR== mode_status && flashflg){
  370.           line3str[1]=' '; //100%顯示
  371.           line3str[2]=' ';

  372.   }else{
  373.           line3str[1]=0x30+settime[HOUR]/10; //100%顯示
  374.           line3str[2]=0x30+settime[HOUR]%10;
  375.         }
  376.         if(MODE_SET_MIN== mode_status && flashflg){
  377.           line3str[4]=' '; //100%顯示
  378.           line3str[5]=' ';

  379.   }else{
  380.           line3str[4]=0x30+settime[MIN]/10; //100%顯示
  381.           line3str[5]=0x30+settime[MIN]%10;
  382.         }        
  383.         
  384.         if(MODE_SET_SEC== mode_status && flashflg){
  385.           line3str[7]=' '; //100%顯示
  386.           line3str[8]=' ';

  387.   }else{
  388.           line3str[7]=0x30+settime[SEC]/10; //100%顯示
  389.           line3str[8]=0x30+settime[SEC]%10;
  390.         }               
  391.         OLED_8x16Str(0,4,line3str);
  392.         
  393.         //顯示手機
  394.         strncpy(line4str,"NO:13538510586   ",16);
  395.         for(i=3;i<14;i++){
  396.     line4str[i]=  recephonenum[i-3];
  397.   }
  398.         OLED_8x16Str(0,6,line4str);
  399. }



  400. /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  401. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
  402. int main(void)
  403. {
  404.         uint8_t check,flashi,t,posi;
  405.         uint16_t adcx,motori,tt;
  406.         u32 i=0,xx;
  407.         SystemInit();                                        //系統(tǒng)時鐘配置
  408.         OLED_Init();                                          //初始化OLED  
  409.   NVIC_Configuration();                //初始化中斷向量
  410.         Init_RTC();                                                        //內部RTC初始化
  411.         Adc_Init();                                                        //adc 初始化
  412.         Usart1_Configuration(9600);        //串口配置 設置波特率9600
  413.         USART2_Config(9600);
  414.         Key_init();                                                        //按鍵初始化輸入
  415.   OLED_8x16Str(0,0,line1str);
  416.         OLED_8x16Str(0,2,line2str);
  417.   OLED_8x16Str(0,4,line3str);
  418.         OLED_8x16Str(0,6,line4str);        

  419.         Motor_Init();                                                //馬達控制IO初始化
  420.         
  421.         Uart1_ClrBuf();
  422.   while(0==Sim_Send_AT())   delay_ms(1000);                //??SIM ???? ,SIM900?????
  423.   Sim_Set_MODE(1);
  424.   delay_ms(800);
  425.   Sim_ReSms_Config();
  426.   delay_ms(800);
  427.   Sim_Sms_Config_Cscs();
  428.         Solid_Init();                                         //繼電器IO配置輸出
  429.         Uart2_ClrBuf();
  430.         Uart1_ClrBuf();

  431.         set_lit_high=85;
  432.   almtmp_high=40;
  433.   almhumi_high=60;
  434.         
  435.         mode_status=0;
  436.         //RTC_Set(2015,4,25,20,35,00);
  437.         adci=0;
  438.         while(1)                                                                                                        
  439.         {
  440.           if(KEY_MENU_IN==0){        
  441.                                 delay_ms(5);
  442.                           if(KEY_MENU_IN==0){
  443.           mode_status++; //
  444.                       if(mode_status>9) mode_status=0;               
  445.                                         if( settimeflg){
  446.                                                 settimeflg=0;
  447.                                                 Time_Update(settime[YEAR]+2000,settime[MON],settime[DATE],settime[HOUR],settime[MIN],settime[SEC]);
  448.                                         }
  449.                                 }
  450.         while(KEY_MENU_IN==0) ;                        //等待放鍵
  451.           }        
  452.           if(KEY_ADD_IN==0){    //加鍵
  453.                         delay_ms(5);
  454.                         if(KEY_ADD_IN==0){
  455.                           switch(mode_status ){ //
  456.          case MODE_SET_HOUR:   
  457.                                          if(settime[HOUR]<24)  settime[HOUR]++;
  458.                                          else                                                        settime[HOUR]=0;
  459.                                          settimeflg=1;
  460.                                  break;
  461.          case MODE_SET_MIN:   
  462.                                          if(settime[MIN]<60)  settime[MIN]++;
  463.                                          else                                                        settime[MIN]=0;
  464.                                          settimeflg=1;
  465.                                  break;                                 
  466.          case MODE_SET_SEC:   
  467.                                          if(settime[MIN]<60)  settime[SEC]++;
  468.                                          else                                                        settime[SEC]=0;
  469.                                          settimeflg=1;
  470.                                  break;               
  471.          case MODE_SET_YEAR:   
  472.                                          if(settime[YEAR]<99)  settime[YEAR]++;
  473.                                          else                                                        settime[YEAR]=0;
  474.                                          settimeflg=1;
  475.                                  break;               
  476.          case MODE_SET_MON:   
  477.                                          if(settime[MON]<12)  settime[MON]++;
  478.                                          else                                                        settime[MON]=0;
  479.                                          settimeflg=1;
  480.                                  break;               
  481.          case MODE_SET_DATE:   
  482.                                          if(settime[DATE]<31)  settime[DATE]++;
  483.                                          else                                                        settime[DATE]=0;
  484.                                          settimeflg=1;
  485.                                  break;
  486.          case MODE_SET_TEMP_HIGH:   
  487.                                          if(almtmp_high<99)  almtmp_high++;
  488.                                          else                                                        almtmp_high=0;
  489.                                  break;
  490.          case MODE_SET_HUMI_HIGH :   
  491.                                          if(almhumi_high<99)  almhumi_high++;
  492.                                          else                                                        almhumi_high=0;
  493.                                  break;        
  494.          case MODE_SET_LIGHT :   
  495.                                          if(set_lit_high<99)  set_lit_high++;
  496.                                          else                                                        set_lit_high=0;
  497.                                  break;                                         
  498.                           }
  499.                         }                                
  500.       while(KEY_ADD_IN==0) ;                        
  501.         }
  502.         if(KEY_SUB_IN==0){   
  503.       delay_ms(5);  
  504.                         if(KEY_SUB_IN==0){        
  505.                           switch(mode_status ){ //
  506.          case MODE_SET_HOUR:   
  507.                                          if(settime[HOUR]>0)  settime[HOUR]--;
  508.                                          else                                                        settime[HOUR]=0;
  509.                                          settimeflg=1;
  510.                                  break;
  511.          case MODE_SET_MIN:   
  512.                                          if(settime[MIN]>0)  settime[MIN]--;
  513.                                          else                                                        settime[MIN]=0;
  514.                                          settimeflg=1;
  515.                                  break;                                 
  516.          case MODE_SET_SEC:   
  517.                                          if(settime[MIN]>0)  settime[SEC]--;
  518.                                          else                                                        settime[SEC]=0;
  519.                                          settimeflg=1;
  520.                                  break;               
  521.          case MODE_SET_YEAR:   
  522.                                          if(settime[YEAR]>0)  settime[YEAR]--;
  523.                                          else                                 settime[YEAR]=0;
  524.                                          settimeflg=1;
  525.                                  break;               
  526.          case MODE_SET_MON:   
  527.                                          if(settime[MON]>0)  settime[MON]--;
  528.                                          else                                                        settime[MON]=0;
  529.                                          settimeflg=1;
  530.                                  break;               
  531.          case MODE_SET_DATE:   
  532.                                          if(settime[DATE]>0)  settime[DATE]--;
  533.                                          else                                                        settime[DATE]=0;
  534.                                          settimeflg=1;
  535.                                  break;
  536.          case MODE_SET_TEMP_HIGH:   
  537.                                          if(almtmp_high>0)  almtmp_high--;
  538.                                          else                                                        almtmp_high=0;
  539.                                  break;
  540.          case MODE_SET_HUMI_HIGH :   
  541.                                          if(almhumi_high>0)  almhumi_high--;
  542.                                          else                                                        almhumi_high=0;
  543.                                  break;                                 
  544.          case MODE_SET_LIGHT :   
  545.                                          if(set_lit_high>0)  set_lit_high--;
  546.                                          else                                                        set_lit_high=0;
  547.                                  break;                                                
  548.                          }         
  549.                  }                                
  550.      while(KEY_SUB_IN==0) ;                        
  551. }        


  552. switch(mode_status){  ///不同狀態(tài)顯示不同頁面
  553.          
  554.                         case MODE_NORMAL:                                
  555.                
  556.                         dht11_readdata(dht11_buf);
  557.                         check= dht11_buf[0]+ dht11_buf[1]+ dht11_buf[2]+ dht11_buf[3];
  558.                         if(dht11_buf[4]==check){

  559.                                 nowhumi = dht11_buf[0];
  560.                                 nowtemp = dht11_buf[2];
  561.                                 thalmflg =0;
  562.                                 if(nowtemp> almtmp_high) thalmflg=1;
  563.                                 if(nowhumi> almhumi_high) thalmflg=1;
  564.                         
  565.                                 if (thalmflg){  //觸發(fā)短息發(fā)送
  566.                                                 tt++;
  567.                                           if(tt>300){
  568.                                                         strncpy(strLs,"Alarm Temp:99 oC, Humi:99 %RH",29);
  569.                                             strLs[11]=0x30+nowtemp/10;
  570.                                                         strLs[12]=0x30+nowtemp%10;
  571.                                                         strLs[23]=0x30+nowhumi/10;
  572.                                                         strLs[24]=0x30+nowhumi%10;
  573.                                                         OLED_8x16Str(0,2,"Sending msg.... ");        
  574.                                                         delay_ms(1000);
  575.                                                         Sim_Send_Text(recephonenum,strLs);
  576.                                                         tt=0;
  577.                                                 }
  578.                                        
  579.                                 }               
  580.                         }        
  581.                         
  582.                                 adtemp[adci]=Get_Adc(ADC_CH0);
  583.                                 adci++;               
  584.                                 if(        adci>11) {
  585.                                         adci=0;
  586.                                         light_adc = adc_avg();
  587.                                         if(light_adc >  set_lit_high*41) {//光照充足關閉窗簾
  588.             if(winflg==1){
  589.                                                           motori=800;
  590.                 while(motori--) { motor_Backward();}
  591.                                                                 Motor1_STOP_run;
  592.                                                 }
  593.                                                 winflg=0;}        
  594.                                   else        {
  595.                                                 if(winflg==0){
  596.                                                           motori=800;
  597.                 while(motori--) { motor_Foreward();}
  598.                                                                 Motor1_STOP_run;
  599.                                                 }
  600.                                                 winflg=1;   //打開窗簾
  601.                                         }
  602.                                 }        

  603.                                 if(t!=timer.sec)
  604.                                 {
  605.                                         t=timer.sec;
  606.                                         //printf("%d年%d月%d日%d點%d分%d秒\r\n",timer.w_year,timer.w_month,timer.w_date,timer.hour,timer.min,timer.sec);               
  607.                                 }        
  608.                                 Show_Normal();
  609.                                 memset(strLs,0,sizeof(strLs));
  610.                                 strLs[0]=0x3a;
  611.                                 strLs[1]=nowtemp/10+0x30;
  612.                                 strLs[2]=nowtemp%10+0x30;                                
  613.                                 strLs[3]=nowhumi/10+0x30;
  614.                                 strLs[4]=nowtemp%10+0x30;                                
  615.                                 strLs[5]=0x30+light_adc/41/10;        
  616.                                 strLs[6]=0x30+light_adc/41%10;               
  617.                                 strLs[7]=timer.w_year%1000%100/10+0x30;
  618.                                 strLs[8]=timer.w_year%1000%100%10+0x30;
  619.                                 strLs[9]=timer.w_month/10+0x30;                        
  620.                                 strLs[10]=timer.w_month%10+0x30;               
  621.                                 strLs[11]=timer.w_date/10+0x30;                        
  622.                                 strLs[12]=timer.w_date%10+0x30;                        
  623.                                 if(solid1flg) strLs[14]=1+0x30;                        
  624.                                 else                                        strLs[14]=0+0x30;               
  625.                                 if(solid2flg) strLs[15]=1+0x30;                        
  626.                                 else                                        strLs[15]=0+0x30;        
  627.                                 if(winflg)                 strLs[16]=1+0x30;                        
  628.                                 else                                        strLs[16]=0+0x30;                        
  629.                                 
  630.                                 for(i=0;i<17;i++) USART2_Senddata(strLs[i]);
  631.                    break;

  632.             case MODE_SET_HOUR:
  633.                         case MODE_SET_MIN:
  634.                         case MODE_SET_SEC:
  635.                   case MODE_SET_YEAR:
  636.                         case MODE_SET_MON:
  637.                         case MODE_SET_DATE:        
  638.                         case MODE_SET_HUMI_HIGH:
  639.                         case MODE_SET_TEMP_HIGH:               
  640.                         case MODE_SET_LIGHT:               
  641.                                 flashi++;
  642.                                 if(flashi>2){
  643.                                         flashflg=~flashflg;
  644.                                         flashi=0;
  645.                                 }                        
  646.                                 Show_SetPage();

  647.                          break;
  648.                          default:
  649.                                         break;

  650.                 }        
  651.                  
  652.                
  653.                 if(mystrstr(Uart1_RxBuf,"+CMTI:")!= NULL ){  //接收到手機短息
  654.                         delay_ms(300);
  655.                         OLED_8x16Str(0,2,"Receing msg.... ");        
  656.                   Uart1_ClrBuf();
  657.                         delay_ms(1000);               
  658.             USART1_SendString("AT+CMGR=1\r\n"); //??????
  659.                
  660.                         while(Uart1_RxBuf[0]==0);                                        //等級待接收
  661.                         delay_ms(1000);                                //set 1lu:
  662.                         delay_ms(1000);                                //set 1lu:
  663.                         delay_ms(1000);                                //set 1lu:
  664.                         if( mystrstr(Uart1_RxBuf,"1 Close")!= NULL ){
  665.                                 GPIO_ResetBits(GPIOB,GPIO_Pin_5);  //關閉1路繼電器輸出
  666.                                 solid1flg=0;
  667.                         }
  668.                         if( mystrstr(Uart1_RxBuf,"1 Open")!= NULL ){
  669.                                 GPIO_SetBits(GPIOB,GPIO_Pin_5);  //關閉1路繼電器輸出
  670.                                 solid1flg=1;
  671.                         }
  672.                         if( mystrstr(Uart1_RxBuf,"2 Close")!= NULL ){
  673.                                 GPIO_ResetBits(GPIOB,GPIO_Pin_6);  //關閉2路繼電器輸出
  674.                                 solid2flg=0;
  675.                         }
  676.                         if( mystrstr(Uart1_RxBuf,"2 Open")!= NULL ){
  677.                                 GPIO_SetBits(GPIOB,GPIO_Pin_6);  //打開2路繼電器輸出
  678.                                 solid2flg=1;
  679.                         }
  680.                         Sim_delt_Sms();                //刪除短信
  681. …………
  682. …………
  683. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼



所有資料51hei提供下載:

基于STM32的智能家居控制系統(tǒng).rar (1.73 MB, 下載次數(shù): 726)





作者: niexiaohui    時間: 2018-12-24 20:54
學習了,謝謝版主!!
作者: niexiaohui    時間: 2018-12-24 21:26
所有資料51hei提供下載:
作者: linqiming222    時間: 2019-1-11 15:04
最近準備學習一下單片機
作者: helpqiu    時間: 2019-2-27 14:59
畢設正準備做智能家居,學習了
作者: 冬哥~    時間: 2019-2-28 11:11
樓主,有沒有電路圖清晰版的啊 這個只有個圖片,謝謝
作者: forest3    時間: 2019-3-1 09:11
感謝,先看看
作者: Jooooooo    時間: 2019-4-17 21:03
請問這個SIM900支持的是多少G的SIM卡啊

作者: 冬哥~    時間: 2019-4-29 20:14
樓主 電路板用的STM32但是為什么仿真卻用得是51的主控?有沒有原理圖啊可以分享下嗎 、。?謝謝
作者: feiji666    時間: 2019-4-29 21:45
厲害了
作者: li321    時間: 2019-5-20 22:17
linqiming222 發(fā)表于 2019-1-11 15:04
最近準備學習一下單片機

有電路仿真的圖嗎
作者: 1298457699    時間: 2019-6-5 08:17
樓,請問有電路仿真嗎,求答
作者: linraochang    時間: 2019-9-1 15:56
請問樓主有原理圖嗎

作者: contactdeshine    時間: 2019-9-2 20:13
非常有用,感謝樓主分享
作者: 王慷    時間: 2020-3-26 09:40
非常有用,感謝樓主分享
作者: wangsh    時間: 2020-5-18 21:28
thank you very much
作者: ly533999    時間: 2020-6-16 21:51
冬哥~ 發(fā)表于 2019-4-29 20:14
樓主 電路板用的STM32但是為什么仿真卻用得是51的主控?有沒有原理圖啊可以分享下嗎 、。?謝謝

想要32原理圖~




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1