0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

keil5+STM32F103C8T6設(shè)計(jì)的智能插座+人體感應(yīng)燈 支持跨平臺(tái)編譯運(yùn)行

1126626497 ? 來(lái)源:DS小龍哥-嵌入式技術(shù) ? 作者:DS小龍哥-嵌入式技 ? 2022-02-28 13:19 ? 次閱讀

?

一、環(huán)境介紹

MCU: STM32F103C8T6

程序開(kāi)發(fā)IDE: keil5

STM32程序風(fēng)格: 采用寄存器方式開(kāi)發(fā),注釋齊全,執(zhí)行效率高,方便移植

手機(jī)APP: 采用QT設(shè)計(jì),程序支持跨平臺(tái)編譯運(yùn)行(Android、IOS、Windows、Linux都可以編譯運(yùn)行,對(duì)應(yīng)平臺(tái)上QT的環(huán)境搭建,之前博客已經(jīng)發(fā)了文章講解)

硬件包含:SRM32F103C8T6最小系統(tǒng)板、紅外熱釋電人體感應(yīng)模塊、DHT11溫濕度傳感器、0.96寸單色OLED顯示屏、ESP8266、繼電器、RGB大功率白燈.

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

二、功能介紹

這是基于STM32設(shè)計(jì)的智能插座+人體感應(yīng)燈。

硬件包含:

1. SRM32F103C8T6最小系統(tǒng)板: 基礎(chǔ)的系統(tǒng)板,引出了所有IO口

2. 紅外熱釋電人體感應(yīng)模塊: 用來(lái)檢測(cè)人體

3. DHT11溫濕度傳感器: 檢測(cè)環(huán)境的溫度、濕度

4. 0.96寸單色OLED顯示屏 : 顯示狀態(tài)信息。比如: WIFI狀態(tài)、RTC時(shí)鐘、插座狀態(tài)、溫濕度值

5. ESP8266: 用來(lái)與手機(jī)APP之間通信

6. 繼電器: 模擬插座開(kāi)關(guān)

7. RGB大功率白燈: 模擬正常的燈泡

支持的功能如下:

1. 使用熱釋電人體感應(yīng)模塊檢測(cè)人體,檢測(cè)到人體自動(dòng)開(kāi)燈,30秒(時(shí)間可以根據(jù)要求調(diào)整)沒(méi)有檢測(cè)到人體就自動(dòng)關(guān)燈。

2. 檢測(cè)環(huán)境溫濕度,使用OLED顯示屏在界面上實(shí)時(shí)顯示出來(lái)。 如果環(huán)境溫度高于閥值,強(qiáng)制關(guān)閉插座、如果濕度高于閥值,也會(huì)強(qiáng)制關(guān)閉插座;防止火災(zāi)隱患。 溫度最高閥值設(shè)置為: 30°,濕度閥值為80%, 這些都可以根據(jù)設(shè)計(jì)要求調(diào)整。

并且RGB燈也會(huì)根據(jù)不同的溫度閥值亮不同顏色的燈。 比如: 溫度高于30°亮紅色、溫度20°黃色 、溫度10°青色

3. 設(shè)置ESP8266WIFI模塊為AP模式(路由器模式),手機(jī)或者電腦可以連接到ESP8266.搭建局域網(wǎng)。

4. 設(shè)計(jì)手機(jī)APP和電腦客戶端軟件,可以實(shí)時(shí)顯示收到的溫濕度數(shù)據(jù)(3秒上傳一次).可以顯示歷史. 點(diǎn)擊手機(jī)APP上的按鈕,可以用來(lái)控制插座開(kāi)關(guān)。

5. OLED一共有4個(gè)頁(yè)面。 RTC實(shí)時(shí)時(shí)鐘顯示頁(yè)面、溫濕度顯示頁(yè)面、智能插座開(kāi)關(guān)狀態(tài)頁(yè)面、WIFI熱點(diǎn)信息頁(yè)面

6. OLED顯示屏的第一頁(yè)是實(shí)時(shí)時(shí)鐘頁(yè)面,時(shí)間可以通過(guò)手機(jī)APP來(lái)校準(zhǔn)。 在手機(jī)APP上有一個(gè)RTC校準(zhǔn)按鈕,點(diǎn)擊一下就可以校準(zhǔn)設(shè)備上的時(shí)間。

三、使用的相關(guān)硬件介紹

3.1DTH11 溫濕度傳感器

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

DHT11數(shù)字溫濕度傳感器是一款含有已校準(zhǔn)數(shù)字信號(hào)輸出的溫濕度復(fù)合傳感器,它應(yīng)用專(zhuān)用的數(shù)字模塊采集技術(shù)和溫濕度傳感技術(shù),確保產(chǎn)品具有極高的可靠性和卓越的長(zhǎng)期穩(wěn)定性。傳感器包括一個(gè)電阻式感濕元件和一個(gè)NTC測(cè)溫元件,并與一個(gè)高性能8位單片機(jī)相連接。因此該產(chǎn)品具有品質(zhì)卓越、超快響應(yīng)、抗干擾能力強(qiáng)、性價(jià)比極高等優(yōu)點(diǎn)。每個(gè)DHT11傳感器都在極為精確的濕度校驗(yàn)室中進(jìn)行校準(zhǔn)。校準(zhǔn)系數(shù)以程序的形式存在OTP內(nèi)存中,傳感器內(nèi)部在檢測(cè)信號(hào)的處理過(guò)程中要調(diào)用這些校準(zhǔn)系數(shù)。單線制串行接口,使系統(tǒng)集成變得簡(jiǎn)易快捷。超小的體積、極低的功耗,使其成為該類(lèi)應(yīng)用中,在苛刻應(yīng)用場(chǎng)合的最佳選擇。產(chǎn)品為4針單排引腳封裝,連接方便。

3.2熱釋電傳感器

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

熱釋電紅外傳感器在結(jié)構(gòu)上引入場(chǎng)效應(yīng)管,其目的在于完成阻抗變換。由于熱釋電元輸出的是電荷信號(hào),并不能直接使用,因而需要用電阻將其轉(zhuǎn)換為電壓形式。故引入的N溝道結(jié)型場(chǎng)效應(yīng)管應(yīng)接成共漏形式來(lái)完成阻抗變換。熱釋電紅外傳感器由傳感探測(cè)元、干涉濾光片和場(chǎng)效應(yīng)管匹配器三部分組成。設(shè)計(jì)時(shí)應(yīng)將高熱電材料制成一定厚度的薄片,并在它的兩面鍍上金屬電極,然后加電對(duì)其進(jìn)行極化,這樣便制成了熱釋電探測(cè)元。
熱釋電紅外傳感器的外形如上圖所示。其可以檢測(cè)人體發(fā)出的紅外線信號(hào),并將其轉(zhuǎn)換成電信號(hào)輸出。傳感器頂部的長(zhǎng)方形窗口加有濾光片,可以使人體發(fā)出的9~10μm波長(zhǎng)的紅外線通過(guò),而其它波長(zhǎng)的紅外線被濾除,這樣便提高了抗干擾能。熱釋電紅外傳感器由濾光片、熱釋電探測(cè)元和前置放大器組成,補(bǔ)償型熱釋電傳感器還帶有溫度補(bǔ)償元件,圖所示為熱釋電傳感器的內(nèi)部結(jié)構(gòu)。為防止外部環(huán)境對(duì)傳感器輸出信號(hào)的干擾,上述元件被真空封裝在一個(gè)金屬營(yíng)內(nèi)。熱釋電傳感器的濾光片為帶通濾光片,它封裝在傳感器殼體的頂端,使特定波長(zhǎng)的紅外輻射選擇性地通過(guò),到達(dá)熱釋電探測(cè)元+在其截止范圍外的紅外輻射則不能通過(guò)。
熱釋電探測(cè)元是熱釋電傳感器的核心元件,它是在熱釋電晶體的兩面鍍上金屬電極后,加電極化制成,相當(dāng)于一個(gè)以熱釋電晶體為電介質(zhì)的平板電容器。當(dāng)它受到非恒定強(qiáng)度的紅外光照射時(shí),產(chǎn)生的溫度變化導(dǎo)致其表面電極的電荷密度發(fā)生改變,從而產(chǎn)生熱釋電電流。
前置放大器由一個(gè)高內(nèi)阻的場(chǎng)效應(yīng)管源極跟隨器構(gòu)成,通過(guò)阻抗變換,將熱釋電探測(cè)元微弱的電流信號(hào)轉(zhuǎn)換為有用的電壓信號(hào)輸出。

