電機(jī)控制實(shí)現(xiàn):ePWM脈沖與梯形加減速調(diào)度)
簡介面向電機(jī)控制與嵌入式開發(fā)者這套基于TMS320F28335 DSP與Xilinx XC3S500E FPGA的步進(jìn)電機(jī)控制資料包圍繞實(shí)際電機(jī)驅(qū)動(dòng)應(yīng)用提供完整軟硬件實(shí)現(xiàn)。壓縮包內(nèi)含248個(gè)文件大小約25.13MB主要文件類型包括C語言驅(qū)動(dòng)源碼、FPGA VHDL設(shè)計(jì)文件、原理圖PDF、UCF約束文件以及bit配置位流等覆蓋從軟件算法到硬件設(shè)計(jì)的多個(gè)層次。已有349人學(xué)習(xí)下載。源碼部分涉及PWM波形生成、方向與速度控制、微步進(jìn)細(xì)分技術(shù)、DSP與FPGA間的SPI/UART通信及同步機(jī)制并可能包含PID等閉環(huán)控制策略原理圖部分則清晰展示了主控芯片與步進(jìn)電機(jī)驅(qū)動(dòng)器的連接方式、電源管理及過流保護(hù)電路。將源碼、原理圖和FPGA配置結(jié)合研讀可快速掌握DSPFPGA聯(lián)合控制步進(jìn)電機(jī)的工程實(shí)現(xiàn)方法對學(xué)習(xí)現(xiàn)代精密電機(jī)控制技術(shù)具有較高參考價(jià)值。1. 為什么用 DSP28335 驅(qū)動(dòng)步進(jìn)電機(jī)寄存器直控與實(shí)時(shí)中斷的取舍步進(jìn)電機(jī)控制本身不算難難的是在頻繁加減速時(shí)讓脈沖序列保持穩(wěn)定。DSP28335 的 ePWM 模塊可以直接從硬件生成連續(xù)方波周期中斷觸發(fā)固定不會(huì)像普通單片機(jī)那樣被主循環(huán)里的一次串口處理打斷。這個(gè)項(xiàng)目正是一套圍繞 F28335 展開的步進(jìn)電機(jī)開環(huán)控制方案外設(shè)初始化、梯形加減速調(diào)度、方向與限位邏輯都拆成了清晰的小模塊。適合正在做運(yùn)動(dòng)控制原型、準(zhǔn)備把 DSP28335 用進(jìn)實(shí)際設(shè)備的開發(fā)者也適合想從寄存器層面理解電機(jī)控制的人。2. 硬件與外設(shè)分配ePWM 脈沖鏈路、方向 GPIO 與限位輸入的搭法2.1 控制鏈路從 DSP 引腳到電機(jī)軸一條完整的控制鏈路可以拆成三段來理解控制段負(fù)責(zé)生成脈沖與方向信號隔離段負(fù)責(zé)把兩個(gè)地隔開功率段把信號放大成繞組電流。GPIO0 復(fù)用為 EPWM1A 后引腳輸出的是 3.3V 的方波這個(gè)信號一般不要直接接到驅(qū)動(dòng)器因?yàn)轵?qū)動(dòng)器側(cè)往往用 24V 邏輯電源地也沒與控制板共地。常見做法是讓脈沖信號先通過光耦再進(jìn)驅(qū)動(dòng)器的 PUL 端子隔離的同時(shí)完成電平轉(zhuǎn)換。方向信號 DIR 和使能信號 ENA 也走同樣的光耦通道。實(shí)際項(xiàng)目里我一般會(huì)在脈沖線上串一個(gè) 470Ω 左右的限流電阻光耦內(nèi)部的 LED 正向壓降約 1.2V3.3V 減去壓降再除以 470Ω電流約 4.5mA已經(jīng)足夠TLP 類光耦可靠導(dǎo)通。驅(qū)動(dòng)器那一側(cè)的上拉電阻也不能省否則光耦輸出端在進(jìn)入導(dǎo)通與截止切換時(shí)沿不夠陡高速脈沖下驅(qū)動(dòng)器會(huì)漏檢測。2.2 外設(shè)分工哪根引腳負(fù)責(zé)什么引腳分配時(shí)有一個(gè)容易忽略的原則脈沖輸出一定要選硬件外設(shè)引腳而不是普通 GPIO。GPIO 翻轉(zhuǎn)依賴軟件參與一旦主循環(huán)里出現(xiàn)延時(shí)或高優(yōu)先級中斷脈沖間隔就會(huì)抖動(dòng)電機(jī)跟著發(fā)出不均勻的噪音。EPWM 輸出完全由硬件時(shí)序產(chǎn)生CPU 只需要在狀態(tài)變化時(shí)更新周期寄存器。功能引腳外設(shè)說明脈沖 PULGPIO0EPWM1A3.3V 方波經(jīng)光耦接驅(qū)動(dòng)器 PUL方向 DIRGPIO1普通 GPIO高電平正轉(zhuǎn)低電平反轉(zhuǎn)使能 ENAGPIO2普通 GPIO低電平使能驅(qū)動(dòng)器功率輸出原點(diǎn)限位GPIO12輸入 GPIO常開壓合時(shí)接地終點(diǎn)限位GPIO13輸入 GPIO常開壓合時(shí)接地GPIO0 到 GPIO31 屬于 GPIOA 組所以方向位操作要用 GPASET 和 GPACLEAR而不是 GPIOB 那組。初始化代碼如下// gpio_init.c —— 管腳復(fù)用方向配置 void GPIO_Init(void) { EALLOW; GpioMuxRegs.GPAMUX1.bit.GPIO0 1; // GPIO0 復(fù)用為 EPWM1A GpioMuxRegs.GPADIR.bit.GPIO1 1; // GPIO1 方向輸出 GpioMuxRegs.GPADIR.bit.GPIO2 1; // GPIO2 使能輸出 GpioMuxRegs.GPADIR.bit.GPIO12 0; // GPIO12 限位輸入 GpioMuxRegs.GPADIR.bit.GPIO13 0; // GPIO13 限位輸入 EDIS; }GPAMUX1 負(fù)責(zé) GPIO0-GPIO15 的復(fù)用選擇寫 1 表示選擇外設(shè)功能而非普通 IO。GPADIR 對應(yīng)方向寄存器寫 1 為輸出寫 0 為輸入。這里的 EALLOW/EDIS 是 F28335 保護(hù)寄存器機(jī)制修改復(fù)用和方向時(shí)必須先解除保護(hù)否則寫操作會(huì)被忽略這一點(diǎn)剛上手時(shí)很容易踩。2.3 驅(qū)動(dòng)器接口電平與使能邏輯驅(qū)動(dòng)器側(cè)的 ENA 使能引腳多數(shù)是低電平有效接低時(shí)功率級打開電機(jī)進(jìn)入鎖定狀態(tài)接高或懸空時(shí)功率級關(guān)閉。上電前最好把 ENA 通過上拉電阻固定到無效電平避免 DSP 復(fù)位期間的 IO 狀態(tài)不確定導(dǎo)致電機(jī)在啟動(dòng)瞬間跳一步。限位開關(guān)的接法建議用常開型碰到擋塊時(shí)開關(guān)閉合把 GPIO 拉到地程序里檢測低電平即可如果常閉斷線故障不會(huì)被發(fā)現(xiàn)可靠性差一截。3. 核心代碼拆解從 ePWM 波形到梯形加減速的完整鏈路3.1 ePWM 脈沖輸出初始化F28335 的 ePWM 模塊沒有繁瑣的庫封裝直接面對寄存器。時(shí)基計(jì)數(shù)器從 0 遞增到 TBPRD然后歸零重新開始遞增過程中到達(dá) CMPA 時(shí)輸出動(dòng)作一次歸零時(shí)再動(dòng)作一次這樣就產(chǎn)生了一個(gè)周期的方波。這里的關(guān)鍵是預(yù)分頻選擇TBPRD 只有 16 位如果 TBCLK 直接使用 150MHz1kHz 脈沖需要的周期值是 150000超出上限所以必須分頻。// epwm.c —— 脈沖輸出初始化脈沖引腳 GPIO0/EPWM1A void EPwm1_Init(void) { EALLOW; GpioMuxRegs.GPAMUX1.bit.GPIO0 1; // GPIO0 復(fù)用為 EPWM1A EDIS; // TBCLK SYSCLKOUT / 32 4.6875MHz // 避免低頻場景下 TBPRD 超過 16 位上限65535 EPwm1Regs.TBCTL.bit.CLKDIV 5; // 5 對應(yīng) /32 EPwm1Regs.TBCTL.bit.HSPCLKDIV 0; // 高速時(shí)鐘不分頻 EPwm1Regs.TBCTL.bit.PRDLD 1; // TBPRD 在計(jì)數(shù)器歸零時(shí)更新 EPwm1Regs.TBCTL.bit.CTRMODE 0; // 遞增計(jì)數(shù)模式 // 初始脈沖頻率 1kHz周期值 4.6875MHz / 1000Hz EPwm1Regs.TBPRD 4687 - 1; // 占空比 50%CMPA 取周期一半 EPwm1Regs.CMPA.bit.CMPA (4687 - 1) / 2; // 動(dòng)作配置遞增計(jì)數(shù)到 CMPA 時(shí)輸出高歸零時(shí)輸出低 EPwm1Regs.AQCTLA.bit.CAU 2; // CAU 事件置高 EPwm1Regs.AQCTLA.bit.PRD 1; // 周期事件置低 // 周期中斷每次 TBCTR 歸零觸發(fā)一次用于脈沖計(jì)數(shù) EPwm1Regs.ETSEL.bit.INTEN 1; // 使能 ePWM 中斷 EPwm1Regs.ETSEL.bit.INTSEL 1; // 選擇周期事件觸發(fā) EPwm1Regs.ETPS.bit.INTPRD 1; // 每個(gè)周期事件都觸發(fā) }CLKDIV 取 5 意味著 TBCLK 4.6875MHz。1kHz 對應(yīng)的 TBPRD 是 468716kHz 對應(yīng)的 TBPRD 只有 292。在 16kHz 附近TBPRD 每變化 1頻率大約變化 55Hz做加減速足夠用了。PRDLD 位必須設(shè)為 1它決定了 TBPRD 的更新時(shí)刻是“計(jì)數(shù)器歸零時(shí)”而不是“寫入時(shí)”這直接關(guān)系著加減速過程中會(huì)不會(huì)出現(xiàn)畸形脈沖。3.2 1ms 節(jié)拍與梯形加減速調(diào)度加減速本質(zhì)上是一個(gè)頻率調(diào)度問題每毫秒把當(dāng)前頻率往目標(biāo)頻率推進(jìn)一步然后把新的頻率寫進(jìn) ePWM。CPU Timer0 很適合做這個(gè) 1ms 節(jié)拍配置如下// main.c —— 初始化 CPU Timer0 為 1ms 中斷 void CpuTimer0_Init(void) { CpuTimer0Regs.PRD.all (150000000UL / 1000) - 1; // 1ms 150MHz CpuTimer0Regs.TPR.all 0xFFFF; CpuTimer0Regs.TPRH.all 0xFFFF; CpuTimer0Regs.TCR.bit.TSS 1; // 先停止 CpuTimer0Regs.TCR.bit.TRB 1; // 重載周期值 CpuTimer0Regs.TCR.bit.TIE 1; // 使能中斷 }然后是運(yùn)動(dòng)調(diào)度的核心。狀態(tài)機(jī)包含加速、勻速、減速、停止四個(gè)狀態(tài)每個(gè) 1ms 節(jié)拍更新一次頻率// motion.c —— 運(yùn)動(dòng)狀態(tài)機(jī)由 1ms 定時(shí)器中斷調(diào)用 #define MIN_FREQ 1000u // 啟動(dòng)/停止脈沖頻率 Hz #define MAX_FREQ 16000u // 最高脈沖頻率 Hz #define ACCEL_RATE 400u // 每毫秒頻率增量 Hz/ms #define DECEL_RATE 400u // 每毫秒頻率減量 Hz/ms void motion_tick(void) { if (running 0) return; switch (state) { case STATE_ACCEL: freq_hz ACCEL_RATE; if (freq_hz MAX_FREQ) { freq_hz MAX_FREQ; state STATE_RUN; } break; case STATE_RUN: // 剩余脈沖數(shù)低于減速閾值時(shí)切入減速 if ((target_pulses - pulse_cnt) decel_threshold) { state STATE_DECEL; } break; case STATE_DECEL: if (freq_hz MIN_FREQ) { freq_hz - DECEL_RATE; } if (freq_hz MIN_FREQ) { freq_hz MIN_FREQ; state STATE_DONE; } break; default: break; } pwm_set_freq(freq_hz); }pwm_set_freq 負(fù)責(zé)把頻率換算成寄存器值// epwm.c —— 動(dòng)態(tài)修改脈沖頻率 void pwm_set_freq(uint32_t freq_hz) { uint32_t period; if (freq_hz 0) { EPwm1Regs.TBCTL.bit.FREESOFT 2; // 立即停止輸出高電平 return; } // TBCLK 4.6875MHz四舍五入求周期 period (4687500UL freq_hz / 2) / freq_hz; EPwm1Regs.TBPRD period - 1; EPwm1Regs.CMPA.bit.CMPA (period - 1) / 2; // 同步更新占空比 }注意到減速閾值不能拍腦袋定它會(huì)決定減速段是否夠長。我的習(xí)慣是運(yùn)行前按梯形面積估算從 MAX_FREQ 降到 MIN_FREQ 需要時(shí)間(MAX_FREQ - MIN_FREQ) / DECEL_RATE毫秒減速期間平均頻率約為(MAX_FREQ MIN_FREQ) / 2兩者相乘就是減速段預(yù)計(jì)發(fā)出的脈沖數(shù)。代入本項(xiàng)目參數(shù)減速大約需要 37.5ms發(fā)出約 318 個(gè)脈沖所以 decel_threshold 可以取 350 留一點(diǎn)余量。3.3 位置計(jì)數(shù)與到位判斷加減速調(diào)度是“宏觀”層面的脈沖計(jì)數(shù)則是“微觀”層面的。到位判斷如果放在 1ms 節(jié)拍里做誤差可能接近 1ms 內(nèi)發(fā)出的所有脈沖數(shù)在高速段相當(dāng)于上百個(gè)脈沖的位置誤差。把計(jì)數(shù)放進(jìn) ePWM 周期中斷每個(gè)脈沖都精確記一次誤差最多一個(gè)脈沖周期。// epwm_isr —— 每個(gè)脈沖觸發(fā)一次 __interrupt void epwm1_isr(void) { pulse_cnt; if (pulse_cnt target_pulses) { pwm_set_freq(0); // 停止脈沖 state STATE_DONE; running 0; } EPwm1Regs.ETCLR.bit.INT 1; // 清除中斷標(biāo)志 }pulse_cnt 與 target_pulses 都聲明為 volatile uint32_t因?yàn)樗鼈冊谥袛嗪椭餮h(huán)之間共享。F28335 的 32 位讀寫是單指令完成的不需要臨界區(qū)保護(hù)如果以后改成 64 位變量就必須考慮先關(guān)中斷再讀寫。EPWM 中斷還要在 PIE 里使能中斷向量掛到 PieVectTable.EPWM1_INTPIEIER3 的 INTx1 置 1最后 IER | M_INT3。3.4 方向與限位邏輯方向控制放在運(yùn)動(dòng)啟動(dòng)之前設(shè)置不要在運(yùn)行途中切換否則電機(jī)在高速下突然反向會(huì)直接失步甚至堵轉(zhuǎn)。限位檢測放到主循環(huán)里輪詢即可不需要中斷因?yàn)橄尬皇菣C(jī)械觸點(diǎn)輪詢周期 1ms 足夠快// motion.c —— 方向設(shè)置與限位讀取 #define DIR_POS 1 #define DIR_NEG 0 void motion_set_dir(uint16_t dir) { if (dir DIR_POS) { GpioDataRegs.GPASET.bit.GPIO1 1; // 正轉(zhuǎn) } else { GpioDataRegs.GPACLEAR.bit.GPIO1 1; // 反轉(zhuǎn) } } uint16_t motion_check_limit(void) { // 低電平表示限位開關(guān)被壓合 if (GpioDataRegs.GPADAT.bit.GPIO12 0) return 1; if (GpioDataRegs.GPADAT.bit.GPIO13 0) return 1; return 0; }檢測到限位后建議立即調(diào)用 pwm_set_freq(0) 并讓 running 置 0這是硬停止邏輯不能依賴后面的軟件狀態(tài)機(jī)慢慢降速。原點(diǎn)回歸邏輯可以在此基礎(chǔ)上加先向負(fù)方向找原點(diǎn)限位觸發(fā)后清零 pulse_cnt再正轉(zhuǎn)脫離限位一段距離即可。4. 工程落地CCS 建工程、CMD 內(nèi)存分配與示波器驗(yàn)證4.1 CCS 工程結(jié)構(gòu)與文件職責(zé)DSP28335 工程并不復(fù)雜但文件歸屬一定要清楚。最怕把所有代碼堆進(jìn) main.c外設(shè)初始化、運(yùn)動(dòng)邏輯、中斷服務(wù)混在一起后面想改一個(gè)加減速參數(shù)都要找半天。推薦按模塊拆文件文件職責(zé)main.c初始化順序與主循環(huán)輪詢gpio.c / gpio.h引腳復(fù)用與方向配置epwm.c / epwm.hePWM 初始化、頻率修改、脈沖計(jì)數(shù)中斷motion.c / motion.h加減速狀態(tài)機(jī)、方向、限位判斷DSP2833x_CpuTimers.c官方定時(shí)器驅(qū)動(dòng)28335_RAM_lnk.cmdRAM 調(diào)試鏈接腳本DSP2833x_Headers_nonBIOS.cmd外設(shè)寄存器地址映射這些人文件在 CCS 工程里的關(guān)系是CMD 文件決定代碼和數(shù)據(jù)放在哪段內(nèi)存頭文件 CMD 決定外設(shè)寄存器地址能否被訪問。兩套地址映射同時(shí)生效前者管程序運(yùn)行空間后者管外設(shè)訪問空間。4.2 CMD 內(nèi)存分配RAM 調(diào)試與 Flash 固化的差異RAM 調(diào)試版 CMD 把代碼段全部放進(jìn)內(nèi)部 RAM程序通過仿真器直接加載運(yùn)行斷電即失。適合開發(fā)前期反復(fù)改代碼的階段。Flash 版本需要把可執(zhí)行代碼寫進(jìn) Flash同時(shí)把運(yùn)行時(shí)可變的段搬進(jìn) RAM啟動(dòng)流程復(fù)雜得多。以下是一個(gè)簡化的 RAM 調(diào)試 CMD 片段MEMORY { PAGE 0: RAML0 : origin 0x008000, length 0x001000 PAGE 1: RAML1 : origin 0x009000, length 0x001000 } SECTIONS { .text : RAML0, PAGE 0 .cinit : RAML0, PAGE 0 .bss : RAML1, PAGE 1 .stack : RAML1, PAGE 1 }段名是編譯器規(guī)定的.text 是代碼.cinit 是全局變量初始值.bss 是未初始化全局變量.stack 是棧。如果某個(gè)段沒有被分配鏈接時(shí)直接報(bào)錯(cuò)很容易定位。Flash 固化版要復(fù)雜很多還要處理 .codestart 段和 boot 模式引腳我的建議是前期一直用 RAM 調(diào)試功能全部驗(yàn)證通過后再碰 Flash。4.3 示波器驗(yàn)證從 1kHz 到 16kHz 的加減速觀察沒有示波器調(diào)步進(jìn)電機(jī)基本等于盲調(diào)至少需要一臺(tái)能測到幾十 kHz 的雙通道示波器。驗(yàn)證順序從靜態(tài)到動(dòng)態(tài)單步進(jìn)入調(diào)試器把 EPwm1Regs.TBPRD 加入變量監(jiān)視窗口手動(dòng)改一次周期值看波形頻率有沒有立刻變化。確認(rèn)寄存器寫入路徑正確后再跑完整的加減速流程。示波器探頭接 EPWM1A地線夾到控制板地。把目標(biāo)位置設(shè)得足夠長讓電機(jī)完整經(jīng)歷加速-勻速-減速-停止觀察脈沖包絡(luò)是否呈現(xiàn)對稱的梯形如果減速段比加速段短很多說明 decel_threshold 估算偏小。另外測一下停止瞬間的波形應(yīng)當(dāng)立刻變平不能有殘留脈沖。5. 踩坑記錄脈沖毛刺、失步與下載跑飛的原因排查5.1 電機(jī)嗡嗡響但不轉(zhuǎn)方向信號被當(dāng)脈沖了現(xiàn)象是上電后電機(jī)鎖定發(fā)出尖銳的嗡鳴聲軸在來回抖動(dòng)始終沒有連續(xù)旋轉(zhuǎn)。示波器看脈沖引腳波形正常方向引腳也正常。原因排查到最后是光耦輸出側(cè)方向線和脈沖線在驅(qū)動(dòng)器端子處接反了。驅(qū)動(dòng)器把方向信號上的電平跳變誤認(rèn)為脈沖電機(jī)在每個(gè)“脈沖”到來時(shí)改變一次轉(zhuǎn)向表現(xiàn)為原地高頻換向。這個(gè)坑在實(shí)物接線階段特別容易發(fā)生因?yàn)槊}沖和方向在杜邦線上長得一模一樣。解決方法是把驅(qū)動(dòng)器的 PUL 與 DIR 接線對調(diào)。為了減少這類問題我在后來的項(xiàng)目里統(tǒng)一用不同顏色線纜區(qū)分脈沖與方向脈沖用橙白、方向用藍(lán)白上電前拿萬用表先確認(rèn)兩個(gè)端子的對地電平關(guān)系。5.2 加速過程中電機(jī)咔咔響速度越高越容易丟步現(xiàn)象是低速運(yùn)行完全正常頻率超過 10kHz 之后電機(jī)發(fā)出明顯的失步噪音繼續(xù)加速就直接堵轉(zhuǎn)停住。原因通常是兩個(gè)一是 ACCEL_RATE 太大電機(jī)轉(zhuǎn)矩跟不上頻率爬升斜率二是驅(qū)動(dòng)器的細(xì)分?jǐn)?shù)設(shè)得過高比如 8 細(xì)分下 16kHz 脈沖對應(yīng)每秒 10 圈已經(jīng)超過該電機(jī)在該負(fù)載下的失步力矩范圍。很多人只調(diào)軟件里的加速度忽略驅(qū)動(dòng)器細(xì)分與最高頻率的關(guān)系最后在硬件參數(shù)上翻車。解決方法是先把 MAX_FREQ 降到 8kHz 跑通整套流程確認(rèn)加減速曲線沒問題后再以 2kHz 為單位往上試探。同時(shí)適當(dāng)加大驅(qū)動(dòng)器的電流設(shè)定步進(jìn)電機(jī)在高速段的輸出力矩會(huì)明顯下降提高供電電壓比調(diào)整電流更有效。5.3 加減速過程中示波器看到畸形脈沖電機(jī)一頓一頓現(xiàn)象是電機(jī)整體運(yùn)行速度曲線看起來正常但示波器上偶爾出現(xiàn)一個(gè)特別窄或者特別寬的脈沖電機(jī)聲音也不均勻。根因是 TBPRD 的更新時(shí)機(jī)不對。默認(rèn)配置下寫入 TBPRD 可能立即生效如果寫入發(fā)生在計(jì)數(shù)器計(jì)到一半的時(shí)候當(dāng)前周期就被強(qiáng)行截?cái)嗷蚶L形成一個(gè)寬度異常的脈沖。這個(gè)異常脈沖會(huì)讓驅(qū)動(dòng)器在錯(cuò)誤的時(shí)間點(diǎn)換相輕則頓挫重則失步。解決方法是把 PRDLD 設(shè)為 1強(qiáng)制周期值在計(jì)數(shù)器歸零時(shí)更新中斷里再去修改頻率時(shí)新的周期值只會(huì)從下一個(gè)完整周期開始生效。這個(gè)細(xì)節(jié)做運(yùn)動(dòng)控制時(shí)必須養(yǎng)成習(xí)慣凡是周期值、比較值可能在運(yùn)行中被修改的 PWM 模塊都先看周期加載模式。5.4 仿真器跑得好好的燒進(jìn) Flash 就不運(yùn)行現(xiàn)象是 RAM 調(diào)試一切正常換成 Flash 版本的 CMD 后燒錄成功但重新上電沒有任何反應(yīng)程序沒有跑起來。原因在啟動(dòng)流程F28335 從 Flash 啟動(dòng)需要 boot 引腳電平配合同時(shí) Flash 等待狀態(tài)寄存器沒有初始化會(huì)導(dǎo)致取指異常。另外中斷向量表默認(rèn)在 RAM上電時(shí)如果不把向量表初始化好任何一個(gè)中斷觸發(fā)都會(huì)讓程序跑飛。解決方法是先確認(rèn) boot 模式引腳下拉到正確組合在 main 開頭先調(diào)用初始化 Flash 等待狀態(tài)的函數(shù)再把 PIE 向量表重新裝載一遍。我的習(xí)慣是 Flash 版本專門保留一個(gè)空白工程做對比每次只改 CMD 和必要的初始化代碼不混入業(yè)務(wù)邏輯。5.5 上電瞬間電機(jī)跳一步現(xiàn)象是每次按下電源開關(guān)電機(jī)都會(huì)“咯噔”響一聲軸偏轉(zhuǎn)一個(gè)角度。原因是 DSP 復(fù)位階段 GPIO 輸出高阻光耦輸入側(cè)懸空驅(qū)動(dòng)器把噪聲當(dāng)成了脈沖或者使能引腳 ENA 在上電瞬間處于無效電平功率級沒開但脈沖已經(jīng)先進(jìn)來等使能一開就執(zhí)行了這一步。解決方法是硬件上在 DIR 和 ENA 引腳加下拉電阻讓復(fù)位期間電平固定在已知狀態(tài)軟件上初始化 GPIO 后先延時(shí) 200ms再打開使能信號。這個(gè)延時(shí)給了電源和外部電路一個(gè)穩(wěn)定時(shí)間之后才允許脈沖輸出。6. 二次開發(fā)思路加編碼器閉環(huán)、S 曲線與串口協(xié)議開環(huán)梯形加減速能滿足大部分點(diǎn)位運(yùn)動(dòng)需求但需要做位置精度補(bǔ)償或速度平穩(wěn)性優(yōu)化時(shí)有三條明確的升級路徑。第一是位置閉環(huán)。F28335 自帶 EQEP 模塊把編碼器 A/B 相接入 EQEP1 引腳初始化正交解碼后直接讀位置計(jì)數(shù)器。在運(yùn)行中周期性對比目標(biāo)位置與實(shí)際位置用比例系數(shù)把位置誤差映射到運(yùn)行頻率誤差大就提高頻率誤差小就降頻。這個(gè)改進(jìn)能消除丟步積累的位置偏差前提是誤差修正的速度遠(yuǎn)低于加減速調(diào)度頻率通常在 1ms 節(jié)拍里做一次就很合適。第二是 S 形速度曲線。梯形加減速在加速段起點(diǎn)和終點(diǎn)存在加速度突變機(jī)械結(jié)構(gòu)高速時(shí)會(huì)感受到明顯沖擊。把線性加頻率改成正弦插值加速進(jìn)度從 0 到 1頻率增量按 sin(progress × 90°) 縮放讓加速度從零開始逐漸增加到峰值再回落到零。F28335 有浮點(diǎn)單元計(jì)算 sin 的開銷很小每毫秒算一次完全夠用。第三是串口指令協(xié)議。定義一個(gè)極簡幀格式幀頭 0xAA、命令字、4 字節(jié)目標(biāo)脈沖數(shù)、末尾異或校驗(yàn)。把運(yùn)動(dòng)控制封裝成執(zhí)行單一指令的函數(shù)收到目標(biāo)后自動(dòng)完成加減速和到位停止。這樣后續(xù)接上位機(jī)、觸摸屏或者視覺模塊都只需要維護(hù)協(xié)議解析部分核心運(yùn)動(dòng)邏輯不用動(dòng)。那次我在一套送檢設(shè)備上試過直接加大加速度縮短節(jié)拍時(shí)間結(jié)果電機(jī)在共振區(qū)間反復(fù)失步后來強(qiáng)制自己每次修改加減速參數(shù)都先在 1kHz 低頻、短距離工況下完整跑一遍確認(rèn)包絡(luò)正常后再放滿載。從那以后我改任何運(yùn)動(dòng)控制參數(shù)都會(huì)先出低頻測試不直接上高速驗(yàn)證。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取