找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6257|回復: 3
打印 上一主題 下一主題
收起左側(cè)

C#寫的溫度檢測控制程序 上位機、STM32單片機下位機代碼

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1023010 發(fā)表于 2022-5-4 17:29 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
包含,上位機、下位機
程序界面:


電路原理圖如下:


智能家居是通過簡單的操作實現(xiàn)對家居的管理以提升家居便利性、舒適性的一種方式。本設(shè)計的主要功能是使用戶能夠在一定距離內(nèi)以無線的方式控制設(shè)備的開關(guān)、工作模式、工作功率等以及監(jiān)測實時室溫和室溫變化。
內(nèi)容和要求:
通過不同的按鈕控制設(shè)備工作在不同的模式
通過在用戶界面上的簡單操作實現(xiàn)對設(shè)備工作功率的調(diào)節(jié)
實現(xiàn)設(shè)備的定時開關(guān)
上位機顯示實時室溫以及溫度變化曲線
    本設(shè)計的硬件電路較簡單,主要是上位機與下位機的程序設(shè)計,難點在于上位機與下位機的通信協(xié)議設(shè)置以及下位機對硬件設(shè)備的控制。

  • 總體設(shè)計

1.1系統(tǒng)功能及框圖

    本設(shè)計功能主要是對風扇、LED兩個設(shè)備的控制以及通過溫度傳感器采集溫度實現(xiàn)實時溫度監(jiān)測。上位機和下位機通過wifi模塊實現(xiàn)一定距離內(nèi)的無線通信。上位機向下位機發(fā)送命令,下位機接受命令并直接控制各設(shè)備,然后向上位機返回一定的信息(下圖箭頭方向表示數(shù)據(jù)流動方向)。

圖1-1 總體框圖

1.1.1上位機

使用PC作為上位機,上位機控制軟件由基于WinForm的C#編寫。

首先,相比較VB.Net而言,C#支持無符號整數(shù),這對于需要頻繁與下位機交換正整數(shù)信息的上位機軟件而言是必須的;其次,VB 對大小寫不敏感,而C#是大小寫敏感的,對于習慣使用C語言編程的人而言C#更合適;最后,C#書寫的代碼比VB平均短小20%。

綜合考慮,本設(shè)計采用的編程語言是C#。


1.1.2單片機系統(tǒng)

單片機使用的是STM32F103RCT6。

首先,STM32使用3.3V電壓供電,本設(shè)計采用的wifi模塊也使用3.3V供電,相比較5V供電的51單片機而言,省去了電平匹配電路;其次,本設(shè)計需要輸出不同占空比的PWM波以控制設(shè)備的功率,STM32有2個16位的6通道高級控制定時器,最多6個通道可用于PWM輸出,符合設(shè)計要求。

1.1.3 LED

該綠色LED用來模擬可由單片機直接控制的小功率設(shè)備,有三種工作模式。

模式一:以1s為周期進行亮滅

模式二:以2s為周期進行亮滅

模式三:常亮


1.1.4風扇

    風扇工作需要較大的電流,無法使用單片機直接驅(qū)動,因此在單片機與風扇之間加入驅(qū)動電路以提高單片機的驅(qū)動能力。該風扇用來模擬無法直接用單片機驅(qū)動的大功率設(shè)備。

該風扇可以根據(jù)上位機的設(shè)置按一定的功率進行工作。LED(紅)用來指示風扇的功率。


1.1.5溫度采集

    傳感器使用的是溫度傳感器DS18B20。

DS18B20是美國Dallas半導體公司的新一代數(shù)字式溫度傳感器,它具有獨特的單總線接口方式,即允許在一條信號線上掛接數(shù)十甚至上百個數(shù)字式傳感器,從而使測溫裝置與各傳感器的接口變得十分簡單,克服了模擬式傳感器與微機接口時需要的A/D轉(zhuǎn)換器及其他復雜外圍電路的缺點,而且,可以通過總線供電,由它組成的溫度測控系統(tǒng)非常方便,而且成本低、體積小、可靠性高。DS18B20的測溫范圍-55~+125℃最高分辨率可達0.0625℃,完全符合本設(shè)計的要求。


1.1.6 wifi模塊

    本設(shè)計使用了兩個wifi模塊。一個與電腦通過串口相連,一個與下位機通過串口相連。兩個wifi模塊直接通過無線傳輸串口送來的數(shù)據(jù)。數(shù)據(jù)流通如下所示:

圖1-2 數(shù)據(jù)流通



1.2 通信協(xié)議方案

上位機向下位機發(fā)送的控制信息大部分是0—100的數(shù)字,要區(qū)分這些數(shù)字是作用于哪個設(shè)備的控制信息就需要設(shè)計上位機與下位機的通信協(xié)議。

方案一:上位機在發(fā)送數(shù)字指令前先將數(shù)字轉(zhuǎn)換成字符串,在該字符串前加上標志位,下位機接收到該字符串后去除標志位,并將剩余字符串轉(zhuǎn)化為數(shù)字。

方案二:上位機在發(fā)送數(shù)字指令前先發(fā)送字符指令,通過不同的字符指令使得下位機中對應(yīng)的標志位置位,其余標志位復位,再發(fā)送數(shù)字指令。下位機根據(jù)各標志位的狀態(tài)分辨出該數(shù)字指令是作用于哪個設(shè)備。

方案一不需要開辟內(nèi)存空間設(shè)置標志位,代碼量較少,上位機編程簡單,但下位機對字符串的處理難度較大。方案二代碼量大,需要的內(nèi)存空間較大,但編程思路簡單明了,易于實現(xiàn)。綜合考慮,本設(shè)計使用方案二。


1.3實時溫度采集方案

上位機實時溫度曲線的繪制需要實時采集溫度以更新用于繪制曲線的數(shù)組。

方案一:使用下位機的定時器,以1s為周期向上位機發(fā)送實時溫度值。

方案二:使用上位機的timer控件,以1s為周期想下位機發(fā)送請求,利用下位機的串口中斷獲取實時溫度值。

下位機定時器的初始化配置和開啟與關(guān)閉較為復雜,且新增一個定時器中斷也會影響下位機的工作性能。相比較而言,上位機的timer控件使用較簡單,而且獲取實時溫度使用的是下位機的串口中斷,不必新增中斷源。綜合考慮,本設(shè)計使用方案二。


  • 硬件設(shè)計

    硬件電路由STM32最小系統(tǒng)、DS18B20溫度采集、LED驅(qū)動、風扇驅(qū)動這四個部分組成。下圖為硬件原理圖。








圖2-1 硬件原理圖



2.1 STM32最小系統(tǒng)

最小系統(tǒng)是一個可以正常啟動和運行的單片系統(tǒng),該系統(tǒng)中任何部件都是完全必要的,缺一不可的。在微處理器其他所有的設(shè)計中,都包含這個最小系統(tǒng)。最小系統(tǒng)的復雜程度,表明了該處理器的單片化程度。


圖2-2 最小系統(tǒng)

圖2-2是一個最小系統(tǒng)圖,圖中包括電源、時鐘和復位電路。

  • 電源:STM32F1xx系列采用低電源工作,電源工作范圍是2.0~3.6V,常規(guī)設(shè)計一般選用3.3V電源。
  • 復位控制:復位控制雖然十分重要,但設(shè)計一般都很簡單。本設(shè)計采用按鍵復位。
  • 時鐘:時鐘是微處理器最重要的部分,時鐘的來源是振蕩器。在STM32F1xx系列產(chǎn)品中,其芯片內(nèi)嵌一個8MHz的RC振蕩器,在芯片上電復位以后,這個RC振蕩器首先起振,為系統(tǒng)提供時鐘源。但是芯片內(nèi)部的RC振蕩器精度不高,在需要高精度時鐘的場合還必須使用外部振蕩器。本設(shè)計中需要實現(xiàn)異步通信,因此需要外接振蕩器以提供高精度時鐘。

STM32F1xx系列有兩個外部振蕩器接口。

  • 系統(tǒng)主時鐘外部振蕩器接口

系統(tǒng)主時鐘是系統(tǒng)除看門狗以外所有功能的時鐘。這個時鐘既可以選內(nèi)部RC振蕩器作為時鐘源,也可以外部接一個時鐘源。本設(shè)計中使用外部8MHz的時鐘源而不使用內(nèi)部RC振蕩器以提高精度。