3.3ESP8266串口WIFI模塊

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

ESP8266系列無(wú)線模塊是高性價(jià)比WIFI SOC模組,該系列模塊支持標(biāo)準(zhǔn)的IEEE802.11b/g/n協(xié)議,內(nèi)置完整的TCP/IP協(xié)議棧。用戶可以使用該系列模塊為現(xiàn)有的設(shè)備添加聯(lián)網(wǎng)功能,也可以構(gòu)建獨(dú)立的網(wǎng)絡(luò)控制器。

能卓越
ESP8266EX 芯片內(nèi)置超低功耗 Tensilica L106 32 位 RISC 處理器,CPU 時(shí)鐘速度最?可達(dá) 160 MHz,?持實(shí)時(shí)操作系統(tǒng) (RTOS) 和 Wi-Fi 協(xié)議棧,可將?達(dá) 80% 的處理能?應(yīng)用于編程和開(kāi)發(fā)。
高度集成
ESP8266 芯片高度集成天線開(kāi)關(guān)、射頻巴倫、功率放大器、低噪聲接收放大器、濾波器等射頻模塊。模組尺寸小巧,尤其適用于空間受限的產(chǎn)品設(shè)計(jì)。

認(rèn)證齊全
RF 認(rèn)證:SRRC、FCC、CE-RED、KCC、TELEC/MIC、IC 和 NCC 認(rèn)證;
環(huán)保認(rèn)證:RoHS、REACH;
可靠性認(rèn)證:HTOL、HTSL、μHAST、TCT、ESD。

豐富的產(chǎn)品應(yīng)用
ESP8266 模組既可以通過(guò) ESP-AT 指令固件,為外部主機(jī) MCU 提供 Wi-Fi 連接功能;也可以作為獨(dú)立 Wi-Fi MCU 運(yùn)行,用戶通過(guò)基于 RTOS 的 SDK 開(kāi)發(fā)帶 Wi-Fi 連接功能的產(chǎn)品。用戶可以輕松實(shí)現(xiàn)開(kāi)箱即用的云連接、低功耗運(yùn)行模式,以及包括 WPA3 在內(nèi)的 Wi-Fi 安全支持等功能。

3.4OLED顯示屏

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

OLED顯示屏是利用有機(jī)電自發(fā)光二極管制成的顯示屏。由于同時(shí)具備自發(fā)光有機(jī)電激發(fā)光二極管,不需背光源、對(duì)比度高、厚度薄、視角廣、反應(yīng)速度快、可用于撓曲性面板、使用溫度范圍廣、構(gòu)造及制程較簡(jiǎn)單等優(yōu)異之特性,被認(rèn)為是下一代的平面顯示器新興應(yīng)用技術(shù)。
有機(jī)發(fā)光二極管 (OLED)顯示器越來(lái)越普遍,在手機(jī)、媒體播放器及小型入門(mén)級(jí)電視等產(chǎn)品中最為顯著。不同于標(biāo)準(zhǔn)的液晶顯示器,OLED 像素是由電流源所驅(qū)動(dòng)。若要了解 OLED 電源供應(yīng)如何及為何會(huì)影響顯示器畫(huà)質(zhì),必須先了解 OLED 顯示器技術(shù)及電源供應(yīng)需求。本文將說(shuō)明最新的 OLED 顯示器技術(shù),并探討主要的電源供應(yīng)需求及解決方案,另外也介紹專(zhuān)為 OLED 電源供應(yīng)需求而提出的創(chuàng)新性電源供應(yīng)架構(gòu)。
背板技術(shù)造就軟性顯示器 高分辨率彩色主動(dòng)式矩陣有機(jī)發(fā)光二極管 (AMOLED) 顯示器需要采用主動(dòng)式矩陣背板,此背板使用主動(dòng)式開(kāi)關(guān)進(jìn)行各像素的開(kāi)關(guān)。液晶 (LC) 顯示器非晶硅制程已臻成熟,可供應(yīng)低成本的主動(dòng)式矩陣背板,并且可用于 OLED。許多公司正針對(duì)軟性顯示器開(kāi)發(fā)有機(jī)薄膜晶體管 (OTFT) 背板制程,此一制程也可用于 OLED 顯示器,以實(shí)現(xiàn)全彩軟性顯示器的推出。不論是標(biāo)準(zhǔn)或軟性 OLED,都需要運(yùn)用相同的電源供應(yīng)及驅(qū)動(dòng)技術(shù)。若要了解 OLED 技術(shù)、功能及其與電源供應(yīng)之間的互動(dòng),必須深入剖析這項(xiàng)技術(shù)本身。OLED 顯示器是一種自體發(fā)光顯示器技術(shù),完全不需要任何背光。OLED 采用的材質(zhì)屬于化學(xué)結(jié)構(gòu)適用的有機(jī)材質(zhì)。 OLED 技術(shù)需要電流控制驅(qū)動(dòng)方法 OLED 具有與標(biāo)準(zhǔn)發(fā)光二極管 (LED) 相當(dāng)類(lèi)似的電氣特性,亮度均取決于 LED 電流。若要開(kāi)啟和關(guān)閉 OLED 并控制 OLED 電流,需要使用薄膜晶體管 (TFT)的控制電路。

OLED為自發(fā)光材料,不需用到背光板,同時(shí)視角廣、畫(huà)質(zhì)均勻、反應(yīng)速度快、較易彩色化、用簡(jiǎn)單驅(qū)動(dòng)電路即可達(dá)到發(fā)光、制程簡(jiǎn)單、可制作成撓曲式面板,符合輕薄短小的原則,應(yīng)用范圍屬于中小尺寸面板。
顯示方面:主動(dòng)發(fā)光、視角范圍大;響應(yīng)速度快,圖像穩(wěn)定;亮度高、色彩豐富、分辨率高。
工作條件:驅(qū)動(dòng)電壓低、能耗低,可與太陽(yáng)能電池、集成電路等相匹配。
適應(yīng)性廣:采用玻璃襯底可實(shí)現(xiàn)大面積平板顯示;如用柔性材料做襯底,能制成可折疊的顯示器。由于OLED是全固態(tài)、非真空器件,具有抗震蕩、耐低溫(-40℃)等特性,在軍事方面也有十分重要的應(yīng)用,如用作坦克、飛機(jī)等現(xiàn)代化武器的顯示終端。

