C-使用STM32L TIM PWM控制伺服电机



因此,我正在尝试使用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之后具有默认时钟,并且设置的周期为0.152598951 sek,而伺服器收到的脉冲宽度为0.07至0.15sek(〜75times to Gone(我认为PC应该为15到存档16*20000时钟。使用您的设置,计时器时钟应该超过100MHz,而L1

不可能

计时器计数tick tick,tick滴答的时间取决于时钟速度和计时器时钟分隔线。

到档案20ms,您需要将PSC留为零值,并且ARR = 41939

当然1MS是2097和2ms -4194

您需要计算正确的值

配置PLL的最简单方法是使用wysiwyg cubemx时钟编辑器

确实取决于您的时钟设置,如@peterj所述。我只会在这里放一些精度。

您的ARR似乎很好,因为很明显您的周期是20ms。

但是,应根据ARR设置您的PSC,以达到1KHz。为此,您必须知道时钟频率。

旁注,根据STM文档,PSC值应比所需的1个单位比所需的1个单位(例如,如果您想要16,应该写15个(。

计数时钟频率ck_cnt等于fck_psc/(psc [15:0] 1(

最新更新