需要产生频率[50, 200k]Hz,数目[1, 2000]的PWM脉冲来驱动步进电机。目前已经尝试了三种方法。 1. 直接使用定时器中断计数和停止脉冲 2. 设置一个门模式从定时器计数和停止脉冲 3. 使用高级定时器的单脉冲和重复计数器(RCR)计数和停止脉冲 个人认为第三种方法最简单、最可靠。毕竟所有的控制都是硬件完成的。但是当频率上升到200kHz时,三种方法均无法产生数目准确的PWM脉冲。并且脉冲数目总是小于预期值。 下面是我计时器的设置和代码。 ![]() ![]()
|
void ydirOut(uint8_t dir) { if(dir) { HAL_GPIO_WritePin(Y_DIR_GPIO_Port, Y_DIR_Pin, GPIO_PIN_RESET); } else { HAL_GPIO_WritePin(Y_DIR_GPIO_Port, Y_DIR_Pin, GPIO_PIN_SET); } } void getFreq(uint16_t steps, const uint16_t dt, uint16_t* psc, uint16_t* arr, uint16_t* ccr) { double temp; temp = CLK_FREQ * dt / steps; temp = sqrt(temp); *(psc) = ((uint16_t) temp) - 1; *(arr) = *(psc); *(ccr) = *(arr) / 2; }复制代码 上面代码好像没显示全
我不知你是如何确认脉冲个数的,感觉你是通过中断统计个数,会不会这块出了问题。我这边刚才使用第3种方式,计数溢出频率为1MHz,要多少就多少,脉冲个数不多不少的。目前我是通过示波器看的。你再找找原因。
我不知你是如何确认脉冲个数的,感觉你是通过中断统计个数,会不会这块出了问题。我这边刚才使用第3种方式 ...
我发现如果只产生一次脉冲的话频率到1MHz确实也没问题。问题在于我需要反复调用motorMove函数产生脉冲。我发现debug模式下,即使我反复调用motorMove,脉冲数也没有问题。而debug模式和正常启动唯一的区别在于断点之间相当于产生了人工的延迟。所以我加了一个一毫秒的延时,然后就搞定了。
STM32F303的最高时钟所产生的PWM输出频率到200K时,精度无法保证,也就是会丢失脉冲。如果做连续输出,有可能满足精度,断续需要其它功能,无法保证。 建议选用更高频率的MCU。