3.5LED大功率燈模塊

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

LED燈是一塊電致發(fā)光的半導(dǎo)體材料芯片,用銀膠或白膠固化到支架上,然后用銀線或金線連接芯片和電路板,四周用環(huán)氧樹(shù)脂密封,起到保護(hù)內(nèi)部芯線的作用,最后安裝外殼,所以 LED 燈的抗震性能好。

LED(Light Emitting Diode),發(fā)光二極管,是一種能夠?qū)㈦娔苻D(zhuǎn)化為可見(jiàn)光的固態(tài)的半導(dǎo)體器件,它可以直接把電轉(zhuǎn)化為光。LED的心臟是一個(gè)半導(dǎo)體的晶片,晶片的一端附在一個(gè)支架上,一端是負(fù)極,另一端連接電源的正極,使整個(gè)晶片被環(huán)氧樹(shù)脂封裝起來(lái)。
半導(dǎo)體晶片由兩部分組成,一部分是P型半導(dǎo)體,在它里面空穴占主導(dǎo)地位,另一端是N型半導(dǎo)體,在這邊主要是電子。但這兩種半導(dǎo)體連接起來(lái)的時(shí)候,它們之間就形成一個(gè)P-N結(jié)。當(dāng)電流通過(guò)導(dǎo)線作用于這個(gè)晶片的時(shí)候,電子就會(huì)被推向P區(qū),在P區(qū)里電子跟空穴復(fù)合,然后就會(huì)以光子的形式發(fā)出能量,這就是LED燈發(fā)光的原理。而光的波長(zhǎng)也就是光的顏色,是由形成P-N結(jié)的材料決定的。

LED可以直接發(fā)出紅、黃、藍(lán)、綠、青、橙、紫、白色的光。

3.6STM32F103C8T6最小系統(tǒng)板

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

STM32F系列屬于中低端的32位ARM微控制器,該系列芯片是意法半導(dǎo)體(ST)公司出品,其內(nèi)核是Cortex-M3。
該系列芯片按片內(nèi)Flash的大小可分為三大類(lèi):小容量(16K和32K)、中容量(64K和128K)、大容量(256K、384K和512K)。
芯片集成定時(shí)器Timer,CAN,ADC,SPI,I2C,USB,UART等多種外設(shè)功能。
內(nèi)核
--ARM 32位的Cortex-M3
--最高72MHz工作頻率,在存儲(chǔ)器的0等待周期訪問(wèn)時(shí)可達(dá)1.25DMips/MHZ(DhrystONe2.1)
--單周期乘法和硬件除法
存儲(chǔ)器
--從16K到512K字節(jié)的閃存程序存儲(chǔ)器(STM32F103XXXX中的第二個(gè)X表示FLASH容量,其中:“4”=16K,“6”=32K,“8”=64K,B=128K,C=256K,D=384K,E=512K)
--最大64K字節(jié)的SRAM
電源管理
--2.0-3.6V供電和I/O引腳
--上電/斷電復(fù)位(POR/PDR)、可編程電壓監(jiān)測(cè)器(PVD)
--4-16MHZ晶振
--內(nèi)嵌經(jīng)出廠調(diào)校的8MHz的RC振蕩器
--內(nèi)嵌帶校準(zhǔn)的40KHz的RC振蕩器
--產(chǎn)生CPU時(shí)鐘的PLL
--帶校準(zhǔn)的32KHz的RC振蕩器
低功耗
--睡眠、停機(jī)和待機(jī)模式
--Vbat為RTC和后備寄存器供電
模數(shù)轉(zhuǎn)換器
--2個(gè)12位模數(shù)轉(zhuǎn)換器,1us轉(zhuǎn)換時(shí)間(多達(dá)16個(gè)輸入通道)
--轉(zhuǎn)換范圍:0至3.6V
--雙采樣和保持功能
--溫度傳感器
DMA
--2個(gè)DMA控制器,共12個(gè)DMA通道:DMA1有7個(gè)通道,DMA2有5個(gè)通道
--支持的外設(shè):定時(shí)器、ADC、SPI、USB、IIC和UART
--多達(dá)112個(gè)快速I(mǎi)/O端口(僅Z系列有超過(guò)100個(gè)引腳)
--26/37/51/80/112個(gè)I/O口,所有I/O口一塊映像到16個(gè)外部中斷;幾乎所有的端口均可容忍5V信號(hào)
調(diào)試模式
--串行單線調(diào)試(SWD)和JTAG接口
--多達(dá)8個(gè)定時(shí)器
--3個(gè)16位定時(shí)器,每個(gè)定時(shí)器有多達(dá)4個(gè)用于輸入捕獲/輸出比較/PWM或脈沖計(jì)數(shù)的通道和增量編碼器輸入
--1個(gè)16位帶死區(qū)控制和緊急剎車(chē),用于電機(jī)控制的PWM高級(jí)控制定時(shí)器
--2個(gè)看門(mén)狗定時(shí)器(獨(dú)立的和窗口型的)
--系統(tǒng)時(shí)間定時(shí)器:24位自減型計(jì)數(shù)器
--多達(dá)9個(gè)通信接口
2個(gè)I2C接口(支持SMBus/PMBus)
3個(gè)USART接口(支持ISO7816接口,LIN,IrDA接口和調(diào)制解調(diào)控制)
2個(gè)SPI接口(18M位/秒)
CAN接口(2.0B主動(dòng))
USB 2.0全速接口
計(jì)算單元
CRC計(jì)算單元,96位的新批唯一代碼
封裝
ECOPACK封裝

3.7杜邦線

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

3.8 繼電器

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

四、STM32核心代碼

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

4.1 STM32: main.c

#include "stm32f10x.h"
#include "beep.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include 
#include 
#include "exti.h"
#include "timer.h"
#include "rtc.h"
#include "wdg.h"
#include "oled.h"
#include "fontdata.h"
#include "adc.h"
#include "FunctionConfig.h"
#include "dht11.h"
#include "HumanDetection.h"
#include "esp8266.h"

/*
函數(shù)功能: 繪制時(shí)鐘表盤(pán)框架
*/
void DrawTimeFrame(void)
{
	u8 i;
	OLED_Circle(32,32,31);//畫(huà)外圓
	OLED_Circle(32,32,1); //畫(huà)中心圓
	//畫(huà)刻度
	for(i=0;i<60;i++)
	{
		if(i%5==0)OLED_DrawAngleLine(32,32,6*i,31,3,1);
	}
	OLED_RefreshGRAM();  //刷新數(shù)據(jù)到OLED屏幕
}

