用TIM的PWM输出模式写一个步进电机的Stepper库函数

这是之前写平衡小车时自己用tim的pwm输出模式写了一个步进电机的stepper库函数。
1
调用顺序
1.1
init函数
1.2
begin函数
1.3
setspeed函数
2
stepper类结构
3
tim结构框图
stm32手册中的结构框图很重要,只要理解了外设的运行逻辑,按照逻辑一步一步给寄存器设值就可以让外设按我们的要求运行。
#ifndef __stepper_h#define __stepper_h#include peripheral.h#include math.h#ifdef __cplusplusextern c{#endif enum dirction { pos, inv }; class stepper { private: /* data */ uint16_t timx_prescaler = 0; uint32_t timx_freq = 0; tim_typedef *timx; uint32_t channel; float speed; public: stepper(tim_typedef *timx, uint32_t channel); ~stepper(); void init(); void gpio_init(); void begin(); void stop(); void setdirection(dirction dir); void setfreq(uint16_t freq); void setspeed(float speed); float getspeed(); }; extern stepper stepper_left; extern stepper stepper_right;#ifdef __cplusplus}#endif#endif#include stepper.hstepper stepper_left(tim1, ll_tim_channel_ch1);stepper stepper_right(tim2, ll_tim_channel_ch2);stepper::stepper(tim_typedef *timx, uint32_t channel){ this- >timx = timx; this- >channel = channel;}stepper::~stepper(){}void stepper::init(){ //开定时器外设时钟 if (timx == tim1) { ll_apb2_grp1_enableclock(ll_apb2_grp1_periph_tim1); //设置预分频器 ll_tim_setprescaler(timx, 90); timx_freq = 90000000; timx_prescaler = 90; } if (timx == tim2) { ll_apb1_grp1_enableclock(ll_apb1_grp1_periph_tim2); //设置预分频器 ll_tim_setprescaler(timx, 45); timx_freq = 45000000; timx_prescaler = 45; } //定时器选择时钟源 ll_tim_setclocksource(timx, ll_tim_clocksource_internal); //设置自动重载寄存器 ll_tim_setautoreload(timx, 2000 - 1); //设置计数方向 ll_tim_setcountermode(timx, ll_tim_countermode_center_up); //使能自动重载预装载 ll_tim_enablearrpreload(timx); if (channel == ll_tim_channel_ch1 || channel == ll_tim_channel_ch1n) { //设置比较值 ll_tim_oc_setcomparech1(timx, 1000 - 1); //设置成pwm模式 ll_tim_oc_setmode(timx, ll_tim_channel_ch1, ll_tim_ocmode_pwm1); //设置捕获/比较寄存器值 ll_tim_oc_enablepreload(timx, ll_tim_channel_ch1); } if (channel == ll_tim_channel_ch2 || channel == ll_tim_channel_ch2n) { //设置比较值 ll_tim_oc_setcomparech2(timx, 1000 - 1); //设置成pwm模式 ll_tim_oc_setmode(timx, ll_tim_channel_ch2, ll_tim_ocmode_pwm1); //设置捕获/比较寄存器值 ll_tim_oc_enablepreload(timx, ll_tim_channel_ch2); } //设置输出极性 ll_tim_oc_setpolarity(timx, channel, ll_tim_ocpolarity_high); //使能输出 ll_tim_enablealloutputs(timx); ll_tim_cc_enablechannel(timx, channel); //gpio初始化 gpio_init();}void stepper::gpio_init(){ if (timx == tim1) { //开启gpio时钟 ll_ahb1_grp1_enableclock(ll_ahb1_grp1_periph_gpioa); //gpio选为af //m1-dir ll_gpio_inittypedef gpio_initstruct = {0}; gpio_initstruct.mode = ll_gpio_mode_output; gpio_initstruct.outputtype = ll_gpio_output_pushpull; gpio_initstruct.pin = ll_gpio_pin_9; gpio_initstruct.pull = ll_gpio_pull_no; gpio_initstruct.speed = ll_gpio_speed_freq_medium; ll_gpio_init(gpioa, &gpio_initstruct); //m1-step gpio_initstruct.alternate = ll_gpio_af_1; gpio_initstruct.mode = ll_gpio_mode_alternate; gpio_initstruct.outputtype = ll_gpio_output_pushpull; gpio_initstruct.pin = ll_gpio_pin_8; gpio_initstruct.pull = ll_gpio_pull_no; gpio_initstruct.speed = ll_gpio_speed_freq_medium; ll_gpio_init(gpioa, &gpio_initstruct); } if (timx == tim2) { //开启gpio时钟 ll_ahb1_grp1_enableclock(ll_ahb1_grp1_periph_gpiob); ll_ahb1_grp1_enableclock(ll_ahb1_grp1_periph_gpioc); //gpio选为af //m2-dir ll_gpio_inittypedef gpio_initstruct = {0}; gpio_initstruct.mode = ll_gpio_mode_output; gpio_initstruct.outputtype = ll_gpio_output_pushpull; gpio_initstruct.pin = ll_gpio_pin_7; gpio_initstruct.pull = ll_gpio_pull_no; gpio_initstruct.speed = ll_gpio_speed_freq_medium; ll_gpio_init(gpioc, &gpio_initstruct); //m2-step gpio_initstruct.alternate = ll_gpio_af_1; gpio_initstruct.mode = ll_gpio_mode_alternate; gpio_initstruct.outputtype = ll_gpio_output_pushpull; gpio_initstruct.pin = ll_gpio_pin_3; gpio_initstruct.pull = ll_gpio_pull_no; gpio_initstruct.speed = ll_gpio_speed_freq_medium; ll_gpio_init(gpiob, &gpio_initstruct); }}void stepper::begin(){ ll_tim_enablecounter(timx);}void stepper::stop(){ ll_tim_disablecounter(timx);}void stepper::setdirection(dirction dir){ if (dir == inv) { if (timx == tim1) { ll_gpio_writeoutputport(gpiob, ll_gpio_readoutputport(gpiob) & (~ll_gpio_pin_4)); } if (timx == tim2) { ll_gpio_writeoutputport(gpiob, ll_gpio_readoutputport(gpiob) & (~ll_gpio_pin_10)); } } if (dir == pos) { if (timx == tim1) { ll_gpio_writeoutputport(gpiob, ll_gpio_readoutputport(gpiob) | (ll_gpio_pin_4)); } if (timx == tim2) { ll_gpio_writeoutputport(gpiob, ll_gpio_readoutputport(gpiob) | (ll_gpio_pin_10)); } }}void stepper::setfreq(uint16_t freq){ if (freq == 0) { ll_tim_disablecounter(timx); return; } else if (!ll_tim_isenabledcounter(timx)) { ll_tim_enablecounter(timx); } uint32_t arr_t = timx_freq / timx_prescaler / freq; if (arr_t > 65535) //触碰上限——频率过低 { timx_prescaler *= 10; //提高分频比 } if (arr_t 5000) speed = 5000; if (speed speed = speed; //将速度转化为定时器频率 uint16_t _freq = speed / 1.8; setfreq(_freq);}float stepper::getspeed(){ return speed;}

