需要产生频率[50, 200k]Hz,数目[1, 2000]的PWM脉冲来驱动步进电机。目前已经尝试了三种方法。
1. 直接使用定时器中断计数和停止脉冲
2. 设置一个门模式从定时器计数和停止脉冲
3. 使用高级定时器的单脉冲和重复计数器(RCR)计数和停止脉冲
个人认为第三种方法最简单、最可靠。毕竟所有的控制都是硬件完成的。但是当频率上升到200kHz时,三种方法均无法产生数目准确的PWM脉冲。并且脉冲数目总是小于预期值。
下面是我计时器的设置和代码。
- #define CLK_FREQ 144000 /* CLK_INT / 1000 */
- #define DT 1 /* dt in millisecond */
- #include "tim.h"
- #include "gpio.h"
- #include "math.h"
- void motorMove(uint8_t xdir,uint16_t xsteps, uint8_t ydir,uint16_t ysteps)
- {
- uint16_t psc = 0;
- uint16_t arr = 0;
- uint16_t ccr = 0;
- xdirOut(xdir);
- getFreq(xsteps, DT, &psc, &arr, &ccr);
- xpwmOut(psc, arr, ccr, xsteps);
- ydirOut(ydir);
- getFreq(ysteps, DT, &psc, &arr, &ccr);
- ypwmOut(psc, arr, ccr, ysteps);
- }
- void xpwmOut(uint16_t psc,uint16_t arr,uint16_t ccr,uint16_t stp)
- {
- htim1.Init.Prescaler = psc;
- htim1.Init.Period = arr;
- __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, ccr);
- htim1.Init.RepetitionCounter = stp - 1;
- HAL_TIM_Base_Init(&htim1);
- HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1);
- }
- void ypwmOut(uint16_t psc,uint16_t arr,uint16_t ccr,uint16_t stp)
- {
- htim8.Init.Prescaler = psc;
- htim8.Init.Period = arr;
- __HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1, ccr);
- htim8.Init.RepetitionCounter = stp - 1;
- HAL_TIM_Base_Init(&htim8);
- HAL_TIM_PWM_Start_IT(&htim8, TIM_CHANNEL_1);
- }
- void xdirOut(uint8_t dir)
- {
- if(dir)
- {
- HAL_GPIO_WritePin(X_DIR_GPIO_Port, X_DIR_Pin, GPIO_PIN_RESET);
- }
- else
- {
- HAL_GPIO_WritePin(X_DIR_GPIO_Port, X_DIR_Pin, GPIO_PIN_SET);
- }
- }
- void ydirOut(uint8_t dir)
- {
- if(dir)
复制代码
|