B.系統(tǒng)輔助時鐘外部振蕩器接口

輔助時鐘作為看門狗的時鐘源,也可以選作實時時鐘RTC的時鐘源。驅(qū)動輔助時鐘的振蕩器也有兩個,一個是內(nèi)部32kHz的RC振蕩器,另一個是外部32.768kHz的振蕩器接口。本設(shè)計中外接一個32.768kHz的晶體振蕩器以提供精確輔助時鐘。

2.2 DS18B20溫度采集

DS18B20的信號線接在PA0口,接收單片機的指令并向單片機返回所測溫度值。

圖2-3 溫度采集

上圖表明DS18B20與單片機的連接。



2.3 LED驅(qū)動

    LED1即上述的具有三種工作模式的LED,LED0與風扇共同受一個IO口控制,用以指示風扇的工作功率。

圖2-4 LED驅(qū)動

LED采用共陽連接,LED正極與上拉電阻相連,負極與IO口相連。


2.4風扇驅(qū)動

風扇用在原理圖中用DS3表示。

雖然風扇與LED0共同受一個IO口控制,但風扇功率較大,無法使用IO口直接驅(qū)動,需要增加驅(qū)動電路。

控制模塊工作原理:當單片機控制端加低電平時,三極管Q2導通,這時Q2的上端,也就是C極被系統(tǒng)拉到0V左右,這時MOS管Q1的G極為0V,所以此時MOS管的DS端不會導通。當單片機控制端加高電平時,三極管Q2不導通,這時Q2的上端,也就是C極電位為Vcc-R9兩端的壓降,電流穿過R8后被穩(wěn)壓管D3穩(wěn)壓在5V,則此時MOS管的G極電壓為5V,所以MOS管導通,負載工作。


圖2-5 風扇驅(qū)動


  • 軟件設(shè)計

軟件設(shè)計分為上位機程序和下位機程序兩個部分。上位機程序用C#編寫,采用事件觸發(fā)的方式便于用戶操作,主要功能是向下位機發(fā)送各種命令,并接受下位機的返回信息以一定方式顯示出來。下位機程序用C語言編寫,主要包括各設(shè)備的驅(qū)動程序以及與上位機通信的串口中斷程序。


3.1上位機程序

上位機界面控制部分由上位機控制、LED控制、風扇控制、溫度監(jiān)測和溫度曲線這五個部分組成。顯示部分包括當前時間與定時時間的顯示、信息返回(下位機返回的信息)、曲線繪制三個部分。

圖3-1 上位機整體框圖


3.1.1上位機控制

上位機控制部分總共有三個按鈕:打開端口、關(guān)閉端口和退出。

    考慮到該上位機專用于本次設(shè)計的下位機,也是為了簡化設(shè)計,端口號、波特率、數(shù)據(jù)位等屬性都在窗口載入時固定下來,無法在程序運行時進行修改。

圖3-2 上位機控制部分

    “打開端口”即打開默認端口。為防止打開端口時因為端口號或其他原因出現(xiàn)的問題使得程序拋出異常,在“打開端口”按鈕的觸發(fā)事件中加入了try-catch語句。

“關(guān)閉端口”即關(guān)閉當前打開的端口。當端口未打開時該按鈕設(shè)置為不可用,只有當有端口打開才可用!巴顺觥奔搓P(guān)閉當前窗體。


3.1.2 LED控制

    控制面板上的三個模式選擇按鈕對應(yīng)與上述的LED的三個工作模式。“關(guān)閉”按鈕即關(guān)閉LED。(模式一:以1s為周期進行亮滅;模式二:以2s為周期進行亮滅;模式三:常亮)

圖3-3 LED控制部分

該部分的標志字符是’a’。該部分的四個按鈕在按下后都會先發(fā)送’a’使下位機對相應(yīng)的標志位進行置位復位操作。然后再發(fā)送數(shù)字命令使下位機進入不同的模式。最后彈出對話框,解釋對應(yīng)模式的具體功能。


3.1.3風扇控制

    該部分由風扇控制和時間顯示兩部分組成?刂撇糠志哂锌刂骑L扇開關(guān)、工作功率以及定時功能。時間顯示部分主要是服務(wù)于定時功能。該部分顯示當前時間和定時時間,當兩者相同時執(zhí)行定時設(shè)置的操作。若未使用定時功能,則不顯示定時時間。

      

            圖3-4風扇控制部分                       圖3-5時間顯示部分

為節(jié)省窗體面板空間以及便于用戶使用,該部分進行了控件的層疊。

具體如下:

    (1)定時時間選擇框在初始加載時不可見,字符“時分秒”不可見,“定時開”“定時關(guān)”按鈕不可見,“設(shè)置完成”按鈕不可見。

    (2)單擊“定時設(shè)置”,“開”“關(guān)”按鈕不可見,定時時間選擇框可見,字符“時分秒”可見,“定時設(shè)置”按鈕不可見,“定時開”“定時關(guān)”按鈕可見,并彈出對話框“請選擇定時開或定時關(guān)”。

    a.單擊“定時開”,“定時開”“定時關(guān)”按鈕不可見,“設(shè)置完成”按鈕可見,彈出對話框“請設(shè)置開啟時間和功率”。

    b.單擊“定時關(guān)”,“定時開”“定時關(guān)”按鈕不可見,“設(shè)置完成”按鈕可見,彈出對話框“請設(shè)置關(guān)閉時間”。

    (3)單擊“設(shè)置完成”,“設(shè)置時間”可見,“開關(guān)控制”部分恢復原樣。

    時分秒以及功率調(diào)節(jié)的下拉框選項都是在窗體載入時初始化的。

    若不使用定時功能,則點擊“開”,設(shè)備按最大功率運行,點擊“關(guān)”,設(shè)備關(guān)閉,點擊“設(shè)置功率”,設(shè)備按設(shè)定的功率運行。該部分發(fā)送的標志字符是’c’。

若使用定時功能,具體操作如上所述。設(shè)置完成后設(shè)置的時間會在“定時時間”后的TIME處顯示,并與當前時間比較(當前時間為系統(tǒng)時間,由timer1每秒刷新一次),當兩者相等時timer控件會向下位機發(fā)送相應(yīng)的命令。


3.1.4溫度監(jiān)測

    該部分分為溫度檢測和溫度曲線兩個部分。第一部分可以設(shè)置溫度上下限以及查詢當前溫度。當溫度超過上限或下限時將發(fā)出相應(yīng)的警報。第二部分可以生成實時溫度曲線,用于直觀地顯示出溫度變化趨勢。

圖3-6 溫度檢測

    下拉框初始化與風扇控制部分相同。

    “溫限設(shè)置”按鈕用于向下位機發(fā)送溫限修改指令,即將下拉框中的溫度上限和溫度下限設(shè)置為下位機溫度的界限。

“溫度顯示”按鈕用于向下位機發(fā)送實時溫度查詢請求。下位機返回的實時溫度信息將顯示在“信息返回”部分的文本框中。

“溫限設(shè)置”的標志字符為’b’,“溫度顯示”的標志字符為’m’。

圖3-7 繪制溫度曲線

“繪制曲線”用于繪制曲線,按下后啟動timer2,每秒向下位機發(fā)送一次溫度采集請求,同時將數(shù)據(jù)讀取方式標志位置位(為方便下位機返回的信息顯示在文本框中,上位機默認使用字符方式讀取串口數(shù)據(jù),當需要繪制曲線時,要更改為使用字節(jié)方式讀取串口數(shù)據(jù),讀取方式由數(shù)據(jù)讀取方式標志位決定)。

從串口讀取到的數(shù)據(jù)經(jīng)過相應(yīng)算法處理后生成溫度曲線圖像顯示在圖片框中。該圖片框也由timer2控制,每秒刷新一次。

timer2溫度采集請求的標志字符為’t’。

“停止繪制”用于撤銷“繪制曲線”按鈕的操作。此時圖片框中顯示最后一次刷新出的圖片并保持。當再次啟動曲線繪制時圖片框清空重新繪制。


3.2下位機程序

