包含,上位機(jī)、下位機(jī)
程序界面:
51hei.png (434 KB, 下載次數(shù): 75)
下載附件
2022-5-5 03:21 上傳
電路原理圖如下:
51hei.png (56.87 KB, 下載次數(shù): 65)
下載附件
2022-5-5 03:20 上傳
智能家居是通過(guò)簡(jiǎn)單的操作實(shí)現(xiàn)對(duì)家居的管理以提升家居便利性、舒適性的一種方式。本設(shè)計(jì)的主要功能是使用戶能夠在一定距離內(nèi)以無(wú)線的方式控制設(shè)備的開(kāi)關(guān)、工作模式、工作功率等以及監(jiān)測(cè)實(shí)時(shí)室溫和室溫變化。
內(nèi)容和要求:
通過(guò)不同的按鈕控制設(shè)備工作在不同的模式
通過(guò)在用戶界面上的簡(jiǎn)單操作實(shí)現(xiàn)對(duì)設(shè)備工作功率的調(diào)節(jié)
實(shí)現(xiàn)設(shè)備的定時(shí)開(kāi)關(guān)
上位機(jī)顯示實(shí)時(shí)室溫以及溫度變化曲線
本設(shè)計(jì)的硬件電路較簡(jiǎn)單,主要是上位機(jī)與下位機(jī)的程序設(shè)計(jì),難點(diǎn)在于上位機(jī)與下位機(jī)的通信協(xié)議設(shè)置以及下位機(jī)對(duì)硬件設(shè)備的控制。
1.1系統(tǒng)功能及框圖 本設(shè)計(jì)功能主要是對(duì)風(fēng)扇、LED兩個(gè)設(shè)備的控制以及通過(guò)溫度傳感器采集溫度實(shí)現(xiàn)實(shí)時(shí)溫度監(jiān)測(cè)。上位機(jī)和下位機(jī)通過(guò)wifi模塊實(shí)現(xiàn)一定距離內(nèi)的無(wú)線通信。上位機(jī)向下位機(jī)發(fā)送命令,下位機(jī)接受命令并直接控制各設(shè)備,然后向上位機(jī)返回一定的信息(下圖箭頭方向表示數(shù)據(jù)流動(dòng)方向)。 
圖1-1 總體框圖 1.1.1上位機(jī) 使用PC作為上位機(jī),上位機(jī)控制軟件由基于WinForm的C#編寫(xiě)。 首先,相比較VB.Net而言,C#支持無(wú)符號(hào)整數(shù),這對(duì)于需要頻繁與下位機(jī)交換正整數(shù)信息的上位機(jī)軟件而言是必須的;其次,VB 對(duì)大小寫(xiě)不敏感,而C#是大小寫(xiě)敏感的,對(duì)于習(xí)慣使用C語(yǔ)言編程的人而言C#更合適;最后,C#書(shū)寫(xiě)的代碼比VB平均短小20%。 綜合考慮,本設(shè)計(jì)采用的編程語(yǔ)言是C#。
1.1.2單片機(jī)系統(tǒng) 單片機(jī)使用的是STM32F103RCT6。 首先,STM32使用3.3V電壓供電,本設(shè)計(jì)采用的wifi模塊也使用3.3V供電,相比較5V供電的51單片機(jī)而言,省去了電平匹配電路;其次,本設(shè)計(jì)需要輸出不同占空比的PWM波以控制設(shè)備的功率,STM32有2個(gè)16位的6通道高級(jí)控制定時(shí)器,最多6個(gè)通道可用于PWM輸出,符合設(shè)計(jì)要求。 1.1.3 LED 該綠色LED用來(lái)模擬可由單片機(jī)直接控制的小功率設(shè)備,有三種工作模式。 模式一:以1s為周期進(jìn)行亮滅 模式二:以2s為周期進(jìn)行亮滅 模式三:常亮
1.1.4風(fēng)扇 風(fēng)扇工作需要較大的電流,無(wú)法使用單片機(jī)直接驅(qū)動(dòng),因此在單片機(jī)與風(fēng)扇之間加入驅(qū)動(dòng)電路以提高單片機(jī)的驅(qū)動(dòng)能力。該風(fēng)扇用來(lái)模擬無(wú)法直接用單片機(jī)驅(qū)動(dòng)的大功率設(shè)備。 該風(fēng)扇可以根據(jù)上位機(jī)的設(shè)置按一定的功率進(jìn)行工作。LED(紅)用來(lái)指示風(fēng)扇的功率。
1.1.5溫度采集 傳感器使用的是溫度傳感器DS18B20。 DS18B20是美國(guó)Dallas半導(dǎo)體公司的新一代數(shù)字式溫度傳感器,它具有獨(dú)特的單總線接口方式,即允許在一條信號(hào)線上掛接數(shù)十甚至上百個(gè)數(shù)字式傳感器,從而使測(cè)溫裝置與各傳感器的接口變得十分簡(jiǎn)單,克服了模擬式傳感器與微機(jī)接口時(shí)需要的A/D轉(zhuǎn)換器及其他復(fù)雜外圍電路的缺點(diǎn),而且,可以通過(guò)總線供電,由它組成的溫度測(cè)控系統(tǒng)非常方便,而且成本低、體積小、可靠性高。DS18B20的測(cè)溫范圍-55~+125℃最高分辨率可達(dá)0.0625℃,完全符合本設(shè)計(jì)的要求。
1.1.6 wifi模塊 本設(shè)計(jì)使用了兩個(gè)wifi模塊。一個(gè)與電腦通過(guò)串口相連,一個(gè)與下位機(jī)通過(guò)串口相連。兩個(gè)wifi模塊直接通過(guò)無(wú)線傳輸串口送來(lái)的數(shù)據(jù)。數(shù)據(jù)流通如下所示: 
圖1-2 數(shù)據(jù)流通
1.2 通信協(xié)議方案 上位機(jī)向下位機(jī)發(fā)送的控制信息大部分是0—100的數(shù)字,要區(qū)分這些數(shù)字是作用于哪個(gè)設(shè)備的控制信息就需要設(shè)計(jì)上位機(jī)與下位機(jī)的通信協(xié)議。 方案一:上位機(jī)在發(fā)送數(shù)字指令前先將數(shù)字轉(zhuǎn)換成字符串,在該字符串前加上標(biāo)志位,下位機(jī)接收到該字符串后去除標(biāo)志位,并將剩余字符串轉(zhuǎn)化為數(shù)字。 方案二:上位機(jī)在發(fā)送數(shù)字指令前先發(fā)送字符指令,通過(guò)不同的字符指令使得下位機(jī)中對(duì)應(yīng)的標(biāo)志位置位,其余標(biāo)志位復(fù)位,再發(fā)送數(shù)字指令。下位機(jī)根據(jù)各標(biāo)志位的狀態(tài)分辨出該數(shù)字指令是作用于哪個(gè)設(shè)備。 方案一不需要開(kāi)辟內(nèi)存空間設(shè)置標(biāo)志位,代碼量較少,上位機(jī)編程簡(jiǎn)單,但下位機(jī)對(duì)字符串的處理難度較大。方案二代碼量大,需要的內(nèi)存空間較大,但編程思路簡(jiǎn)單明了,易于實(shí)現(xiàn)。綜合考慮,本設(shè)計(jì)使用方案二。
1.3實(shí)時(shí)溫度采集方案 上位機(jī)實(shí)時(shí)溫度曲線的繪制需要實(shí)時(shí)采集溫度以更新用于繪制曲線的數(shù)組。 方案一:使用下位機(jī)的定時(shí)器,以1s為周期向上位機(jī)發(fā)送實(shí)時(shí)溫度值。 方案二:使用上位機(jī)的timer控件,以1s為周期想下位機(jī)發(fā)送請(qǐng)求,利用下位機(jī)的串口中斷獲取實(shí)時(shí)溫度值。 下位機(jī)定時(shí)器的初始化配置和開(kāi)啟與關(guān)閉較為復(fù)雜,且新增一個(gè)定時(shí)器中斷也會(huì)影響下位機(jī)的工作性能。相比較而言,上位機(jī)的timer控件使用較簡(jiǎn)單,而且獲取實(shí)時(shí)溫度使用的是下位機(jī)的串口中斷,不必新增中斷源。綜合考慮,本設(shè)計(jì)使用方案二。
硬件電路由STM32最小系統(tǒng)、DS18B20溫度采集、LED驅(qū)動(dòng)、風(fēng)扇驅(qū)動(dòng)這四個(gè)部分組成。下圖為硬件原理圖。

