中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Marlin固件的步進電機控制代碼解析

發布時間:2020-07-19 13:23:06 來源:網絡 閱讀:19734 作者:Raevo 欄目:開發技術

    對于入行一年的我來說,桌面級FDM打印機很多功能細節,我還沒能仔細了解:藏在固件代碼背后的信息內容,我也遠沒有完全消化。這正說明一個簡單的道理:消化一段代碼的最有效方法是對其移植或者重寫。換言之,僅僅是走馬觀花的瀏覽一遍,除非自己曾經編寫過類似程序,很難能透徹的領會固件代碼的精髓。特別是對Marlin這個數百名(可能不準確)開源工程師貢獻和維護的大型固件項目。

    Marlin的步進電機驅動子系統,是由中斷響應函數實現的。如果是恒定速度的步進電機驅動,實現就和這句話一樣簡單。不過對于3D打印機系統,x,y軸的運動往往速度變化非常頻繁:不僅在每次更新位置的速度不同,而且每一段位移的速度也需要經歷加速,恒速和減速階段。這是由機械系統的慣性特征決定的:如果不同動作之間的速度銜接不好,會對電路系統造成強大的電流沖擊。特別是3D打印過程,這種速度的變化每次打印任務都數以萬計,這就意味著電路壽命將大打折扣。

    Marlin系統的速度銜接,基于leib Ramp Algorithm[1],這是一個支撐步進電機速度和控制器計數器頻率關系的算法理論,由IBM的工程師于1994年發表并于2004年在控制器內實現。這里算法實現的關鍵在于路徑規劃器(planner)。路徑規劃器的設計意味著,程序在執行步進電機的動作之前,就已經計算好了整個過程的速度曲線。后面就只是Stepper模塊忠實地執行。

    在機器層面,這樣的設計減少了中斷響應函數中的運算量,這對于單片機來說非常友好。同時3D打印機的機械運動相比控制器的16M主頻來說要慢很多,路徑規劃器相比直接驅動,增加了一個運動緩存。這樣就能夠有效的利用控制器的高頻率,里面蘊藏著“空間換取時間”的思想。

    在代碼層面,planner的本質在于對于一個FIFO的管理。使用C++的結構體指針數據結構能夠非常優雅的實現這個緩存的創建和管理:planner.h:

typedef struct {
  // Fields used by the bresenham algorithm for tracing the line
  long steps_x, steps_y, steps_z, steps_e;  // Step count along each axis
  unsigned long step_event_count;           // The number of step events required to complete this block
  long accelerate_until;                    // The index of the step event on which to stop acceleration
  long decelerate_after;                    // The index of the step event on which to start decelerating
  long acceleration_rate;                   // The acceleration rate used for acceleration calculation
  unsigned char direction_bits;             // The direction bit set for this block (refers to *_DIRECTION_BIT in config.h)
  float nominal_speed;                               // The nominal speed for this block in mm/sec 
  float entry_speed;                                 // Entry speed at previous-current junction in mm/sec
  float max_entry_speed;                             // Maximum allowable junction entry speed in mm/sec
  float millimeters;                                 // The total travel of this block in mm
  float acceleration;                                // acceleration mm/sec^2
  unsigned char recalculate_flag;                    // Planner flag to recalculate trapezoids on entry junction
  unsigned char nominal_length_flag;                 // Planner flag for nominal speed always reached

  // Settings for the trapezoid generator
  unsigned long nominal_rate;                        // The nominal step rate for this block in step_events/sec 
  unsigned long initial_rate;                        // The jerk-adjusted step rate at start of block  
  unsigned long final_rate;                          // The minimal rate at exit
  unsigned long acceleration_st;                     // acceleration steps/sec^2
  unsigned long fan_speed;
  #ifdef BARICUDA
  unsigned long valve_pressure;
  unsigned long e_to_p_pressure;
  #endif
  volatile char busy;
} block_t;

block_t block_buffer[BLOCK_BUFFER_SIZE];            // A ring buffer for motion instfructions
volatile unsigned char block_buffer_head;           // Index of the next block to be pushed
volatile unsigned char block_buffer_tail;

    volatile 關鍵字確保了隊列頭和隊列尾被不同函數訪問過程中,編譯器不會因為優化和丟失更改行為。block_t類型的指針可以方便的方位結構體內任何元素。在后面的planner規劃動作plan_buffer_line()中,代碼可以用非常優雅的結構體指針來完成。

     每當3D打印機解析到位移指令的時候,plan_buffer_line()函數就被調用。在里面新的block_t首先被創建,并且排入隊列的隊尾;然后執行calculate_trapezoid_for_block(),計算新的block_t的關鍵速度節點及其對應的step數目;接著更新隊列里面所有block_t的連接速度:之前隊尾的block_t的收尾速度和相關速度節點會被更新。最后調用st_wake_up()保證stepper執行的中斷打開。

    而在%steppper中,ISR函數負責在主循環之外,執行隊列里可能存在的所有block_t。在ISR中,首先由plan_get_current_block()讀取隊列首的block_t,然后按照結構成員的step數,調用STEP_ADD和STEP_IF_COUNTER兩個宏來執行x,y,z三軸的運動。ISR每執行一次,三路各發出一個脈沖,并通過lamp ramp算法更新,根據下一個速度值來更新OCR1A寄存器來設定下一次中斷響應的周期。

    整個軟件C++實現妙至毫巔。建議大家在win環境使用eclipse來查看Cpp工程。eclipse對條件預編譯的支持非常完美,#if def能夠準確顯隱,可讀性非常好(見下圖)。全局查詢,go to define等功能也很完備。

Marlin固件的步進電機控制代碼解析    

    另外,eclipse有豐富的快捷鍵支持看代碼:用ctrl+shift+G就能查到變量的引用;F12就能查到變量的定義。Alt+左鍵 /右鍵回到之前的鼠標位置和之后的鼠標位置;用CTRL+SHIFT+P就能尋找括號的另外一半。

    附Marlin項目



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永宁县| 葫芦岛市| 明光市| 汕尾市| 东兴市| 阳东县| 登封市| 林周县| 阆中市| 民县| 江源县| 工布江达县| 巴南区| 新昌县| 任丘市| 盐亭县| 碌曲县| 阜南县| 杭州市| 开江县| 广灵县| 马鞍山市| 于田县| 洪洞县| 溧水县| 舒城县| 万源市| 长泰县| 德保县| 鹤岗市| 工布江达县| 衡山县| 阳原县| 原阳县| 潜山县| 陇西县| 安阳县| 玉溪市| 利辛县| 米泉市| 邯郸县|