下位機程序主要由以下幾個部分構(gòu)成:LED驅(qū)動程序(因為風扇與指示其功率大小的LED由同一個IO口控制,所以沒有專門的風扇驅(qū)動程序)、DS18B20驅(qū)動程序、PWM波生成程序、定時器設(shè)置程序、串口中斷服務(wù)程序。


3.2.1主函數(shù)

主函數(shù)完成各部分的初始化,完成風扇功率的設(shè)置以及控制LED工作在不同的模式下,其余功能由各中斷函數(shù)完成。


與LED相連的IO口設(shè)置為推挽輸出。LED的三種顯示模式均在主函數(shù)中完成,由標志位LED_model控制。該標志位由串口中斷服務(wù)程序根據(jù)上位機發(fā)送過來的數(shù)據(jù)進行置位或復位。
3.2.3串口通信
串口波特率為9600,數(shù)據(jù)位8位,1位停止位,無奇偶校驗位,無硬件數(shù)據(jù)流控制,采用收發(fā)模式。
串口中斷服務(wù)程序主要包括兩個部分:(1)根據(jù)上位機發(fā)送的信息對標志位進行置位或復位;(2)根據(jù)設(shè)置的標志位執(zhí)行相應(yīng)的操作。


串口中斷服務(wù)程序調(diào)用相當頻繁。
該程序讀取上位機發(fā)送過來的標志信息,對各標志位進行置位或復位操作,再根據(jù)上位機發(fā)送過來的數(shù)字信息修改相應(yīng)的變量。
該程序根據(jù)上位機發(fā)送過來的命令給出響應(yīng)信息,根據(jù)上位機的要求返回對應(yīng)的信息(例如溫度值)。            
以下為各標志位以及部分變量的解釋:
temp_trx:下位機從緩沖區(qū)讀取到的上位機數(shù)據(jù)。
   LED_model:LED模式,不同取值會使LED進入不同狀態(tài)。取值1到3表示三種工作模式,取值4表示熄滅。
   fan_rate:風扇功率。例如該變量取值50,則風扇以50%的功率工作。
   temp_show:溫度顯示標志,該標志位置位表示下位機接收到上位機采集單個溫度值的請求。
   LED_flag:LED控制信息標識,當下位機接收到LED控制字符時該標志位置位,表示上位機接下來發(fā)送的數(shù)據(jù)是用于對與LED相關(guān)的變量操作。
   temp_flag:溫度控制信息標識,當下位機接收到溫度上下限控制字符時該標志位置位,表示上位機接下來發(fā)送的數(shù)據(jù)是用于對溫度上下限的修改。
   fan_flag:風扇控制信息標識,當下位機接收到風扇控制字符時該標志位置位,表示上位機接下來發(fā)送的數(shù)據(jù)是用于對風扇功率的修改。
   fan_send_flag:用于屏蔽標志字符,該位用于識別數(shù)據(jù)是控制字符還是實際控制信息。
   temp_send_flag:用于分辨上下限或標志字符,當該位為0時表示目前數(shù)據(jù)為標志位,不予處理;當該位為1時表示目前數(shù)據(jù)是用于溫度上限修改;當該位為2是表示目前數(shù)據(jù)是用于溫度下限修改。
   temp_draw:實時溫度連續(xù)發(fā)送的標志,當上位機timer2控件工作時每次發(fā)送控制字符改為置位,并返回實時溫度值,最后復位。

3.2.4定時器設(shè)置
定時器以1s的周期采集溫度并更新存儲的溫度值,同時檢測當前溫度是否超出溫度上限或溫度下限,如果超出,向上位機發(fā)出警告。


本次設(shè)計是我第一次將C#和ARM架構(gòu)的單片機用于實際項目中。在整個設(shè)計過程中也遇到了許多問題。以下是對于一些問題的總結(jié):
(1)問題:定時器中斷的初始化放在PWM輸出的初始化之前則PWM波無法正常輸出
     解決辦法:調(diào)換語句位置
問題:當指示風扇功率的LED功率最大時風扇功率最小
     解決辦法:在控制信號接入風扇控制端前加上反向器。由于LED為共陽連接,當單片機控制端輸出低電平時LED工作,然而此時控制電路的三極管導通,MOS柵極電壓較低,無法導通,風扇不工作。