圖2-1 硬件原理圖
2.1 STM32最小系統(tǒng) 最小系統(tǒng)是一個(gè)可以正常啟動(dòng)和運(yùn)行的單片系統(tǒng),該系統(tǒng)中任何部件都是完全必要的,缺一不可的。在微處理器其他所有的設(shè)計(jì)中,都包含這個(gè)最小系統(tǒng)。最小系統(tǒng)的復(fù)雜程度,表明了該處理器的單片化程度。

圖2-2 最小系統(tǒng) 圖2-2是一個(gè)最小系統(tǒng)圖,圖中包括電源、時(shí)鐘和復(fù)位電路。 - 電源:STM32F1xx系列采用低電源工作,電源工作范圍是2.0~3.6V,常規(guī)設(shè)計(jì)一般選用3.3V電源。
- 復(fù)位控制:復(fù)位控制雖然十分重要,但設(shè)計(jì)一般都很簡(jiǎn)單。本設(shè)計(jì)采用按鍵復(fù)位。
- 時(shí)鐘:時(shí)鐘是微處理器最重要的部分,時(shí)鐘的來(lái)源是振蕩器。在STM32F1xx系列產(chǎn)品中,其芯片內(nèi)嵌一個(gè)8MHz的RC振蕩器,在芯片上電復(fù)位以后,這個(gè)RC振蕩器首先起振,為系統(tǒng)提供時(shí)鐘源。但是芯片內(nèi)部的RC振蕩器精度不高,在需要高精度時(shí)鐘的場(chǎng)合還必須使用外部振蕩器。本設(shè)計(jì)中需要實(shí)現(xiàn)異步通信,因此需要外接振蕩器以提供高精度時(shí)鐘。
STM32F1xx系列有兩個(gè)外部振蕩器接口。 系統(tǒng)主時(shí)鐘是系統(tǒng)除看門(mén)狗以外所有功能的時(shí)鐘。這個(gè)時(shí)鐘既可以選內(nèi)部RC振蕩器作為時(shí)鐘源,也可以外部接一個(gè)時(shí)鐘源。本設(shè)計(jì)中使用外部8MHz的時(shí)鐘源而不使用內(nèi)部RC振蕩器以提高精度。 B.系統(tǒng)輔助時(shí)鐘外部振蕩器接口 輔助時(shí)鐘作為看門(mén)狗的時(shí)鐘源,也可以選作實(shí)時(shí)時(shí)鐘RTC的時(shí)鐘源。驅(qū)動(dòng)輔助時(shí)鐘的振蕩器也有兩個(gè),一個(gè)是內(nèi)部32kHz的RC振蕩器,另一個(gè)是外部32.768kHz的振蕩器接口。本設(shè)計(jì)中外接一個(gè)32.768kHz的晶體振蕩器以提供精確輔助時(shí)鐘。 2.2 DS18B20溫度采集 DS18B20的信號(hào)線接在PA0口,接收單片機(jī)的指令并向單片機(jī)返回所測(cè)溫度值。 
圖2-3 溫度采集 上圖表明DS18B20與單片機(jī)的連接。
2.3 LED驅(qū)動(dòng) LED1即上述的具有三種工作模式的LED,LED0與風(fēng)扇共同受一個(gè)IO口控制,用以指示風(fēng)扇的工作功率。 
圖2-4 LED驅(qū)動(dòng) LED采用共陽(yáng)連接,LED正極與上拉電阻相連,負(fù)極與IO口相連。
2.4風(fēng)扇驅(qū)動(dòng) 風(fēng)扇用在原理圖中用DS3表示。 雖然風(fēng)扇與LED0共同受一個(gè)IO口控制,但風(fēng)扇功率較大,無(wú)法使用IO口直接驅(qū)動(dòng),需要增加驅(qū)動(dòng)電路。 控制模塊工作原理:當(dāng)單片機(jī)控制端加低電平時(shí),三極管Q2導(dǎo)通,這時(shí)Q2的上端,也就是C極被系統(tǒng)拉到0V左右,這時(shí)MOS管Q1的G極為0V,所以此時(shí)MOS管的DS端不會(huì)導(dǎo)通。當(dāng)單片機(jī)控制端加高電平時(shí),三極管Q2不導(dǎo)通,這時(shí)Q2的上端,也就是C極電位為Vcc-R9兩端的壓降,電流穿過(guò)R8后被穩(wěn)壓管D3穩(wěn)壓在5V,則此時(shí)MOS管的G極電壓為5V,所以MOS管導(dǎo)通,負(fù)載工作。