/*
函數(shù)功能: 更新時(shí)間框架顯示,在RTC中斷里調(diào)用
*/
char TimeBuff[20];
void Update_FrameShow(void)
{
	/*1. 繪制秒針、分針、時(shí)針*/
	OLED_DrawAngleLine2(32,32,rtc_clock.sec*6-6-90,27,0);//清除之前的秒針
	OLED_DrawAngleLine2(32,32,rtc_clock.sec*6-90,27,1); //畫(huà)秒針
	
	OLED_DrawAngleLine2(32,32,rtc_clock.min*6-6-90,24,0);
	OLED_DrawAngleLine2(32,32,rtc_clock.min*6-90,24,1);
	
	OLED_DrawAngleLine2(32,32,rtc_clock.hour*30-6-90,21,0);
	OLED_DrawAngleLine2(32,32,rtc_clock.hour*30-90,21,1);
	
	//繪制電子鐘時(shí)間
	sprintf(TimeBuff,"%d",rtc_clock.year);
	OLED_ShowString(65,16*0,16,TimeBuff);  //年份字符串
	OLED_ShowChineseFont(66+32,16*0,16,4); //顯示年
	
	sprintf(TimeBuff,"%d/%d",rtc_clock.mon,rtc_clock.day);
	OLED_ShowString(75,16*1,16,TimeBuff); //月
	
	if(rtc_clock.sec==0)OLED_ShowString(65,16*2,16,"        ");	//清除多余的數(shù)據(jù)
	sprintf(TimeBuff,"%d:%d:%d",rtc_clock.hour,rtc_clock.min,rtc_clock.sec);
	OLED_ShowString(65,16*2,16,TimeBuff); //秒
	
	//顯示星期
	OLED_ShowChineseFont(70,16*3,16,5); //星
	OLED_ShowChineseFont(70+16,16*3,16,6); //期
	OLED_ShowChineseFont(70+32,16*3,16,rtc_clock.week+7); //具體的值
}


/*
函數(shù)功能: 溫濕度顯示
*/
void ShowTemperatureAndHumidity(u8 temp,u8 humi)
{
    sprintf(TimeBuff,"T: %d",temp);
	OLED_ShowString(40,16*1,16,TimeBuff); 
    sprintf(TimeBuff,"H: %d%%",humi);
	OLED_ShowString(40,16*2,16,TimeBuff); 
}

/*
函數(shù)功能: OLED所有顯示頁(yè)面信息初始化
*/
u8 ESP8266_Stat=0;   			//存放ESP8266狀態(tài)  1 OK ,0 error
u8 ESP8266_WIFI_AP_SSID[10];  //存放WIFI的名稱(chēng)	
#define STM32_96BIT_UID (0x1FFFF7E8) //STM32內(nèi)部96位唯一芯片標(biāo)識(shí)符寄存器地址

/*
函數(shù)功能: ESP8266 WIFI 顯示頁(yè)面
*/
char ESP8266_PwdShow[20];
char ESP8266_IP_PortAddr[30];  //存放ESP8266 IP地址與端口號(hào)地址
u8 Save_ESP8266_SendCmd[30];  //保存WIFI發(fā)送的命令
u8 Save_ESP8266_SendData[50];  //保存WIFI發(fā)送的數(shù)據(jù)

void ESP8266_ShowPageTable(void)
{
    if(ESP8266_Stat)OLED_ShowString(0,16*0,16,"WIFI STAT:ERROR");
    else OLED_ShowString(0,16*0,16,"WIFI STAT:OK");

    //顯示字符串
    //OLED_ShowString(0,2,(u8*)"                "); //清除一行的顯示
    memset((u8*)ESP8266_PwdShow,0,20); //清空內(nèi)存
    sprintf((char*)ESP8266_PwdShow,"WIFI:%s",ESP8266_WIFI_AP_SSID);
    ESP8266_PwdShow[15]='\0';
    OLED_ShowString(0,16*1,16,ESP8266_PwdShow);	
    memset((u8*)ESP8266_PwdShow,0,20); //清空內(nèi)存

    sprintf((char*)ESP8266_PwdShow,"PWD:%s",wifiap_password);
    OLED_ShowString(0,16*2,16,ESP8266_PwdShow);
    OLED_ShowString(0,16*3,16,"192.168.4.1:8089");	    
}


void OledShowPageTableInit(void)
{
    u8 data[100],i;
    u32 stm32_uid=0;
    u8 *uid;

/*1. ESP8266 WIFI相關(guān)信息初始化*/

    OLED_ShowString(0,2,16,"             "); //清空一行的顯示
    OLED_ShowString(0,2,16,"WifiInit...");  	//顯示頁(yè)面提示信息

    /*1.1 設(shè)置WIFI AP模式 */
    if(ESP8266_SendCmd("AT+CWMODE=2\r\n","OK",50))
    {
            ESP8266_Stat=1;  //OK
    }
    else
    {
            ESP8266_Stat=0;  //ERROR
    }
    
    /*1.2 重啟模塊 */
    ESP8266_SendCmd("AT+RST\r\n","OK",20);
    
    /*1.3 延時(shí)3S等待重啟成功*/
    DelayMs(1000);            
    DelayMs(1000);
    DelayMs(1000);
    
    //得到WIFI的名稱(chēng)
    uid=(u8*)STM32_96BIT_UID; //轉(zhuǎn)為指針為1個(gè)字節(jié)
    for(i=0;i<96;i++)
    {	
        stm32_uid+=*uid++; //計(jì)算校驗(yàn)和,得到WIFI數(shù)字編號(hào)
    }
    printf("stm32_uid=%d\r\n",stm32_uid);
    sprintf((char*)data,"%d",stm32_uid);
    strcpy((char*)ESP8266_WIFI_AP_SSID,"wbyq_");
    strcat((char*)ESP8266_WIFI_AP_SSID,(char*)data);
    printf("請(qǐng)用設(shè)備連接WIFI熱點(diǎn):%s,%s,%s\r\n",(u8*)ESP8266_WIFI_AP_SSID,(u8*)wifiap_encryption,(u8*)wifiap_password);
    
    /*1.4 配置模塊AP模式無(wú)線參數(shù)*/
    memset(data,0,100); //清空數(shù)組
    sprintf((char*)data,"AT+CWSAP=\"%s\",\"%s\",1,4\r\n",ESP8266_WIFI_AP_SSID,wifiap_password); 
    ESP8266_SendCmd(data,"OK",1000);

    /*1.5  設(shè)置多連接模式:0單連接,1多連接(服務(wù)器模式必須開(kāi)啟)*/
    ESP8266_SendCmd("AT+CIPMUX=1\r\n","OK",20); 
    
    /*1.6 開(kāi)啟Server模式(0,關(guān)閉;1,打開(kāi)),端口號(hào)為portnum */
    memset(data,0,100); //清空數(shù)組
    sprintf((char*)data,"AT+CIPSERVER=1,%s\r\n",(u8*)portnum);
    ESP8266_SendCmd(data,"OK",50);
    
    /*1.7 獲取當(dāng)前模塊的IP*/
    ESP8266_GetWanip((u8*)ESP8266_IP_PortAddr);
    strcat(ESP8266_IP_PortAddr,":");
    strcat(ESP8266_IP_PortAddr,portnum);
    printf("IP地址:%s\r\n",ESP8266_IP_PortAddr);
    
    OLED_ShowString(0,2,16,"              "); //清空一行的顯示
    OLED_ShowString(0,2,16,"WifiInitOk");  	//顯示頁(yè)面提示信息
}


/*
函數(shù)功能: 顯示開(kāi)關(guān)狀態(tài)
*/
void Show_Switch(int state)
{
    //清屏
    OLED_Clear(0);
    
    if(state)
    {
        sprintf(TimeBuff,"Socket:ON");
        OLED_ShowString(20,16*2,16,TimeBuff); 
    }   
    else
    {
        sprintf(TimeBuff,"Socket:OFF");
        OLED_ShowString(20,16*2,16,TimeBuff); 
    }
}

//int main1(void)
//{
//    HumanDetection_Init(); //熱釋電模塊初始化
//    UsartInit(USART1,72,115200);//串口1的初始化
//    LED_Init();  //初始化LED
//    while(1)
//    {
//    //熱釋電狀態(tài)  為真表示有人
//        if(HumanState)
//        {
//            LED1=0; //開(kāi)燈
//        }
//        else  //為假
//        {
//            LED1=1; //關(guān)燈
//        }
//        printf("%d\n",HumanState);
//    }
//}


int main(void)
{
    u8 rlen;
    char *p;
    u8 temp;  //溫度
    u8 humi;  //濕度
    u8 stat;
    u8 key_val;
	u32 TimeCnt=0;
    u32 wifi_TimeCnt=0;
    u16 temp_data; //溫度數(shù)據(jù)
    u8 page_cnt=0; //顯示的頁(yè)面
     char *time;
    u8 socket_state=0;
    
    UsartInit(USART1,72,115200);//串口1的初始化
    
	BEEP_Init(); //初始化蜂鳴器
	LED_Init();  //初始化LED
	KEY_Init();  //按鍵初始化
    
     printf("正在初始化OLED...\r\n");  
	OLED_Init(0xc8,0xa1); //OLED顯示屏初始化--正常顯示
    
    //OLED_Init(0xc0,0xa0); //OLED顯示屏初始化--翻轉(zhuǎn)顯示

	OLED_Clear(0x00); 						//清屏	
    
   
    UsartInit(USART3,36,115200); //WIFI的波特率為115200
    Timer2Init(72,10000); 		   //10ms中斷一次,輔助串口3接收數(shù)據(jù)--WIFI數(shù)據(jù)
	
    
    printf("正在初始化ESP8266..\r\n");  
    //ESP8266初始化
    OledShowPageTableInit();
     //清屏
    OLED_Clear(0);
      
    printf("正在初始化RTC...\r\n");         
    RTC_Init(); //RTC初始化
 
    DrawTimeFrame();  						//畫(huà)時(shí)鐘框架
	
    USART3_RX_STA=0; //清空串口的接收標(biāo)志位
    USART3_RX_CNT=0; //清空計(jì)數(shù)器
        
     printf("初始化DHT11...\r\n");   
    DHT11_Init(); //初始化DHT11
     printf("熱釋電模塊初始化...\r\n");   
    HumanDetection_Init(); //熱釋電模塊初始化
    
    //OLED_Clear(0);
    
    printf("開(kāi)始進(jìn)入while(1)\r\n");    
    while(1)
	{	
        key_val=KEY_GetValue();
        if(key_val)
        {
            page_cnt++;
            printf("page_cnt:%d\r\n",page_cnt);
            
             //清屏
             OLED_Clear(0);
            
             //時(shí)鐘頁(yè)面
            if(page_cnt==0)
            {
                DrawTimeFrame();  						//畫(huà)時(shí)鐘框架
                RTC->CRH|=1<<0; //開(kāi)啟秒中斷
            }
            //溫濕度頁(yè)面
            else if(page_cnt==1)
            {
                RTC->CRH&=~(1<<0); //關(guān)閉秒中斷
                //溫濕度
                ShowTemperatureAndHumidity(temp,humi);
            }
            //ESP8266顯示
            else if(page_cnt==2)
            {
                ESP8266_ShowPageTable();
            }
            else if(page_cnt==3)
            {
                 Show_Switch(socket_state);
            }
            else
            {
                DrawTimeFrame();  						//畫(huà)時(shí)鐘框架
                RTC->CRH|=1<<0; //開(kāi)啟秒中斷
                page_cnt=0;
            }    
        }
        
        //時(shí)間記錄
        DelayMs(10);
        TimeCnt++;
        wifi_TimeCnt++;
        if(TimeCnt>=100) //1000毫秒一次
        {
             TimeCnt=0;
             
             //讀取溫濕度數(shù)據(jù)
             DHT11_Read_Data(&temp,&humi);
            
            //濕度大于90就關(guān)閉開(kāi)關(guān)
            if(humi>90)
            {
                socket_state=0;
                if(page_cnt==3)
                {
                     Show_Switch(socket_state);
                }
            }
            
            //溫濕度頁(yè)面
            if(page_cnt==1)
            {
                //溫濕度
                ShowTemperatureAndHumidity(temp,humi);
            }
	    }
        
        if(wifi_TimeCnt>=300) //3000毫秒一次
        {
            wifi_TimeCnt=0;
            //溫濕度1秒上傳一次
            sprintf((char*)Save_ESP8266_SendData,"#%d,%d",temp,humi);  //拼接數(shù)據(jù)
            sprintf((char*)Save_ESP8266_SendCmd,"AT+CIPSEND=0,%d\r\n",strlen((char*)Save_ESP8266_SendData));
            ESP8266_SendCmd(Save_ESP8266_SendCmd,(u8*)"OK",200); //WIFI設(shè)置發(fā)送數(shù)據(jù)長(zhǎng)度
            ESP8266_SendData(Save_ESP8266_SendData,(u8*)"OK",100); //WIFI發(fā)送數(shù)據(jù)
        }
        
        //熱釋電狀態(tài)  為真表示有人
        if(HumanState)
        {
            LED1=0; //開(kāi)燈
        }
        else  //為假
        {
            LED1=1; //關(guān)燈
        }
        
        /*輪詢掃描數(shù)據(jù)*/
        if(USART3_RX_STA)		  //WIFI 接收到一次數(shù)據(jù)了
        { 
            rlen=USART3_RX_CNT;	//得到本次接收到的數(shù)據(jù)長(zhǎng)度
            USART3_RX_BUF[rlen]='\0';		  //添加結(jié)束符 
        //	printf("接收的數(shù)據(jù): %s\r\n",USART3_RX_BUF);	//發(fā)送到串口   

            {
                /*判斷是否收到客戶端發(fā)來(lái)的數(shù)據(jù)  */
                p=strstr((char*)USART3_RX_BUF,"+IPD");
                if(p!=NULL) //正常數(shù)據(jù)格式: +IPD,0,7:LED1_ON    +IPD,0表示第0個(gè)客戶端   7:LED1_ON表示數(shù)據(jù)長(zhǎng)度與數(shù)據(jù)
                {
                        /*解析上位機(jī)發(fā)來(lái)的數(shù)據(jù)*/
                        p=strstr((char*)USART3_RX_BUF,":");
                        if(p!=NULL)
                        {
                                p+=1; //向后偏移1個(gè)字節(jié)
                                if(*p=='*')  //設(shè)置RTC時(shí)間
                                {
                                        p+=1; //向后偏移,指向正確的時(shí)間
                                        time=p;
                                        rtc_clock.year=(time[0]-48)*1000+(time[1]-48)*100+(time[2]-48)*10+(time[3]-48)*1;
                                        rtc_clock.mon=(time[4]-48)*10+(time[5]-48)*1;
                                        rtc_clock.day=(time[6]-48)*10+(time[7]-48)*1;
                                        rtc_clock.hour=(time[8]-48)*10+(time[9]-48)*1;
                                        rtc_clock.min=(time[10]-48)*10+(time[11]-48)*1;
                                        rtc_clock.sec=(time[12]-48)*10+(time[13]-48)*1;
                                        RTC_SetTime(rtc_clock.year,rtc_clock.mon,rtc_clock.day,rtc_clock.hour,rtc_clock.min,rtc_clock.sec);

                                        if(page_cnt==0)
                                        {
                                            OLED_Clear(0); //OLED清屏
                                            DrawTimeFrame();//畫(huà)時(shí)鐘框架   
                                        }                                    
                                }
                                else if(strcmp(p,"LED1_ON")==0)
                                {
                                    socket_state=1;
                                }
                                else if(strcmp(p,"LED1_OFF")==0)
                                {
                                    socket_state=0;
                                }
                                
                                if(page_cnt==3)
                                {
                                     Show_Switch(socket_state);
                                }
                        }
                }
          }
            USART3_RX_STA=0;
            USART3_RX_CNT=0;
        }
    }        
}

4.2 STM32: rtc.c

#include "rtc.h"

//定義RTC標(biāo)準(zhǔn)結(jié)構(gòu)體
struct RTC_CLOCK rtc_clock; 

/*
函數(shù)功能: RTC初始化函數(shù)
*/
void RTC_Init(void)
{
        //檢查是不是第一次配置時(shí)鐘
	u8 temp=0;
	if(BKP->DR1!=0X5051)//之前使用的不是LSE
	{	 
	  	RCC->APB1ENR|=1<<28;     //使能電源時(shí)鐘	    
		RCC->APB1ENR|=1<<27;     //使能備份時(shí)鐘	    
		PWR->CR|=1<<8;           //取消備份區(qū)寫(xiě)保護(hù)
		RCC->BDCR|=1<<16;        //備份區(qū)域軟復(fù)位	   
		RCC->BDCR&=~(1<<16);     //備份區(qū)域軟復(fù)位結(jié)束	  	 
	    RCC->BDCR|=1<<0;         //開(kāi)啟外部低速振蕩器 
	    while((!(RCC->BDCR&0X02))&&temp<250)//等待外部時(shí)鐘就緒	 
		{
			temp++;
			DelayMs(10);
		};
		
		if(temp>=250)  //return 1;//初始化時(shí)鐘失敗,晶振有問(wèn)題	   
		{
			
			RCC->CSR|=1<<0; //開(kāi)啟外部低速振蕩器 
			while(!(RCC->CSR&(1<<1)));//外部低速振蕩器 
			RCC->BDCR|=2<<8; //LSI作為RTC時(shí)鐘 
			BKP->DR1=0X5050; //標(biāo)記使用LSI作為RTC時(shí)鐘
		}
		else 
        {
            RCC->BDCR|=1<<8; //LSE作為RTC時(shí)鐘 
            BKP->DR1=0X5051; //標(biāo)記使用LSE作為RTC時(shí)鐘
        }
		RCC->BDCR|=1<<15;//RTC時(shí)鐘使能	
		
	  	while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成	 
    	while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步  
    	RTC->CRH|=0X01;  		  //允許秒中斷
    	while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成	 
		RTC->CRL|=1<<4;           //允許配置	 
		RTC->PRLH=0X0000;
		RTC->PRLL=32767;          //時(shí)鐘周期設(shè)置(有待觀察,看是否跑慢了?)理論值:32767	
		RTC_SetTime(2021,4,25,20,36,20);  //設(shè)置時(shí)間	  
		RTC->CRL&=~(1<<4);           //配置更新
		while(!(RTC->CRL&(1<<5)));   //等待RTC寄存器操作完成		 									  
	 	printf("FIRST TIME\n");
	}else//系統(tǒng)繼續(xù)計(jì)時(shí)
	{
    	while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步  
    	RTC->CRH|=0X01;  		  //允許秒中斷
    	while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
		printf("OK\n");
	}		    				  
	STM32_NVIC_SetPriority(RTC_IRQn,2,2); //優(yōu)先級(jí)   
    
}

extern void Update_FrameShow(void);
/*
函數(shù)功能: RTC鬧鐘中斷服務(wù)函數(shù)
*/
void RTC_IRQHandler(void)
{
	  u32 SecCnt;
		if(RTC->CRL&1<<0)
		{
				SecCnt=RTC->CNTH<<16;//獲取高位
				SecCnt|=RTC->CNTL;   //獲取低位
				RTC_GetTime(SecCnt); //轉(zhuǎn)換標(biāo)準(zhǔn)時(shí)間
				RTC_GetWeek(SecCnt);
			 // printf("%d-%d-%d %d:%d:%d week:%d\n",rtc_clock.year,rtc_clock.mon,rtc_clock.day,rtc_clock.hour,rtc_clock.min,rtc_clock.sec,rtc_clock.week);
				Update_FrameShow(); //更新顯示
				RTC->CRL&=~(1<<0); //清除秒中斷標(biāo)志位
		}
		
		if(RTC->CRL&1<<1)
		{
//				printf("鬧鐘時(shí)間到達(dá)!....\n");
//			  BEEP=1;
//			  DelayMs(500);
//				BEEP=0;
				RTC->CRL&=~(1<<1); //清除鬧鐘中斷標(biāo)志位
		}
}



//閏年的月份
static int mon_r[12]={31,29,31,30,31,30,31,31,30,31,30,31};
//平年的月份
static int mon_p[12]={31,28,31,30,31,30,31,31,30,31,30,31};


/*
函數(shù)功能: 設(shè)置RTC時(shí)間
函數(shù)形參:
    u32 year;   2018
	  u32 mon;     8
	  u32 day;
		u32 hour;
		u32 min;
	  u32 sec;
*/
void RTC_SetTime(u32 year,u32 mon,u32 day,u32 hour,u32 min,u32 sec)
{
		u32 i;
	  u32 SecCnt=0; //總秒數(shù)
		/*1. 累加已經(jīng)過(guò)去的年份*/
		for(i=2017;iAPB1ENR|=1<<28;//使能電源時(shí)鐘
    RCC->APB1ENR|=1<<27;//使能備份時(shí)鐘
	PWR->CR|=1<<8;    //取消備份區(qū)寫(xiě)保護(hù)
	//上面三步是必須的!
	RTC->CRL|=1<<4;   //允許配置 
	RTC->CNTL=SecCnt&0xffff;
	RTC->CNTH=SecCnt>>16;
	RTC->CRL&=~(1<<4);//配置更新
	while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成 
}


/*
函數(shù)功能: 獲取RTC時(shí)間
函數(shù)參數(shù): u32 sec 秒單位時(shí)間
*/
void RTC_GetTime(u32 sec)
{
		u32 i;
		rtc_clock.year=2017; //基準(zhǔn)年份
		
	  /*1. 計(jì)算當(dāng)前的年份*/
	  while(1)
		{
			  if(RTC_GetYearState(rtc_clock.year))
				{
						if(sec>=366*24*60*60) //夠一年
						{
								sec-=366*24*60*60;
								rtc_clock.year++;
						}
						else break;
				}
				else
				{
						if(sec>=365*24*60*60) //夠一年
						{
								sec-=365*24*60*60;
								rtc_clock.year++;
						}
						else break;
				}
		}
		
		/*2. 計(jì)算當(dāng)前的月份*/
		rtc_clock.mon=1;
		for(i=0;i<12;i++)
		{
				if(RTC_GetYearState(rtc_clock.year))
				{
					 	if(sec>=mon_r[i]*24*60*60)
						{
							 sec-=mon_r[i]*24*60*60;
							 rtc_clock.mon++;
						}
						else break;		
				}
				else
				{
						if(sec>=mon_p[i]*24*60*60)
						{
							 sec-=mon_p[i]*24*60*60;
							 rtc_clock.mon++;
						}
						else break;	
				}
		}
		
		/*3. 計(jì)算當(dāng)前的天數(shù)*/
		rtc_clock.day=1;
		while(1)
		{
				if(sec>=24*60*60)
				{
						sec-=24*60*60;
						rtc_clock.day++;
				}
				else break;
		}
		
		/*4. 計(jì)算當(dāng)前的小時(shí)*/
		rtc_clock.hour=0;
		while(1)
		{
				if(sec>=60*60)
				{
						sec-=60*60;
						rtc_clock.hour++;
				}
				else break;
		}
		
		/*5. 計(jì)算當(dāng)前的分鐘*/
		rtc_clock.min=0;
		while(1)
		{
				if(sec>=60)
				{
						sec-=60;
						rtc_clock.min++;
				}
				else break;
		}
		
		/*6. 計(jì)算當(dāng)前的秒*/
		rtc_clock.sec=sec;
}


/*
函數(shù)功能: 判斷年份是否是平年、閏年
返回值  : 0表示平年 1表示閏年
*/
u8 RTC_GetYearState(u32 year)
{
	 if((year%4==0&&year%100!=0)||year%400==0)
	 {
		 return 1;
	 }
	 return 0;
}


/*
函數(shù)功能: 獲取星期
*/
void RTC_GetWeek(u32 sec)
{
	u32 day1=sec/(60*60*24); //將秒單位時(shí)間轉(zhuǎn)為天數(shù)
	switch(day1%7)
	{
		case 0:
			rtc_clock.week=0;
			break;
	 	case 1:
			rtc_clock.week=1;
			break;
		case 2:
			rtc_clock.week=2;
			break;
		case 3:
			rtc_clock.week=3;
			break;
		case 4:
			rtc_clock.week=4;
			break;
		case 5:
			rtc_clock.week=5;
			break;
		case 6:
			rtc_clock.week=6;
			break;
	}
}

;i++)>
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

4.3 ESP8266.c

#include "esp8266.h"

/*
函數(shù)功能:向ESP82668266發(fā)送命令
函數(shù)參數(shù):
				cmd:發(fā)送的命令字符串
				ack:期待的應(yīng)答結(jié)果,如果為空,則表示不需要等待應(yīng)答
				waittime:等待時(shí)間(單位:10ms)
返 回 值:
				 0,發(fā)送成功(得到了期待的應(yīng)答結(jié)果)
         1,發(fā)送失敗
*/
u8 ESP8266_SendCmd(u8 *cmd,u8 *ack,u16 waittime)
{
	u8 res=0; 
	USART3_RX_STA=0;
	USART3_RX_CNT=0;
	UsartStringSend(USART3,cmd);//發(fā)送命令
	if(ack&&waittime)		//需要等待應(yīng)答
	{
		while(--waittime)	//等待倒計(jì)時(shí)
		{
			DelayMs(10);
			if(USART3_RX_STA)//接收到期待的應(yīng)答結(jié)果
			{
				if(ESP8266_CheckCmd(ack))
				{
					res=0;
					//printf("cmd->ack:%s,%s\r\n",cmd,(u8*)ack);
					break;//得到有效數(shù)據(jù) 
				}
				USART3_RX_STA=0;
				USART3_RX_CNT=0;
			} 
		}
		if(waittime==0)res=1; 
	}
	return res;
}


/*
函數(shù)功能:ESP8266發(fā)送命令后,檢測(cè)接收到的應(yīng)答
函數(shù)參數(shù):str:期待的應(yīng)答結(jié)果
返 回 值:0,沒(méi)有得到期待的應(yīng)答結(jié)果
				 其他,期待應(yīng)答結(jié)果的位置(str的位置)
*/
u8* ESP8266_CheckCmd(u8 *str)
{
	char *strx=0;
	if(USART3_RX_STA)  //接收到一次數(shù)據(jù)了
	{ 
		USART3_RX_BUF[USART3_RX_CNT]=0;//添加結(jié)束符
		strx=strstr((const char*)USART3_RX_BUF,(const char*)str); //查找是否應(yīng)答成功
		//printf("RX=%s",USART3_RX_BUF);
	}
	return (u8*)strx;
}

/*
函數(shù)功能:向ESP8266發(fā)送指定數(shù)據(jù)
函數(shù)參數(shù):
				data:發(fā)送的數(shù)據(jù)(不需要添加回車(chē))
				ack:期待的應(yīng)答結(jié)果,如果為空,則表示不需要等待應(yīng)答
				waittime:等待時(shí)間(單位:10ms)
返 回 值:0,發(fā)送成功(得到了期待的應(yīng)答結(jié)果)luojian
*/
u8 ESP8266_SendData(u8 *data,u8 *ack,u16 waittime)
{
	u8 res=0; 
	USART3_RX_STA=0;
	UsartStringSend(USART3,data);//發(fā)送數(shù)據(jù)
	if(ack&&waittime)		//需要等待應(yīng)答
	{
		while(--waittime)	//等待倒計(jì)時(shí)
		{
			DelayMs(10);
			if(USART3_RX_STA)//接收到期待的應(yīng)答結(jié)果
			{
				if(ESP8266_CheckCmd(ack))break;//得到有效數(shù)據(jù) 
				USART3_RX_STA=0;
				USART3_RX_CNT=0;
			} 
		}
		if(waittime==0)res=1; 
	}
	return res;
}
	
	

/*
函數(shù)功能:ESP8266退出透?jìng)髂J?返 回 值:0,退出成功;
         1,退出失敗
*/
u8 ESP8266_QuitTrans(void)
{
	while((USART3->SR&0X40)==0);	//等待發(fā)送空
	USART3->DR='+';      
	DelayMs(15);					//大于串口組幀時(shí)間(10ms)
	while((USART3->SR&0X40)==0);	//等待發(fā)送空
	USART3->DR='+';      
	DelayMs(15);					//大于串口組幀時(shí)間(10ms)
	while((USART3->SR&0X40)==0);	//等待發(fā)送空
	USART3->DR='+';      
	DelayMs(500);					//等待500ms
	return ESP8266_SendCmd("AT\r\n","OK",20);//退出透?jìng)髋袛?
}

/*
函數(shù)功能:獲取ESP8266模塊的連接狀態(tài)
返 回 值:0,未連接;1,連接成功.
*/
u8 ESP8266_ConstaCheck(void)
{
	u8 *p;
	u8 res;
	if(ESP8266_QuitTrans())return 0;			  //退出透?jìng)?
	ESP8266_SendCmd("AT+CIPSTATUS\r\n",":",50);	//發(fā)送AT+CIPSTATUS指令,查詢連接狀態(tài)
	p=ESP8266_CheckCmd("+CIPSTATUS\r\n:"); 
	res=*p;																	//得到連接狀態(tài)	
	return res;
}

/*
函數(shù)功能:獲取ip地址
函數(shù)參數(shù):ipbuf:ip地址輸出緩存區(qū)
*/
void ESP8266_GetWanip(u8* ipbuf)
{
	  u8 *p,*p1;
		if(ESP8266_SendCmd("AT+CIFSR\r\n","OK",50))//獲取WAN IP地址失敗
		{
			ipbuf[0]=0;
			return;
		}		
		p=ESP8266_CheckCmd(""");
		p1=(u8*)strstr((const char*)(p+1),""");
		*p1=0;
		sprintf((char*)ipbuf,"%s",p+1);	
}

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

五、QT設(shè)計(jì)的上位機(jī)代碼: Android手機(jī)APP+Windows系統(tǒng)上位機(jī)

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11329

    瀏覽量

    209977
  • STM32
    +關(guān)注

    關(guān)注

    2270

    文章

    10915

    瀏覽量

    356787
  • 智能家居
    +關(guān)注

    關(guān)注

    1928

    文章

    9592

    瀏覽量

    185814
  • 人體感應(yīng)
    +關(guān)注

    關(guān)注

    3

    文章

    64

    瀏覽量

    17018
  • 智能插座
    +關(guān)注

    關(guān)注

    5

    文章

    194

    瀏覽量

    27762
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    基于STM32+Rd-03D做個(gè)智能人體跟隨旋轉(zhuǎn)臺(tái)

    基于STM32F103C8T6+Rd-03D設(shè)計(jì)的智能人體跟隨旋轉(zhuǎn)臺(tái),可根據(jù)空間內(nèi)人體的運(yùn)動(dòng)位置進(jìn)行智能跟蹤,將旋轉(zhuǎn)臺(tái)調(diào)整至對(duì)應(yīng)的角度。
    的頭像 發(fā)表于 12-14 09:23 ?195次閱讀
    基于<b class='flag-5'>STM32</b>+Rd-03D做個(gè)<b class='flag-5'>智能人體</b>跟隨旋轉(zhuǎn)臺(tái)

    STM32F103×8/STM32F103×B MCU手冊(cè)

    1. Q: STM32F103C8T6如何正確配置時(shí)鐘系統(tǒng)?A: STM32F103C8T6的時(shí)鐘系統(tǒng)配置通常涉及HSE(高速外部時(shí)鐘)、HSI(高速內(nèi)部時(shí)鐘)、PLL(相位鎖定環(huán))等。配置時(shí),首先
    發(fā)表于 11-18 15:14 ?0次下載

    19.3-星曈科技 openmv Hopenmv發(fā)送五個(gè)uchar Openmv+STM32F103C8T6視覺(jué)巡線小車(chē) STM32循跡小車(chē)系列教程

    19.3-【星曈科技】openmv Hopenmv發(fā)送五個(gè)uchar Openmv+STM32F103C8T6視覺(jué)巡線小車(chē) STM32循跡小車(chē)系列教程 使用OpenMV循跡 openMV尋跡與小車(chē)控制
    的頭像 發(fā)表于 08-20 11:32 ?980次閱讀
    19.3-星曈科技 openmv Hopenmv發(fā)送五個(gè)uchar Openmv+<b class='flag-5'>STM32F103C8T6</b>視覺(jué)巡線小車(chē) <b class='flag-5'>STM32</b>循跡小車(chē)系列教程

    19.4-STM32接收數(shù)據(jù)-狀態(tài)顯示在屏幕 openMV尋跡與小車(chē)控制 Openmv+STM32F103C8T6視覺(jué)巡線小車(chē)

    19.4-STM32接收數(shù)據(jù)-狀態(tài)顯示在屏幕 openMV尋跡與小車(chē)控制 Openmv+STM32F103C8T6視覺(jué)巡線小車(chē)
    的頭像 發(fā)表于 08-20 11:12 ?1003次閱讀
    19.4-<b class='flag-5'>STM32</b>接收數(shù)據(jù)-狀態(tài)顯示在屏幕 openMV尋跡與小車(chē)控制 Openmv+<b class='flag-5'>STM32F103C8T6</b>視覺(jué)巡線小車(chē)

    第七章-V1.5 STM32超聲波測(cè)距STM32F103C8t6超聲波避障小車(chē) 超聲波避障模塊 STM32超聲波測(cè)距

    5STM32超聲波測(cè)距STM32F103C8t6超聲波避障小車(chē)
    的頭像 發(fā)表于 08-15 16:25 ?720次閱讀
    第七章-V1.5 <b class='flag-5'>STM32</b>超聲波測(cè)距<b class='flag-5'>STM32F103C8t6</b>超聲波避障小車(chē) 超聲波避障模塊 <b class='flag-5'>STM32</b>超聲波測(cè)距

    怎么做才能在5.40版本的keil正常給F103c8t6下載程序?

    有一片F103c8t6,使用PDA下載器在5.14keil可以正常下載程序,但是在5.40版本的keil卻顯示\"Error: Not a genuine ST Device! Abort connection.\" 請(qǐng)問(wèn)我該怎
    發(fā)表于 07-24 06:58

    STMC32F103C8T6核心板原理圖

    STM32F103C8T6原理圖
    發(fā)表于 07-15 11:47 ?5次下載

    CW2015_STM32F1XX_C8T6資料包分享

    CW2015_STM32F1XX_C8T6
    發(fā)表于 06-07 12:46 ?10次下載

    STM32F103C8T6燒錄程序后上電不工作是怎么回事?

    STM32F103C8T6 燒錄程序后上電不工作
    發(fā)表于 05-24 07:27

    學(xué)STM32為什么首選F103C8T6

    STM32F103C8T6是STMicroelectronics(ST)推出的一款基于ARMCortex-M3內(nèi)核的32位微控制器單片機(jī)(MCU)。它具有一系列優(yōu)勢(shì)和廣泛的應(yīng)用場(chǎng)景。這里就來(lái)介紹一下
    的頭像 發(fā)表于 05-18 08:04 ?6264次閱讀
    學(xué)<b class='flag-5'>STM32</b>為什么首選<b class='flag-5'>F103C8T6</b>?

    STM32F030K6T6STM32F103C8T6的晶振換成25M的可以嗎?

    大神們,如果 把STM32F030K6T6STM32F103C8T6 的晶振換成25M的,可以嗎?
    發(fā)表于 04-26 06:12

    從程序STM32L151C8T6移植到STM32F103C8T6需要注意些什么?

    請(qǐng)問(wèn)從程序STM32L151C8T6移植到STM32F103C8T6需要注意些什么?
    發(fā)表于 04-15 06:06

    STM32F103C8T6最小系統(tǒng)板的外設(shè)對(duì)應(yīng)的引腳和STM32F103RCT6相同外設(shè)對(duì)應(yīng)的引腳相同嗎?

    STM32F103C8T6最小系統(tǒng)板的外設(shè)對(duì)應(yīng)的引腳和正點(diǎn)原子的Mini版的STM32F103RCT6相同外設(shè)對(duì)應(yīng)的引腳相同嗎
    發(fā)表于 04-08 06:08

    用ST-LINK燒錄STM32F103C8T6程序,燒錄程序就會(huì)出現(xiàn)無(wú)法連接的情況是為什么?

    請(qǐng)教一個(gè)古老的問(wèn)題.我用ST-LINK燒錄一個(gè)STM32F103C8T6的程序,并設(shè)置了燒錄完成自動(dòng)運(yùn)行,程序開(kāi)始跑了。然后在中途過(guò)程中,如果我再燒錄程序就會(huì)出現(xiàn)無(wú)法連接,必須手動(dòng)按下復(fù)位鍵(不松
    發(fā)表于 04-07 07:44

    用USB轉(zhuǎn)TTL線怎么把程序燒寫(xiě)到stm32f103C8T6

    ,我們需要準(zhǔn)備以下材料: 1. 一臺(tái)計(jì)算機(jī)(Windows操作系統(tǒng)) 2. STM32F103C8T6開(kāi)發(fā)板 3. USB轉(zhuǎn)TTL線(也稱(chēng)為串口線) 4. 充電線(用于給開(kāi)發(fā)板供電) 5. ST-LINK
    的頭像 發(fā)表于 01-31 15:46 ?7457次閱讀