(3)問題:上位機定時設(shè)置返回后無法讀取設(shè)定值
     解決辦法:根據(jù)存儲在字符串中的時間信息進行處理
(4)問題:上位機定時時間顯示不正常,年月日變化長度變化
    解決辦法:先獲取系統(tǒng)時間日期的長度,再根據(jù)這個長度來截取字符串
(5)問題:上位機實時溫度數(shù)組無法正常刷新
     解決辦法:每次接收到溫度值并刷新數(shù)組后將緩沖區(qū)清空
(6)問題:上位機定時功能有時無法實現(xiàn)
     解決辦法:更改定時時間選擇下拉框初始化程序。為了美觀,當時間選擇為個位數(shù)時默認在前面加上“0”,但由于系統(tǒng)時間的小時位為個位時不會自動補“0”,因此當系統(tǒng)時間的小時為0~9時無法正常完成比較,因此定時功能無法實現(xiàn)。
問題:WIFI模塊無法正常完成數(shù)據(jù)透傳
     解決辦法:設(shè)為AP模式的模塊與下位機相連,設(shè)為STA模式的模塊與上位機相連。
問題:PWM波輸出IO口最低電平2.2V風扇無法工作
     解決辦法:將上位機送來的功率值乘三作為PWM波占空比。PWM輸出在初始設(shè)置時占空比值為0~300,而上位機送來的功率值只是0~100,乘三后才能對應(yīng)。
在之前的設(shè)計中,我一直使用現(xiàn)成的通用上位機軟件,只能通過文本框?qū)⒑唵蔚臄?shù)字或字符命令發(fā)送給下位機并顯示下位機的返回信息。在自己動手編寫上位機軟件之后,我對這一工具有了新的認識,思維也得到了開闊。上位機軟件不僅可以發(fā)送命令,接受顯示信息,還能輔助下位機完成一定的工作。例如在本設(shè)計中,對于實時溫度的采集,我采用的是上位機軟件中的timer控件,而不是下位機的定時器。這樣既可以減輕下位機的負擔,也省去了下位機定時器復雜配置的步驟。
相比較之前一直使用51單片機而言,這次使用STM32也是一個不小的變化。雖然STM32的使用比51單片機復雜許多,但它的功能確實比51單片機強大許多。例如定時器,51單片機只有三個定時器,如果需要使用一個定時器輸出PWM波,那么剩下的兩個定時器對于功能較為復雜的系統(tǒng)而言就顯得捉襟見肘。而STM32的8個定時器完全足夠滿足一般的系統(tǒng)設(shè)計,而且STM32能夠通過較簡單的設(shè)置完成PWM波的輸出。
本次設(shè)計的功能仍有不足之處。例如溫度曲線的顯示,目前只做到了實時溫度的采集以及簡單顯示,沒有繪制出坐標軸,也不能根據(jù)數(shù)據(jù)的多少來調(diào)整坐標。而且控制面板的布局也不盡合理,實時溫度曲線的顯示部分并不是與其他功能同時使用,因此可以設(shè)計彈窗顯示以精簡控制面板。不過就實時溫度采集以及用于存儲實時溫度值的數(shù)組更新我已經(jīng)花費了大量的時間調(diào)試,在此過程中我對于VS2012的調(diào)試功能有了進一步的掌握。
本次設(shè)計實現(xiàn)的控制功能比較簡單,但我從中學到了很多,尤其是C#程序設(shè)計。今后我會繼續(xù)使用這一工具,將上位機與下位機緊密結(jié)合,設(shè)計出更高效的系統(tǒng)。