骁龙835:联发科、海思的10nm工艺跟自己无法比!
新款三星Galaxy S9上市,成功胜过苹果拔得印度手机市场头筹
对石墨烯知识的了解:石墨烯应用领域及面临的挑战
低功耗单电池供电升压电路图
一位软件测试工程师的艰辛成长之路
用TIM的PWM输出模式写一个步进电机的Stepper库函数
专家称,剪裁易拉罐能增强WiFi信号 方法如下文
市场资讯|意法半导体ST60毫米波非接触式连接器荣获“2023 CAIMRS自动化创新奖(工业通信类)”
安全身份为医疗保健引入IoMT认证
空调4G远程控制器是什么,有哪些优势
英飞凌携手北京中清怡和——SLE78超微型NFC安全模块荣获 中金国盛移动金融安全载体认证
如何检测湿度传感器性能?
secure boot的签名和验签方案
先进的数字隔离技术提高了太阳能逆变器的可靠性
单片机驱动蜂鸣器发声原理
芯片产业需要在全球范围内加强合作,共同打造芯片产业链
HOLTEK新推出HT45R5530 TRIAC LED调光照明OTP MCU
关于贴片电阻51Ω的规格号
纺织品燃烧性能测试法规以及性能测试方法
为防止密封条老化,我们该如何保养车门密封条