一. 摘要前端
這篇文章詳細介紹了一個「多路信號採集系統」的開發過程。「多路信號採集系統」是一個可伸縮的信號採集系統,通道能夠選擇從0~100路不一樣的信號源。單個採集板都可以採集10路數據,用戶能夠根據本身的需求方便地擴展或者收縮信號通道數。本系統能夠用於常見的民用或者工業現場監控、儀器儀表等數據採集場合。該系統基於Arm Context M3內核處理器實現,有基板和採集板兩大部分組成,基板主要負責整個採集時序的控制,而採集板則完成真是的數據採集並將採集到的數據發送到數據總線,進而傳輸到主機端。數據傳輸採用了串口通訊的方式(RS485),並採用Modbus協議實現,從而方便地實現了採集板地址的檢索、數據量控制、以及CRC校驗值肯定等功能。軟件系統則採用了固件庫編程的方式,全程開發均使用C語言完成,從而爲之後升級作好準備。開發使用了今日標企業工做平臺以及Github代碼託管平臺相結合完成開發的方式,使用今日標企業工做平臺管理項目開發流程,而使用Github則方便地實現了不一樣地區開發者協做開發的目的。而系統調試則選擇了傳統的調試方式,先進行單個功能模塊測試,再測試系統功能,進而Burning實驗。
二. 本文提綱git
1. 摘要
2. 本文提綱
3. 項目起始
4. 開發方式選擇
5. 系統構架
6. 硬件設計
7. 軟件設計
8. 系統調試
9. 總結
三. 項目起始github
該系統是應蘭州交通大學自動化研究所(一下簡稱爲研究所)的項目需求進行開發。項目開始的時候談的最多的問題主要有兩個,一個是「錢」的問題,還有一個就是項目需求了。至於錢最後的商定結果爲,天佑電子有限公司(如下簡稱天佑)只負責產品研發,開發過程當中全部的元器件、材料、以及測試系統的全部成本均由研究所承擔,而天佑則只承擔人力成本。最後研究所應該支付天佑XXX研發費用。因爲之前有過不少次的合做經歷了,因此談判過程也比較順利,也沒有書面的合同約束雙方。不過這也僅僅創建在雙方已經有過不少次的合做經歷,彼此都是很熟的人,項目自己技術上沒有太大的複雜度,並且最終產品的應用場合也不會形成大的損失的基礎之上。不過通常的項目合同是很重要的一個方面,合同不只僅爲雙方的行爲創建起了約束,並且若是項目失敗等形成損失,雙方也可以明確本身的責任。至於項目需求,則只有如下幾點需求:
1. 信號通道數必須在50~100路之間(可伸縮)
2. 單路信號偏差限定在0.03V以內
3. 數據傳輸使用485協議
4. 數據協議遵循Modbus協議
5. 傳送數據中必須包含數據量以及CRC校驗值
6. 上電或者數據傳送過程都須要有相應的指示燈指示其狀態
項目自己是個很簡單的項目,幾乎沒有技術上的難點。產品需求也一目瞭然,看了項目需求以後解決方案就已經呼之欲出了。經初步分析,整個設計過程當中惟一可能須要仔細斟酌的也就是多個板子之間通訊時的時序問題,事實證實,這部分到後面的確測試了挺長時間才實現功能,並且測試了好多邊界條件才最終肯定下來最後的最優化參數。
四. 開發方式選擇編程
項目的開發方式選擇了「今日標企業工做平臺」和Github結合進行開發的方式。
在本次開發中使用金目標的目的在於管控項目開發流程,實現整個開發過程簡單的文檔化。雖然該開發過程與如今所倡導的敏捷開發模式相違背,可是考慮到目前咱們的開發條件,最後仍是決定使用傳統的文檔化開發模式。在本次開發中因爲參與開發的主要人員在不一樣的地方(軟件開發在江蘇,而硬件開發在廣東),形成了溝通上的諸多不便,而文檔化則會改善一些溝通上的困難。將全部的開發過程都存放在一個公共平臺上,你們能夠隨時查閱。這樣也最大化地下降了溝通歧義所帶來的項目風險。
衆所周知,Github是一個不只強大並且簡單易用的分佈式代碼託管平臺。對於不一樣地域開發人員之間的協做開發來講,擁有一個強大的代碼共享平臺相當重要。而Github恰好知足這些需求:
1. 多方開發人員同時參與一個工程的開發
2. 平臺必須是分佈式的,開發人員同時必須能編輯同一個文件
2. 整個調試過程當中各個開發人員的代碼必需要保持一致
五. 系統架構安全
系統架構
系統設計時考慮到可伸縮性,以及採集通道要求太多,故而將數據採集任務分給多個採集板去完成。每一個採集板各自完成本身的採集任務,並將採集到的數據傳送到數據總線。而具體的什麼時候採集數據,以及什麼時候傳送數據到數據總線並交給PC段,則有Base Board控制。在這裏設計的時候並無將採集到的數據由Base Board傳送到PC上,而是放到數據總線上直接由PC提取。這種設計是基於如下考慮,若是全部採集到的數據全都交由Base Board向上傳送,則至關於多了一級路由,這樣會下降整個系統的數據採集速率。也加劇了Base Board的工做任務,使其控制邏輯變得複雜,嚴重違背「簡單即爲美」的編程原則。
六. 硬件設計數據結構
有關硬件設計的部分,因爲我本人對於硬件不是很擅長,因此可能總結很差。故而請了咱們團隊中的另外一位硬件工程師撰寫。在這裏我就只上兩張設計的電路圖。
採集板電路圖
基板電路圖
七. 軟件設計架構
在本系統中軟件設計分爲兩個部分,採集板軟件設計和基板軟件設計。下面分別就這兩方面介紹整個軟件開發的過程。
1. 採集板軟件設計:
在肯定了採集板功能的狀況下再開始軟件設計。本次設計中採用了「從兩端到中間」的軟件開發模式。所謂「從兩端到中間的開發模式」是指在軟件開發過程當中,首先按照軟件的架構層次習慣,將軟件分爲前端界面、中間邏輯控制層、以及底層的模型層(這是PC軟件的開發框架)。而對於咱們嵌入式軟件來講,也能夠分爲相似的層。我在此次開發過程當中,則是將整個軟件分爲:業務邏輯、中間件、以及底層驅動模型。而從兩端到中間的開發則是指先開發底層驅動,而後再肯定 業務邏輯 ,而後經過中間件將兩個部分銜接起來,並進行測試的方法。
首先根據需求肯定軟件中須要使用到的底層硬件驅動分別有:AD、USART、DMA、GPIO、外部硬件中斷。而在嵌入式系統中,通常還須要一些延時之類的功能,故而還須要提供一些延時函數的驅動。下圖顯示的是本次設計中用到的全部驅動,雖然開發過程選擇了使用STM32官方提供的固件庫編程方式,可是若是徹底使用固件庫中的函數,而沒有通過封裝。則主函數將會顯得很臃腫,並且整個軟件系統的業務邏輯和底層驅動也嚴重耦合在一塊兒,不便於之後系統維護、升級,也會大大下降系統的可移植性。
這裏的驅動設計,其實從本質上來說的話只是對固件庫中的一些函數或者是宏定義進行進一步的封裝。例如ADC部分的驅動,在~/ADC/adc.c文件中只須要系統一個Adc_Init函數,在該函數中完成對CPU ADC資源的初始化。而對應的USART設備。不只要提供初始化函數,還須要提供一些發送數據以及接收數據等的函數。並且爲了調試方便期間,通常按照我我的的習慣的話還會添加一部分代碼,用以支持printf函數,利用該函數經過串口向PC端,打印出一些程序執行的信息,這樣會大大方便嵌入式軟件調試。對於STM32來講,要支持printf函數只須要加入如下代碼:
驅動文件列表
完成了驅動程序的設計以後,則設計業務邏輯。 業務邏輯 是指從用戶需求的角度完成用戶須要的功能的一部分代碼。這部分代碼通常都是指Main函數中的邏輯。在這次設計中主要的執行流程可使用如下的圖表示。
業務邏輯
最後設計的是中間件,中間件的設計不只要考慮到業務邏輯的需求,更要兼顧底層驅動模型的實現方式。只有將這二者比較好地結合起來,最終才能獲得比較理想的產品。
從底層往上層看,中間件是對底層驅動更高一級的封裝,底層驅動只是實現獨立的單個功能點。而經過中間件不只實現了這些功能點,並且融入了一部分系統功能的成分在裏面。從上層往底層看,中間件則能夠理解成對於系統業務邏輯的細化。業務邏輯相似於將用戶需求文本化或者「代碼化」,從本質上來說,它仍是在用戶需求一級。而經過中間件的做用,則將抽象的業務邏輯實現了具體化,成爲對於處理器來講可以識別並執行的真實代碼。
以上就是採集板的整個軟件開發思路以及開發過程,這裏的程序從其流程來看,的確是幾乎沒有複雜度。可是在這裏提出了一些軟件開發過程當中的框架,一種分層機制。框架的出現將系統級的軟件分紅各個不一樣的模塊,或者分爲不一樣的層。從而實現了軟件良好的可維護性,也大大方便了後期系統升級。對於軟件框架的理解,我也只是一個初學者,在這裏提出權當是拋磚引玉了吧。
1. 基板軟件設計:
從軟件的角度來說,基板是整個系統時序的控制者。就彷彿人的大腦通常,它能夠發出各類指令讓系統的各個部分可以各司其職,而不會致使系統紊亂。本次設計中,基板主要的工做流程以下:
基板的主要工做流程
設計過程當中基板中有一個惟一值得注意的地方就是板子復位後在線板的檢測,在這個系統中掛在基板上的採集板的個數在0~10個之間是隨意的,而控制板發送採集信號命令的時候應該只對當前系統中已經掛載的採集板發送。故而在設計之時,軟件中設計了一個鏈表,你們知道鏈表是一個大小能夠動態分配的數據結構,因此咱們能夠講在線板的信息存儲在這個鏈表當中,而每次須要發送控制命令的時候只要遍歷整個鏈表,併發送控制命令便可。
八. 系統調試併發
在完成了系統硬件設計以及軟件設計以後,接下來的主要任務就是單個模組測試以及系統測試。測試過程主要地能夠分爲如下幾個部分:
1. 單個驅動功能點測試
2. 採集板功能測試
3. BaseBoard功能測試
4. 系統功能測試
5. 系統穩定性測試
下面分別介紹這次開發過程當中針對前面5個測試點的具體實現過程。
1. 單個驅動功能點測試:
單個驅動功能點測試是指在測試單個功能塊,好比在系統中用到的串口通訊模塊、GPIO模塊、中斷模塊等。包括硬件電路測試和軟件驅動測試。這部分的測試對於整個系統測試來講是一個基礎測試,但也是相當重要的部分。只有保證了全部單個功能點可以正確地工做才使得後續系統邏輯無誤成爲可能。根據前面的介紹,在本次設計過程當中,用到的全部驅動全都封裝在相應的驅動文件中,而且單個功能點都很是獨立。前面全部的驅動都可以獨立出來造成一個完整的測試用例。而個人作法則是先建立一個通用的測試模板(一個沒有實現任何功能只包含main函數的工程)。在測試過程當中只須要分別將須要測試的驅動移植到該測試工程中,而且在main函數中調用驅動中提供的函數進行測試便可。
2. 採集板功能測試:
在本系統中,採集板的主要任務是根據基板的控制命令,完成採集數據的動做,並將採集到的數據按照以前的協定進行整理,而後傳送到基板數據總線。因此對於基板的測試,則須要再使用一個模擬基板控制流程的電路板,或信號發生器之類的控制器。而個人作法是使用了一個51板,該板只完成產生一個定時跳變的功能。
採集板功能測試
3. BaseBoard功能測試
對於基板而言,測試的關鍵有兩個方面:
1> 檢測在線板,並將在線板信息保存在隊列中
2> 按照隊列中的信息,將控制信息發送到採集板中
其測試過程反而比較簡單,只須要將測試的信息所有經過串口發送到PC段,根據PC端的顯示信息便可判斷是否實現了須要的功能。可是在測試的過程當中發現了一個問題:串口要使用printf函數向上位機發送信息,則須要實現前面所示代碼,可是這部分代碼與工程中使用的malloc函數所在庫stdlib衝突,故而產生了編譯不過去的問題。也就是說在一個工程中這兩個功能只能使用其中一個。而malloc函數是實現雙向鏈表的關鍵,不能卻去掉。因此我選擇了本身實現一個向上位機發送字符串的方法。具體實現的代碼以下:
void Send_Data(USART_TypeDef* usartx, uint16_t data)
{
USART_SendData(usartx, data);
}
void Send_String(USART_TypeDef* usartx, char *str)
{
while(*str != '\0') //判斷字符串是否發送完畢
{
Send_Data(usartx, *str); //發送單個字符
str++; //字符地址加1,指向先下一個字符
delay_ms(5);
}
}
View Code
4. 系統功能測試
在完成了前面幾個部分的測試以後,對於後面系統功能測試,其實須要作的工做就少了不少。基本上只須要處理好整個系統工做時的時序便可。
測試的過程當中,首先不是將全部的採集板全都掛載到基板上去測試,而是隻掛載一個測試基板和採集板的協同工做是否正確。這部分的測試大概使用了4個小時的時間,期間調整了兩個板子同時上電後的時序,這個時序是經過延時來控制的。基本的流程是上電以後採集板完成系統初始化以後,置位在線信號(置位這個信號以後基板就可以檢測到採集板是否在線,若是採集板不在線,對應的端口呈現的狀態應該是低電平輸入),而後以個比較長的延時(我用了大概5S的時間),而基板則是完成初始化以後也是在一個比較長的延時(我選擇2S)以後,再檢測採集板的在線狀況。使用這樣的時序,就能夠保證只要整個系統同時上電,可以安全採集到在線採集板的信息。這裏雖然是一個比較簡單的邏輯,可是設計之時因爲忽略了兩個板子上電以後完成初始化的過程所使用的時間相差比較大,在通過了不少的測試,並評估以後仍是決定採用長延時這種安全的方式去處理上電後檢測採集板在線信息的任務。
完成了在線檢測以後,就可以肯定在線板的信息已經存在於前面設計的隊列之中了。後面須要測試的就是可否根據採集板的在線信息發送了控制指令以後採集板是否可以採集到數據並傳送上上位機上。經測試這部分的邏輯很容易實現,只要發送了控制信息,採集板就可以發送控制信息到上位機上,可是發送了信息以後對於基板而言,還須要作的工做是等待採集板給它發送閒信號。基板的設計使用了while等待的方式,發送完控制命令以後一直等待直到收到當前工做的採集板發送了閒信號給它以後才推出循環,再對下一塊採集板發送控制指令。如此循環,便能實現一直輪詢採集的任務。
在完成了單個採集板的系統測試以後,就須要測試同時掛載多個採集板時系統的工做狀況了。在測試的過程當中發現了一個問題,採集板的個數比較少的時候系統才能正常工做,可是當個數超過三個的時候指示燈顯示系統是在正常採集數據,可是485就是沒法接收到數據。懷疑爲全部模塊都爲發送使能,有多是相互之間的干擾形成數據通信異常,建議軟體方面改變使能端口狀態,當空閒時關斷使能,將總線釋放,用示波器實測AB輸出波形發現,當單個模塊介入系統,不進行數據通信時A爲「1」,B爲「0」,當進行數據通信時,A變爲「0」時,B將變爲「1」,高電平值3.3v,當接入2個模塊,不進行數據通信時A爲「1」,B爲「0」,當進行數據通信時,A變爲「0」時,B將變爲「1」,但A的低電平值變爲1.56v,而B的高電平值也變爲了1.56V。今後能夠推斷,非通信模塊要將A上拉的3.3V,B要下拉的0V,而通信的模塊想讓A變爲0V,B變爲3.3V,並聯的模塊越多,電平值越小,直至AB差分判斷失效,形成相互干擾。切記一點:但不使用總線時要釋放總線,防止相互干擾。
通過以上的測試,就可以肯定從功能的角度來說,系統是沒有問題了。穩定性還有待測試。
5. 系統穩定性測試
系統穩定性的測試,無外乎就是測試系統長時間的工做是否可以依然正常。由於系統長時間工做會形成系統發熱,而若是熱量太高,則有可能致使整個系統阻抗以及容抗等都發生變化,形成系統不能正常工做。經測試系統工做20小時以上功能依然可以知足,電源部分會有一點熱。通過再三考慮,最後仍是加了一個散熱風扇(使用了普通PC機上的散熱風扇)。再加了風扇以後發現電源部分的發熱現象明顯有了好轉。最後通過48小時的燒機實驗,肯定系統無誤!!!
九. 總結框架
以上就是整個此次《信號採集系統》的開發過程。就如在前文所說,這個系統是一個很簡單的系統,沒有任何技術難點可言。寫這篇博文,只是想拋磚引玉,但願你們之後能夠多推出相似的關於開發流程管理等的文章,你們共同窗習進步。在開發的過程當中確定還有不少不完善的地方,很是期待有這方面愛好的朋友可以提出寶貴的意見,以便我改進。最後再上幾張產品的圖片吧。