C#源程序如下:
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.IO.Ports;
  10. using CCWin;

  11. namespace project4
  12. {
  13.     public partial class Form1 : Skin_Mac
  14.     {
  15.         public Form1()
  16.         {
  17.             InitializeComponent();
  18.             System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
  19.             //label2.Text = DateTime.Now.ToString();
  20.             timer1.Enabled = true;
  21.         }

  22.         private void button1_Click(object sender, EventArgs e)
  23.         {
  24.             try
  25.             {
  26.                 serialPort1.Open();//打開串口
  27.                 button1.Enabled = false;//打開串口按鈕不可用
  28.                 button2.Enabled = true;//關(guān)閉串口按鈕可用
  29.             }
  30.             catch
  31.             {
  32.                 MessageBox.Show("端口錯誤,請檢查串口", "錯誤");
  33.             }
  34.         }

  35.         private void Form1_Load(object sender, EventArgs e)
  36.         {
  37.             int i;

  38.             //初始化功率設(shè)置下拉框
  39.             for (i = 1; i < 100; i++)//百分比范圍(1-99)
  40.             {
  41.                 comboBox1.Items.Add(i.ToString() + " ﹪");

  42.             }
  43.             comboBox1.Text = "1 ﹪";//設(shè)置默認值

  44.             //初始化溫度上限設(shè)置下拉框
  45.             for (i = 0; i < 100; i++)//溫度上限范圍(0-99)
  46.             {
  47.                 comboBox2.Items.Add(i.ToString() + " ℃");

  48.             }
  49.             comboBox2.Text = "30 ℃";

  50.             //初始化溫度下限設(shè)置下拉框
  51.             for (i = 0; i <= 99; i++)//溫度下限范圍(0-99)
  52.             {
  53.                 comboBox3.Items.Add(i.ToString() + " ℃");

  54.             }
  55.             comboBox3.Text = "0 ℃";

  56.             //初始化定時時間設(shè)置下拉框

  57.             //          (特別說明)當數(shù)字不超過10的時候默認只有一位,為了與系統(tǒng)時間格式相同,在0~9前加上字符串"0"
  58.             //此處不能加"0",若加上"0"則與系統(tǒng)時間不匹配,無法順利完成比較
  59.             
  60.             //設(shè)置時間與系統(tǒng)時間保持一致既是為了美觀,也是為了便于比較
  61.             for (i = 0; i < 10; i++)
  62.             {
  63.                 comboBox4.Items.Add(i.ToString());
  64.             }
  65.             for (i = 10; i < 24; i++)
  66.             {
  67.                 comboBox4.Items.Add(i.ToString());
  68.             }
  69.             comboBox4.Text = "00";

  70.             for (i = 0; i < 10; i++)
  71.             {
  72.                 comboBox5.Items.Add("0" + i.ToString());
  73.             }
  74.             for (i =10; i < 60; i++)
  75.             {
  76.                 comboBox5.Items.Add(i.ToString());
  77.             }
  78.             comboBox5.Text = "00";

  79.             for (i = 0; i < 10; i++)
  80.             {
  81.                 comboBox6.Items.Add("0" + i.ToString());
  82.             }
  83.             for (i =10; i < 60; i++)
  84.             {
  85.                 comboBox6.Items.Add(i.ToString());
  86.             }
  87.             comboBox6.Text = "00";

  88.             serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);//添加事件處理程序
  89.         }

  90.         //當開始繪制溫度曲線時,將該標志位置位,刷新溫度數(shù)組
  91.         bool temp_show_flag = false;

  92.         //溫度數(shù)組
  93.         int[]temp_data=new int[100];

  94.         //下位機將溫度分為三部分發(fā)送過來,該標志位用來識別溫度值的各部分
  95.         int temp_data_flag = 0;


  96.         //存儲溫度值各部分的數(shù)組
  97.         int[] data = { 0,0,0};

  98.         //當串口接受到下位機發(fā)過來的數(shù)據(jù)時將其顯示在文本框中
  99.         private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
  100.         {
  101.             if (temp_show_flag == false)
  102.             {
  103.                 string str = serialPort1.ReadExisting();//字符串方式讀
  104.                 textBox1.AppendText(str);//添加內(nèi)容textBox文本框中依次向后顯示
  105.             }
  106.             else
  107.             {
  108.                 //int len = this.serialPort1.ReadBufferSize;
  109.                 //string str = serialPort1.ReadExisting();//字符串方式讀
  110.                 //textBox1.AppendText(str+" "+'a');
  111.                 //string s0 = str.Substring(0, 1);
  112.                 //string s1 = str.Substring(1, 1);
  113.                 //string s2 = str.Substring(2, 1);

  114.                 //byte[] buf = new byte[3];
  115.                 //buf[0] = Convert.ToByte(s0, 16);
  116.                 //buf[1] = Convert.ToByte(s1, 16);
  117.                 //buf[2] = Convert.ToByte(s2, 16);
  118.                 //this.serialPort1.Read(buf, 0, 3);

  119.                 //data[0] = Convert.ToInt16(buf[0]);
  120.                 //data[1] = Convert.ToInt16(buf[1]);
  121.                 //data[2] = Convert.ToInt16(buf[2]);
  122.                 //data[0] = (data[0] - 48) * 100 + (data[1] - 48) * 10 + (data[2] - 48);
  123.                 //int i;
  124.                 //for (i = 0; i < 99; i++)
  125.                 //{
  126.                 //    temp_data[i] = temp_data[i + 1];
  127.                 //}
  128.                 //temp_data[99] = data[0];
  129.                 //textBox1.AppendText(buf[0].ToString());
  130.                 //textBox1.AppendText("\n");
  131.                 //textBox1.AppendText(buf[1].ToString());
  132.                 //textBox1.AppendText("\n");
  133.                 //textBox1.AppendText(buf[2].ToString());
  134.                 //textBox1.AppendText("\n");

  135.                 if (temp_data_flag == 0)
  136.                 {
  137.                     data[0] = serialPort1.ReadByte();
  138.                     temp_data_flag++;
  139.                 }
  140.                 else if (temp_data_flag == 1)
  141.                 {
  142.                     data[1] = serialPort1.ReadByte();
  143.                     temp_data_flag++;
  144. ……………………

  145. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼


單片機源程序如下:
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4. #include "usart.h"
  5. #include "timer.h"
  6. #include "pwm.h"
  7. #include "DS18B20.h"

  8. int main(void)
  9. {
  10.          
  11.         delay_init();                     //延時函數(shù)初始化        
  12.         NVIC_Configuration();// 設(shè)置中斷優(yōu)先級分組 確定每個中斷的優(yōu)先級在uart_init中實現(xiàn)
  13.         uart_init(9600);         //串口初始化為9600
  14.         LED_Init();                           //初始化與LED連接的硬件接口

  15.         TIM1_PWM_Init(299,0);//不分頻。PWM頻率=72000/(299+1)=240Khz
  16.         TIM3_Int_Init(9999,7199);//10Khz的計數(shù)頻率,計數(shù)到10000為1s  
  17.          
  18. //         LED0=0;
  19.         while(1)
  20.         {

  21.                 TIM_SetCompare1(TIM1,fan_rate);        
  22.                
  23.                 if(LED_model==1)
  24.                 {
  25.                         LED1=0;
  26.                         delay_ms(500);
  27.                         LED1=1;
  28.                         delay_ms(500);
  29.                         LED1=0;
  30.                         delay_ms(500);
  31.                         LED1=1;
  32.                         delay_ms(500);
  33.                 }
  34.                 else if(LED_model==2)
  35.                 {
  36.                         LED1=0;
  37.                         delay_ms(1000);
  38.                         LED1=1;
  39.                         delay_ms(1000);
  40.         //                printf("mark\r\n");
  41.                 }
  42.                 else if(LED_model==3)
  43.                 {
  44.                         LED1=0;
  45.                 }
  46.                 else if(LED_model==4)
  47.                 {
  48.                         LED1=1;
  49.                 }
  50.         }         
  51. }
復制代碼

代碼下載: C#寫的溫度.7z (3.44 MB, 下載次數(shù): 138)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:1030595 發(fā)表于 2022-7-7 09:32 | 只看該作者
上位機什么語言編程工具,最好最方便?
回復

使用道具 舉報

板凳
ID:1060941 發(fā)表于 2023-1-11 15:27 | 只看該作者
duckyer 發(fā)表于 2022-7-7 09:32
上位機什么語言編程工具,最好最方便?

博主是基于WinForm的C#語言,比較容易上手
回復

使用道具 舉報

地板
ID:1060941 發(fā)表于 2023-1-12 15:46 | 只看該作者
請問下位機程序里LED_model是接收的上位機發(fā)送過來的數(shù)據(jù)嘛,請教下位機是如何處理這部分數(shù)據(jù)的
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表