我已經用計時器撰寫了這個步進器代碼,五分之一的時間我得到了不同的行為。也許有一種好方法可以監控或記錄脈沖的一致性?但我認為放置日志會阻塞代碼并導致步進器像在 Arduino 上那樣減速,盡管我還沒有嘗試過。不管怎樣,當我按下一個按鈕時,它會在運動開始時觸發加速,也會觸發運動開始。我已經硬編碼了我希望它當前運行的值,因為我只是想讓它作業,但我可以看到它的行為不一致。它將加速,穩定約 5 秒,然后減速接近尾聲。但是五分之一的時間它會穩定 1 秒,甚至可能不會。所有幫助將不勝感激,Stm32CubeIDE 上的提示和技巧也很棒。對于額外的背景關系,計數器周期設定為 42 - 1
volatile static int moveTriggered = 0;
volatile static int step1 = 1;
volatile static int accelerating = 0;
volatile static int decelerating = 0;
static int accelCounter = 0;
static int currentPrescaler = 999;
static const int maxPrescaler = 999;
static const int minPrescaler = 99;
static const int travelSteps = 70000;
static int currentTravelled = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (moveTriggered) {
if (step1) {
HAL_GPIO_WritePin(STEP_OUT_GPIO_Port, STEP_OUT_Pin, GPIO_PIN_SET);
step1 = 0;
}
else {
HAL_GPIO_WritePin(STEP_OUT_GPIO_Port, STEP_OUT_Pin, GPIO_PIN_RESET);
step1 = 1;
}
}
if (accelerating) {
if ( currentPrescaler > minPrescaler && accelCounter == 10) {
__HAL_TIM_SET_PRESCALER(&htim2, currentPrescaler--);
accelCounter = 0;
} else if (currentPrescaler <= minPrescaler) {
accelerating = 0;
}
accelCounter ;
}
if (decelerating) {
if (currentPrescaler < maxPrescaler && accelCounter == 10) {
__HAL_TIM_SET_PRESCALER(&htim2, currentPrescaler );
accelCounter = 0;
} else if (currentPrescaler >= maxPrescaler) {
decelerating = 0;
}
accelCounter ;
}
currentTravelled ;
if (currentTravelled == 65000) decelerating = 1;
else if (currentTravelled >= travelSteps) {
currentTravelled = 0;
moveTriggered = 0;
accelerating = 0;
decelerating = 0;
accelCounter = 0;
currentPrescaler = maxPrescaler;
__HAL_TIM_SET_PRESCALER(&htim2, currentPrescaler);
}
}
和 while 回圈
while (1)
{
int stateOfPushButton = HAL_GPIO_ReadPin(MOTOR_BUTTON_GPIO_Port, MOTOR_BUTTON_Pin);
if ( stateOfPushButton == 0 && accelerating == 0 ) {
moveTriggered = 1;
accelerating = 1;
}
}
uj5u.com熱心網友回復:
您的問題的原因是每次呼叫 ISR 時 currentTravelled 都會增加,無論是否觸發了移動。這意味著當您按下按鈕時,它可以是零和“travelSteps”之間的任何值。因此,您移動的持續時間是該范圍內的亂數。
如果 moveTriggered 為零,則 ISR 中的大部分邏輯都不需要發生。所以你的 ISR 可以先檢查它,如果沒有移動就回傳。這也將阻止您在 ISR 中浪費時間做無意義的事情。
我還建議去掉本質上是布林值的 moveTriggered、accelerating 和 decelerating 變數,并替換為單個變數型別:
enum move_state_e {
MOVE_NONE,
MOVE_ACCELERATING,
MOVE_PLATEAU,
MOVE_DECELERATING
};
這將使您的代碼更簡單,更容易理解。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/534177.html
標籤:C定时器stm32步进器