圖2-5 風(fēng)扇驅(qū)動(dòng)
軟件設(shè)計(jì)分為上位機(jī)程序和下位機(jī)程序兩個(gè)部分。上位機(jī)程序用C#編寫(xiě),采用事件觸發(fā)的方式便于用戶操作,主要功能是向下位機(jī)發(fā)送各種命令,并接受下位機(jī)的返回信息以一定方式顯示出來(lái)。下位機(jī)程序用C語(yǔ)言編寫(xiě),主要包括各設(shè)備的驅(qū)動(dòng)程序以及與上位機(jī)通信的串口中斷程序。
3.1上位機(jī)程序 上位機(jī)界面控制部分由上位機(jī)控制、LED控制、風(fēng)扇控制、溫度監(jiān)測(cè)和溫度曲線這五個(gè)部分組成。顯示部分包括當(dāng)前時(shí)間與定時(shí)時(shí)間的顯示、信息返回(下位機(jī)返回的信息)、曲線繪制三個(gè)部分。 
圖3-1 上位機(jī)整體框圖
3.1.1上位機(jī)控制 上位機(jī)控制部分總共有三個(gè)按鈕:打開(kāi)端口、關(guān)閉端口和退出。 考慮到該上位機(jī)專用于本次設(shè)計(jì)的下位機(jī),也是為了簡(jiǎn)化設(shè)計(jì),端口號(hào)、波特率、數(shù)據(jù)位等屬性都在窗口載入時(shí)固定下來(lái),無(wú)法在程序運(yùn)行時(shí)進(jìn)行修改。 
圖3-2 上位機(jī)控制部分 “打開(kāi)端口”即打開(kāi)默認(rèn)端口。為防止打開(kāi)端口時(shí)因?yàn)槎丝谔?hào)或其他原因出現(xiàn)的問(wèn)題使得程序拋出異常,在“打開(kāi)端口”按鈕的觸發(fā)事件中加入了try-catch語(yǔ)句。 “關(guān)閉端口”即關(guān)閉當(dāng)前打開(kāi)的端口。當(dāng)端口未打開(kāi)時(shí)該按鈕設(shè)置為不可用,只有當(dāng)有端口打開(kāi)才可用。“退出”即關(guān)閉當(dāng)前窗體。
3.1.2 LED控制 控制面板上的三個(gè)模式選擇按鈕對(duì)應(yīng)與上述的LED的三個(gè)工作模式。“關(guān)閉”按鈕即關(guān)閉LED。(模式一:以1s為周期進(jìn)行亮滅;模式二:以2s為周期進(jìn)行亮滅;模式三:常亮) 
圖3-3 LED控制部分 該部分的標(biāo)志字符是’a’。該部分的四個(gè)按鈕在按下后都會(huì)先發(fā)送’a’使下位機(jī)對(duì)相應(yīng)的標(biāo)志位進(jìn)行置位復(fù)位操作。然后再發(fā)送數(shù)字命令使下位機(jī)進(jìn)入不同的模式。最后彈出對(duì)話框,解釋對(duì)應(yīng)模式的具體功能。
3.1.3風(fēng)扇控制 該部分由風(fēng)扇控制和時(shí)間顯示兩部分組成。控制部分具有控制風(fēng)扇開(kāi)關(guān)、工作功率以及定時(shí)功能。時(shí)間顯示部分主要是服務(wù)于定時(shí)功能。該部分顯示當(dāng)前時(shí)間和定時(shí)時(shí)間,當(dāng)兩者相同時(shí)執(zhí)行定時(shí)設(shè)置的操作。若未使用定時(shí)功能,則不顯示定時(shí)時(shí)間。 
圖3-4風(fēng)扇控制部分 圖3-5時(shí)間顯示部分 為節(jié)省窗體面板空間以及便于用戶使用,該部分進(jìn)行了控件的層疊。 具體如下: (1)定時(shí)時(shí)間選擇框在初始加載時(shí)不可見(jiàn),字符“時(shí)分秒”不可見(jiàn),“定時(shí)開(kāi)”“定時(shí)關(guān)”按鈕不可見(jiàn),“設(shè)置完成”按鈕不可見(jiàn)。 (2)單擊“定時(shí)設(shè)置”,“開(kāi)”“關(guān)”按鈕不可見(jiàn),定時(shí)時(shí)間選擇框可見(jiàn),字符“時(shí)分秒”可見(jiàn),“定時(shí)設(shè)置”按鈕不可見(jiàn),“定時(shí)開(kāi)”“定時(shí)關(guān)”按鈕可見(jiàn),并彈出對(duì)話框“請(qǐng)選擇定時(shí)開(kāi)或定時(shí)關(guān)”。 a.單擊“定時(shí)開(kāi)”,“定時(shí)開(kāi)”“定時(shí)關(guān)”按鈕不可見(jiàn),“設(shè)置完成”按鈕可見(jiàn),彈出對(duì)話框“請(qǐng)?jiān)O(shè)置開(kāi)啟時(shí)間和功率”。 b.單擊“定時(shí)關(guān)”,“定時(shí)開(kāi)”“定時(shí)關(guān)”按鈕不可見(jiàn),“設(shè)置完成”按鈕可見(jiàn),彈出對(duì)話框“請(qǐng)?jiān)O(shè)置關(guān)閉時(shí)間”。 (3)單擊“設(shè)置完成”,“設(shè)置時(shí)間”可見(jiàn),“開(kāi)關(guān)控制”部分恢復(fù)原樣。 時(shí)分秒以及功率調(diào)節(jié)的下拉框選項(xiàng)都是在窗體載入時(shí)初始化的。 若不使用定時(shí)功能,則點(diǎn)擊“開(kāi)”,設(shè)備按最大功率運(yùn)行,點(diǎn)擊“關(guān)”,設(shè)備關(guān)閉,點(diǎn)擊“設(shè)置功率”,設(shè)備按設(shè)定的功率運(yùn)行。該部分發(fā)送的標(biāo)志字符是’c’。 若使用定時(shí)功能,具體操作如上所述。設(shè)置完成后設(shè)置的時(shí)間會(huì)在“定時(shí)時(shí)間”后的TIME處顯示,并與當(dāng)前時(shí)間比較(當(dāng)前時(shí)間為系統(tǒng)時(shí)間,由timer1每秒刷新一次),當(dāng)兩者相等時(shí)timer控件會(huì)向下位機(jī)發(fā)送相應(yīng)的命令。
3.1.4溫度監(jiān)測(cè) 該部分分為溫度檢測(cè)和溫度曲線兩個(gè)部分。第一部分可以設(shè)置溫度上下限以及查詢當(dāng)前溫度。當(dāng)溫度超過(guò)上限或下限時(shí)將發(fā)出相應(yīng)的警報(bào)。第二部分可以生成實(shí)時(shí)溫度曲線,用于直觀地顯示出溫度變化趨勢(shì)。 
圖3-6 溫度檢測(cè) 下拉框初始化與風(fēng)扇控制部分相同。 “溫限設(shè)置”按鈕用于向下位機(jī)發(fā)送溫限修改指令,即將下拉框中的溫度上限和溫度下限設(shè)置為下位機(jī)溫度的界限。 “溫度顯示”按鈕用于向下位機(jī)發(fā)送實(shí)時(shí)溫度查詢請(qǐng)求。下位機(jī)返回的實(shí)時(shí)溫度信息將顯示在“信息返回”部分的文本框中。 “溫限設(shè)置”的標(biāo)志字符為’b’,“溫度顯示”的標(biāo)志字符為’m’。 
圖3-7 繪制溫度曲線 “繪制曲線”用于繪制曲線,按下后啟動(dòng)timer2,每秒向下位機(jī)發(fā)送一次溫度采集請(qǐng)求,同時(shí)將數(shù)據(jù)讀取方式標(biāo)志位置位(為方便下位機(jī)返回的信息顯示在文本框中,上位機(jī)默認(rèn)使用字符方式讀取串口數(shù)據(jù),當(dāng)需要繪制曲線時(shí),要更改為使用字節(jié)方式讀取串口數(shù)據(jù),讀取方式由數(shù)據(jù)讀取方式標(biāo)志位決定)。 從串口讀取到的數(shù)據(jù)經(jīng)過(guò)相應(yīng)算法處理后生成溫度曲線圖像顯示在圖片框中。該圖片框也由timer2控制,每秒刷新一次。 timer2溫度采集請(qǐng)求的標(biāo)志字符為’t’。 “停止繪制”用于撤銷“繪制曲線”按鈕的操作。此時(shí)圖片框中顯示最后一次刷新出的圖片并保持。當(dāng)再次啟動(dòng)曲線繪制時(shí)圖片框清空重新繪制。
3.2下位機(jī)程序 下位機(jī)程序主要由以下幾個(gè)部分構(gòu)成:LED驅(qū)動(dòng)程序(因?yàn)轱L(fēng)扇與指示其功率大小的LED由同一個(gè)IO口控制,所以沒(méi)有專門(mén)的風(fēng)扇驅(qū)動(dòng)程序)、DS18B20驅(qū)動(dòng)程序、PWM波生成程序、定時(shí)器設(shè)置程序、串口中斷服務(wù)程序。
3.2.1主函數(shù) 主函數(shù)完成各部分的初始化,完成風(fēng)扇功率的設(shè)置以及控制LED工作在不同的模式下,其余功能由各中斷函數(shù)完成。
與LED相連的IO口設(shè)置為推挽輸出。LED的三種顯示模式均在主函數(shù)中完成,由標(biāo)志位LED_model控制。該標(biāo)志位由串口中斷服務(wù)程序根據(jù)上位機(jī)發(fā)送過(guò)來(lái)的數(shù)據(jù)進(jìn)行置位或復(fù)位。
3.2.3串口通信
串口波特率為9600,數(shù)據(jù)位8位,1位停止位,無(wú)奇偶校驗(yàn)位,無(wú)硬件數(shù)據(jù)流控制,采用收發(fā)模式。
串口中斷服務(wù)程序主要包括兩個(gè)部分:(1)根據(jù)上位機(jī)發(fā)送的信息對(duì)標(biāo)志位進(jìn)行置位或復(fù)位;(2)根據(jù)設(shè)置的標(biāo)志位執(zhí)行相應(yīng)的操作。
串口中斷服務(wù)程序調(diào)用相當(dāng)頻繁。
該程序讀取上位機(jī)發(fā)送過(guò)來(lái)的標(biāo)志信息,對(duì)各標(biāo)志位進(jìn)行置位或復(fù)位操作,再根據(jù)上位機(jī)發(fā)送過(guò)來(lái)的數(shù)字信息修改相應(yīng)的變量。
該程序根據(jù)上位機(jī)發(fā)送過(guò)來(lái)的命令給出響應(yīng)信息,根據(jù)上位機(jī)的要求返回對(duì)應(yīng)的信息(例如溫度值)。
以下為各標(biāo)志位以及部分變量的解釋:
temp_trx:下位機(jī)從緩沖區(qū)讀取到的上位機(jī)數(shù)據(jù)。
LED_model:LED模式,不同取值會(huì)使LED進(jìn)入不同狀態(tài)。取值1到3表示三種工作模式,取值4表示熄滅。
fan_rate:風(fēng)扇功率。例如該變量取值50,則風(fēng)扇以50%的功率工作。
temp_show:溫度顯示標(biāo)志,該標(biāo)志位置位表示下位機(jī)接收到上位機(jī)采集單個(gè)溫度值的請(qǐng)求。
LED_flag:LED控制信息標(biāo)識(shí),當(dāng)下位機(jī)接收到LED控制字符時(shí)該標(biāo)志位置位,表示上位機(jī)接下來(lái)發(fā)送的數(shù)據(jù)是用于對(duì)與LED相關(guān)的變量操作。
temp_flag:溫度控制信息標(biāo)識(shí),當(dāng)下位機(jī)接收到溫度上下限控制字符時(shí)該標(biāo)志位置位,表示上位機(jī)接下來(lái)發(fā)送的數(shù)據(jù)是用于對(duì)溫度上下限的修改。
fan_flag:風(fēng)扇控制信息標(biāo)識(shí),當(dāng)下位機(jī)接收到風(fēng)扇控制字符時(shí)該標(biāo)志位置位,表示上位機(jī)接下來(lái)發(fā)送的數(shù)據(jù)是用于對(duì)風(fēng)扇功率的修改。
fan_send_flag:用于屏蔽標(biāo)志字符,該位用于識(shí)別數(shù)據(jù)是控制字符還是實(shí)際控制信息。
temp_send_flag:用于分辨上下限或標(biāo)志字符,當(dāng)該位為0時(shí)表示目前數(shù)據(jù)為標(biāo)志位,不予處理;當(dāng)該位為1時(shí)表示目前數(shù)據(jù)是用于溫度上限修改;當(dāng)該位為2是表示目前數(shù)據(jù)是用于溫度下限修改。
temp_draw:實(shí)時(shí)溫度連續(xù)發(fā)送的標(biāo)志,當(dāng)上位機(jī)timer2控件工作時(shí)每次發(fā)送控制字符改為置位,并返回實(shí)時(shí)溫度值,最后復(fù)位。
3.2.4定時(shí)器設(shè)置
定時(shí)器以1s的周期采集溫度并更新存儲(chǔ)的溫度值,同時(shí)檢測(cè)當(dāng)前溫度是否超出溫度上限或溫度下限,如果超出,向上位機(jī)發(fā)出警告。
本次設(shè)計(jì)是我第一次將C#和ARM架構(gòu)的單片機(jī)用于實(shí)際項(xiàng)目中。在整個(gè)設(shè)計(jì)過(guò)程中也遇到了許多問(wèn)題。以下是對(duì)于一些問(wèn)題的總結(jié):
(1)問(wèn)題:定時(shí)器中斷的初始化放在PWM輸出的初始化之前則PWM波無(wú)法正常輸出
解決辦法:調(diào)換語(yǔ)句位置
問(wèn)題:當(dāng)指示風(fēng)扇功率的LED功率最大時(shí)風(fēng)扇功率最小
解決辦法:在控制信號(hào)接入風(fēng)扇控制端前加上反向器。由于LED為共陽(yáng)連接,當(dāng)單片機(jī)控制端輸出低電平時(shí)LED工作,然而此時(shí)控制電路的三極管導(dǎo)通,MOS柵極電壓較低,無(wú)法導(dǎo)通,風(fēng)扇不工作。
(3)問(wèn)題:上位機(jī)定時(shí)設(shè)置返回后無(wú)法讀取設(shè)定值
解決辦法:根據(jù)存儲(chǔ)在字符串中的時(shí)間信息進(jìn)行處理
(4)問(wèn)題:上位機(jī)定時(shí)時(shí)間顯示不正常,年月日變化長(zhǎng)度變化
解決辦法:先獲取系統(tǒng)時(shí)間日期的長(zhǎng)度,再根據(jù)這個(gè)長(zhǎng)度來(lái)截取字符串
(5)問(wèn)題:上位機(jī)實(shí)時(shí)溫度數(shù)組無(wú)法正常刷新
解決辦法:每次接收到溫度值并刷新數(shù)組后將緩沖區(qū)清空
(6)問(wèn)題:上位機(jī)定時(shí)功能有時(shí)無(wú)法實(shí)現(xiàn)
解決辦法:更改定時(shí)時(shí)間選擇下拉框初始化程序。為了美觀,當(dāng)時(shí)間選擇為個(gè)位數(shù)時(shí)默認(rèn)在前面加上“0”,但由于系統(tǒng)時(shí)間的小時(shí)位為個(gè)位時(shí)不會(huì)自動(dòng)補(bǔ)“0”,因此當(dāng)系統(tǒng)時(shí)間的小時(shí)為0~9時(shí)無(wú)法正常完成比較,因此定時(shí)功能無(wú)法實(shí)現(xiàn)。
問(wèn)題:WIFI模塊無(wú)法正常完成數(shù)據(jù)透?jìng)?br />
解決辦法:設(shè)為AP模式的模塊與下位機(jī)相連,設(shè)為STA模式的模塊與上位機(jī)相連。
問(wèn)題:PWM波輸出IO口最低電平2.2V風(fēng)扇無(wú)法工作
解決辦法:將上位機(jī)送來(lái)的功率值乘三作為PWM波占空比。PWM輸出在初始設(shè)置時(shí)占空比值為0~300,而上位機(jī)送來(lái)的功率值只是0~100,乘三后才能對(duì)應(yīng)。
在之前的設(shè)計(jì)中,我一直使用現(xiàn)成的通用上位機(jī)軟件,只能通過(guò)文本框?qū)⒑?jiǎn)單的數(shù)字或字符命令發(fā)送給下位機(jī)并顯示下位機(jī)的返回信息。在自己動(dòng)手編寫(xiě)上位機(jī)軟件之后,我對(duì)這一工具有了新的認(rèn)識(shí),思維也得到了開(kāi)闊。上位機(jī)軟件不僅可以發(fā)送命令,接受顯示信息,還能輔助下位機(jī)完成一定的工作。例如在本設(shè)計(jì)中,對(duì)于實(shí)時(shí)溫度的采集,我采用的是上位機(jī)軟件中的timer控件,而不是下位機(jī)的定時(shí)器。這樣既可以減輕下位機(jī)的負(fù)擔(dān),也省去了下位機(jī)定時(shí)器復(fù)雜配置的步驟。
相比較之前一直使用51單片機(jī)而言,這次使用STM32也是一個(gè)不小的變化。雖然STM32的使用比51單片機(jī)復(fù)雜許多,但它的功能確實(shí)比51單片機(jī)強(qiáng)大許多。例如定時(shí)器,51單片機(jī)只有三個(gè)定時(shí)器,如果需要使用一個(gè)定時(shí)器輸出PWM波,那么剩下的兩個(gè)定時(shí)器對(duì)于功能較為復(fù)雜的系統(tǒng)而言就顯得捉襟見(jiàn)肘。而STM32的8個(gè)定時(shí)器完全足夠滿足一般的系統(tǒng)設(shè)計(jì),而且STM32能夠通過(guò)較簡(jiǎn)單的設(shè)置完成PWM波的輸出。
本次設(shè)計(jì)的功能仍有不足之處。例如溫度曲線的顯示,目前只做到了實(shí)時(shí)溫度的采集以及簡(jiǎn)單顯示,沒(méi)有繪制出坐標(biāo)軸,也不能根據(jù)數(shù)據(jù)的多少來(lái)調(diào)整坐標(biāo)。而且控制面板的布局也不盡合理,實(shí)時(shí)溫度曲線的顯示部分并不是與其他功能同時(shí)使用,因此可以設(shè)計(jì)彈窗顯示以精簡(jiǎn)控制面板。不過(guò)就實(shí)時(shí)溫度采集以及用于存儲(chǔ)實(shí)時(shí)溫度值的數(shù)組更新我已經(jīng)花費(fèi)了大量的時(shí)間調(diào)試,在此過(guò)程中我對(duì)于VS2012的調(diào)試功能有了進(jìn)一步的掌握。
本次設(shè)計(jì)實(shí)現(xiàn)的控制功能比較簡(jiǎn)單,但我從中學(xué)到了很多,尤其是C#程序設(shè)計(jì)。今后我會(huì)繼續(xù)使用這一工具,將上位機(jī)與下位機(jī)緊密結(jié)合,設(shè)計(jì)出更高效的系統(tǒng)。
C#源程序如下:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- using System.IO.Ports;
- using CCWin;
- namespace project4
- {
- public partial class Form1 : Skin_Mac
- {
- public Form1()
- {
- InitializeComponent();
- System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
- //label2.Text = DateTime.Now.ToString();
- timer1.Enabled = true;
- }
- private void button1_Click(object sender, EventArgs e)
- {
- try
- {
- serialPort1.Open();//打開(kāi)串口
- button1.Enabled = false;//打開(kāi)串口按鈕不可用
- button2.Enabled = true;//關(guān)閉串口按鈕可用
- }
- catch
- {
- MessageBox.Show("端口錯(cuò)誤,請(qǐng)檢查串口", "錯(cuò)誤");
- }
- }
- private void Form1_Load(object sender, EventArgs e)
- {
- int i;
- //初始化功率設(shè)置下拉框
- for (i = 1; i < 100; i++)//百分比范圍(1-99)
- {
- comboBox1.Items.Add(i.ToString() + " ﹪");
- }
- comboBox1.Text = "1 ﹪";//設(shè)置默認(rèn)值
- //初始化溫度上限設(shè)置下拉框
- for (i = 0; i < 100; i++)//溫度上限范圍(0-99)
- {
- comboBox2.Items.Add(i.ToString() + " ℃");
- }
- comboBox2.Text = "30 ℃";
- //初始化溫度下限設(shè)置下拉框
- for (i = 0; i <= 99; i++)//溫度下限范圍(0-99)
- {
- comboBox3.Items.Add(i.ToString() + " ℃");
- }
- comboBox3.Text = "0 ℃";
- //初始化定時(shí)時(shí)間設(shè)置下拉框
- // (特別說(shuō)明)當(dāng)數(shù)字不超過(guò)10的時(shí)候默認(rèn)只有一位,為了與系統(tǒng)時(shí)間格式相同,在0~9前加上字符串"0"
- //此處不能加"0",若加上"0"則與系統(tǒng)時(shí)間不匹配,無(wú)法順利完成比較
-
- //設(shè)置時(shí)間與系統(tǒng)時(shí)間保持一致既是為了美觀,也是為了便于比較
- for (i = 0; i < 10; i++)
- {
- comboBox4.Items.Add(i.ToString());
- }
- for (i = 10; i < 24; i++)
- {
- comboBox4.Items.Add(i.ToString());
- }
- comboBox4.Text = "00";
- for (i = 0; i < 10; i++)
- {
- comboBox5.Items.Add("0" + i.ToString());
- }
- for (i =10; i < 60; i++)
- {
- comboBox5.Items.Add(i.ToString());
- }
- comboBox5.Text = "00";
- for (i = 0; i < 10; i++)
- {
- comboBox6.Items.Add("0" + i.ToString());
- }
- for (i =10; i < 60; i++)
- {
- comboBox6.Items.Add(i.ToString());
- }
- comboBox6.Text = "00";
- serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);//添加事件處理程序
- }
- //當(dāng)開(kāi)始繪制溫度曲線時(shí),將該標(biāo)志位置位,刷新溫度數(shù)組
- bool temp_show_flag = false;
- //溫度數(shù)組
- int[]temp_data=new int[100];
- //下位機(jī)將溫度分為三部分發(fā)送過(guò)來(lái),該標(biāo)志位用來(lái)識(shí)別溫度值的各部分
- int temp_data_flag = 0;
- //存儲(chǔ)溫度值各部分的數(shù)組
- int[] data = { 0,0,0};
- //當(dāng)串口接受到下位機(jī)發(fā)過(guò)來(lái)的數(shù)據(jù)時(shí)將其顯示在文本框中
- private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
- {
- if (temp_show_flag == false)
- {
- string str = serialPort1.ReadExisting();//字符串方式讀
- textBox1.AppendText(str);//添加內(nèi)容textBox文本框中依次向后顯示
- }
- else
- {
- //int len = this.serialPort1.ReadBufferSize;
- //string str = serialPort1.ReadExisting();//字符串方式讀
- //textBox1.AppendText(str+" "+'a');
- //string s0 = str.Substring(0, 1);
- //string s1 = str.Substring(1, 1);
- //string s2 = str.Substring(2, 1);
- //byte[] buf = new byte[3];
- //buf[0] = Convert.ToByte(s0, 16);
- //buf[1] = Convert.ToByte(s1, 16);
- //buf[2] = Convert.ToByte(s2, 16);
- //this.serialPort1.Read(buf, 0, 3);
- //data[0] = Convert.ToInt16(buf[0]);
- //data[1] = Convert.ToInt16(buf[1]);
- //data[2] = Convert.ToInt16(buf[2]);
- //data[0] = (data[0] - 48) * 100 + (data[1] - 48) * 10 + (data[2] - 48);
- //int i;
- //for (i = 0; i < 99; i++)
- //{
- // temp_data[i] = temp_data[i + 1];
- //}
- //temp_data[99] = data[0];
- //textBox1.AppendText(buf[0].ToString());
- //textBox1.AppendText("\n");
- //textBox1.AppendText(buf[1].ToString());
- //textBox1.AppendText("\n");
- //textBox1.AppendText(buf[2].ToString());
- //textBox1.AppendText("\n");
- if (temp_data_flag == 0)
- {
- data[0] = serialPort1.ReadByte();
- temp_data_flag++;
- }
- else if (temp_data_flag == 1)
- {
- data[1] = serialPort1.ReadByte();
- temp_data_flag++;
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
單片機(jī)源程序如下:
- #include "led.h"
- #include "delay.h"
- #include "sys.h"
- #include "usart.h"
- #include "timer.h"
- #include "pwm.h"
- #include "DS18B20.h"
- int main(void)
- {
-
- delay_init(); //延時(shí)函數(shù)初始化
- NVIC_Configuration();// 設(shè)置中斷優(yōu)先級(jí)分組 確定每個(gè)中斷的優(yōu)先級(jí)在uart_init中實(shí)現(xiàn)
- uart_init(9600); //串口初始化為9600
- LED_Init(); //初始化與LED連接的硬件接口
- TIM1_PWM_Init(299,0);//不分頻。PWM頻率=72000/(299+1)=240Khz
- TIM3_Int_Init(9999,7199);//10Khz的計(jì)數(shù)頻率,計(jì)數(shù)到10000為1s
-
- // LED0=0;
- while(1)
- {
- TIM_SetCompare1(TIM1,fan_rate);
-
- if(LED_model==1)
- {
- LED1=0;
- delay_ms(500);
- LED1=1;
- delay_ms(500);
- LED1=0;
- delay_ms(500);
- LED1=1;
- delay_ms(500);
- }
- else if(LED_model==2)
- {
- LED1=0;
- delay_ms(1000);
- LED1=1;
- delay_ms(1000);
- // printf("mark\r\n");
- }
- else if(LED_model==3)
- {
- LED1=0;
- }
- else if(LED_model==4)
- {
- LED1=1;
- }
- }
- }
復(fù)制代碼
代碼下載:
C#寫(xiě)的溫度.7z
(3.44 MB, 下載次數(shù): 138)
2022-5-5 03:24 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|