簡體   English   中英

使用STM32L TIM PWM控制伺服電機

[英]Using STM32L TIM PWM to control Servo Motor

因此,我試圖使用STM32L1通過PWM控制伺服器。 下面是完整的代碼,不需要庫。 當我上傳並運行此代碼時,伺服器會滴答幾次,而不是實際平穩地移動到所需位置600(0 *),1100(50 *),1600(100 *)和2100(150 *)。 我相信這與預分頻值的計算有關,而且我不確定以微秒為單位提到ARR是否正確,如果不正確,我如何將其配置為讀取微秒而不是毫秒。 請參考代碼中的注釋以獲取更多詳細信息。

#include <stdio.h>
#include "stm32l1xx.h"             
 // Keil::Device:Startup

 // initialization of GPIOB
void TIM4_Init(){
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOARST;       /* Reset GPIOB clock         */
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;           /* Enable GPIOB clock         */
GPIOB->MODER   &=   ~(0x03 << (2*6));       /* Clear bit 11 & 12 Alternate mode*/
GPIOB->MODER   |=   0x02 << (2*6);          /* set as Alternate mode*/
GPIOB->OSPEEDR &=   ~(0x03<< (2*6));        /* 40 MHz  speed        */
GPIOB->OSPEEDR |=   0x03<< (2*6);           /* 40 MHz  speed        */
GPIOB->PUPDR &=         ~(1<<6);            /* NO PULL-UP PULL-DOWN        */
GPIOB->OTYPER &=        ~(1<<6);            /* PUSH-PULL        */
GPIOB->AFR[0] |=        0x2 << (4*6);       /* Pin6 set as alternate function 2 (TIM4) */

RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
TIM4->PSC = 16; //prescale value, AHB/APB1 Fmax=32MHz / 2
TIM4->ARR = 20000-1; //motor Freq = 50Hz, Period(ARR)= 1/50 = 20000us


// initialization of TIM & PWM

TIM4->CCMR1 |= TIM_CCMR1_OC1M;  // 111: PWM mode 2 - In upcounting, channel 1 is inactive 
                               //as long as TIMx_CNT<TIMx_CCR1 else active. 
                              // In downcounting, channel 1 is active as long as 
                             //TIMx_CNT>TIMx_CCR1 else inactive.

TIM4->CCMR1 |= TIM_CCMR1_OC1PE;
TIM4->CR1 |= TIM_CR1_ARPE;
TIM4->CCER |= TIM_CCER_CC1E;
TIM4->EGR |= TIM_EGR_UG;
TIM4->SR &= ~TIM_SR_UIF;
TIM4->DIER |= TIM_DIER_UIE;
TIM4->CR1 |= TIM_CR1_CEN;
}

// set servo to 4 positions in sequence

int main(void){

int i;

int position=600; // initial motor position

TIM4_Init();

while (1){  

if ((position >=600)|| (position <=2100))
position = position+500;      // motor positions will be 600(0*), 1100(50*), 1600(100*)
                             //, 2100(150*)
TIM4->CCR1 = position; 

for(i=0;i<1000;i++); // short delay


   }


 }  

這取決於您的時鍾設置。 您需要首先配置時鍾,因為只有在重設2.097MHz之后,許多L1都將具有默認時鍾,並且設置的周期為0.152598951 sek,並且伺服器接收的脈沖寬度為0.07至0.15sek,約為75倍長(我認為PCS應該為15,以存檔16 * 20000個時鍾周期。 根據您的設置,計時器時鍾應大於100MHz,這對於L1是不可能的

計時器計數滴答聲,滴答聲需要多長時間取決於時鍾速度和計時器時鍾分頻器。

要歸檔20ms,您需要將PSC保留為零值且ARR = 41939

當然1ms將是2097,而2ms-4194

您需要計算正確的值

配置PLL的最簡單方法是使用WYSIWYG CubeMX時鍾編輯器

正如@PeterJ所提到的,這實際上取決於您的時鍾設置。 我將在這里提出一些更高的精度。

您的ARR看起來不錯,因為可以清楚地看到您的周期為20ms。

但是,應根據ARR設置PSC,以達到1kHz。 為此,您必須知道時鍾頻率。

附帶說明,根據stm文檔,PSC值應比期望值小1個單位(例如,如果您希望16,則應將15寫入寄存器)。

計數器時鍾頻率CK_CNT等於fCK_PSC /(PSC [15:0] +1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM