STM32/GD32 DMX 發送/接收信號總結


1,背景介紹

  從事燈光行業的研發,總會碰到DMX,RDM,art-net,scan等等協議,其中使用最多的協議還是DMX協議.在該協議中有美標與中標之分,不過大家硬件上都使用的是RS485,波特率統一為250k/bps,8位數據位,2位停止位.  

  美標協議的具體內容,這里直接截圖上傳,方便直觀的做記錄與參考:(這里參考STM32官方給的UM1004 

文檔)

 

  可以看出,DMX信號特殊在開始位的Mark信號與Mark after break信號,這里要強調一下,STM/GD32是自帶Break信號產生單元的,不過可惜DMX沒有使用正常的Break信號.

  再來記錄中標的DMX信號,也是上圖:(標准參考WH/T 32-2008)

 

  綜合對比,發現中標與美標基本是一致的,最新的標准可以參考這個網站:https://tsp.esta.org/tsp/documents/published_docs.php在這里搜索DMX,可以發現,2019年出了新的標准,並添加了RDMnet規范,也就是加入了網絡DMX/RDM的最新標准.

  言歸正傳,DMX協議的規范,特殊在開始的幀頭部分,在實際使用中,發送端的難點是發送這個非標的Break信號,而接收端也是處理這個Break信號.按照正常的串口發送流程,應該是1位起始位,8位數據位,2位停止位,整個一幀數據發送完需要44us的時間.而Break信號標准至少需要88us的時間,也就意味着發送端口需要發送至少兩幀的低電平時間,STM32與GD32的Break控制單元是無法滿足這個時間(題外話LPC的單片機可以實現).那么這里就需要對STM32的引腳做特殊處理.

  如果DMX是512個通道的話,協議的后面是正常的513個字節數據(這里加上起始位的1位數據),當然按照協議可以延伸到1025,2049個字節數據,將DMX的地址擴展到1024,2048個通道.每個字節之間的間隔時間,協議規定不超過1s.

 2,實現思路

  在使用STM32/GD32實現該協議的方法上,總結網上與實際經驗,整體上有一下幾種方式:

  1.一種是串口配置為9位數據位,1位停止位,發送端在發送break信號時配置為普通IO模式,發送數據時最高位進行或0x100運算.此辦法優點是方便接收與發送同時處理,在接收時只需要檢測最高位是否為1,並在接收到一個數據時判斷接收的數據是否為0,以此來確認接收到Break信號.缺點就是無法使用單片機的DMA功能,發送與接收將消耗單片機大約25ms左右的時間.只能使用循環發送與接收的方式,等待數據發送完成與接收完成.

  2.一種是串口配置為8位數據位,2位停止位,發送端在發送break信號時配置為普通IO模式,正常發送時配置為串口模式..此辦法優點是解放了單片機的發送等待時間,只需要在DMA發送完成中斷里檢測發送完成即可.缺點是在接收時,不方便處理Break信號的識別,一種可行的識別方式是打開單片機的幀錯誤中斷,在檢測到該中斷時開啟DMA接收功能.但是如果是正常的DMX512信號的話接收的數據長度將會是514個字節,需要人為剔除第一個錯誤數據,第二個0數據起始碼.

  3.一種是串口配置為上述1.2任意模式,在接收端再引入一個單片機的定時器捕獲引腳,發送時數據正常發送.接收時,利用單片機的定時器的捕獲功能,捕獲這個特殊的Break信號,捕獲到正常的低電平時間在88us以上,以及Mark after break的8us以上,則任務開始正常接收.(注:STM32官方給的參考方式用了兩個定時器捕獲通道).

  4.一種是串口配置為上述1.2任意模式,在接收端再引入一個引腳,接單片機外部中斷,中斷設置為上升沿與下降沿觸發,再外加一個1us的定時器,計算上一個下降沿到下一個上降沿的間隔時間,如果操過88us以上,再堅持到下一個下降沿時間間隔在8us以上,認為檢測到Break與Mark after break信號,后面數據串口接收進行識別即可.

  5.一種是單純的發送DMX信號,利用定時器->dma->gpio,定時器4us計算一次,直接使用DMA控制GPIO口翻轉,實現模擬的串口,這種方式不考慮接收,可最多模擬出16路DMX串口輸出.

  這里貼出以上思路的幾個參考鏈接:

  1.https://en.wikipedia.org/wiki/DMX512

  http://www.openedv.com/thread-44810-1-1.html

  https://www.amobbs.com/forum.php?mod=viewthread&tid=4991795

  https://www.amobbs.com/thread-4810567-1-1.html

  http://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&ordertype=1&tid=615237

  2.http://www.stm32cube.com/article/52

      (下面這個使用空閑中斷檢測DMX接收信號,個人認為不夠嚴謹,不過配置可以參考)

  https://bbs.21ic.com/forum.php?mod=viewthread&tid=450252&extra=&page=1&mobile=2

  http://archive.ednchina.com/group.ednchina.com/GROUP_MES_14350_306_58521.HTM

  3.https://github.com/xhpohanka/dmx_dimmer/tree/master

  第4種與第5種目前考慮工作原因,這里就不做記錄了

 3,總結

  個人認為,使用STM32/GD32發送與檢測DMX信號,做的最穩定的方式,還是在發送端使用DMA發送,解放CPU等待發送完成時間,這25ms的時間CPU可以做很多時間了在接收端,多引出一個引腳,將該引腳的盡可能配置為最高優先級,外加一個定時器,計算采集時間,同時該定時器可以用作1us計時單位,用作發送break信號與mark after break的延時基准,同時在檢測到標准的開始時間后,再啟動DMA接收,這樣就解放了串口接收完成中斷,省去了CPU頻繁進入接收完成中斷.這樣做的目的還有一個好處,在檢測端適配市面上各個廠家不同的發送端裝置時,可以進行大范圍適配不同發送端break時間.

  另外,其實使用LPC系列的單片機,就不用這么費勁考慮break信號,LPC系列單片機自帶Break信號產生單元,可以很好的控制break信號的產生與檢測.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM