完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
采用定时器TIM3来控制PWM的输出来产生频率变化的脉冲。
过程:加速——匀速——减速——停止 文件:stepmotor.c 定义步进电机控制程序 //用到的tim2为了实现另外的功能可以忽视 #include "stepmotor.h" #include u32 PUL_CNT; // TIM3脉冲计数 vu32 step_done; vu32 run_state; #define run_state_stop 0 #define run_state_acc 1 #define run_state_run 2 #define run_state_dec 3 void STEPMOTOR_CTRL_INIT(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //GPIO时钟使能 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //定时器3时钟使能 //RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //定时器2时钟使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //PA7为TIM3通道2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推免输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO口响应速度 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PA6为DIR控制输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推免输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO口响应速度 GPIO_Init(GPIOA, &GPIO_InitStructure); //TIM3_Configuration TIM_TimeBaseStructure.TIM_Period = 23999; //自动重装载寄存器 TIM_TimeBaseStructure.TIM_Prescaler = 2; //预分频器,t=(23999+1)*(2+1)/72M TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器向上计数模式 TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //时钟分频因子 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0; //每次溢出都产生事件更新 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); //写TIM3各寄存器参数 TIM_ClearFlag(TIM3,TIM_FLAG_Update); //中断标志位清零 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许捕获/比较3中断 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2 TIM3_CCMR1[14:12]=111 在向上计数时,一旦TIMx_CNT TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输入/捕获2输出允许 TIM_OCInitStructure.TIM_Pulse = 40; //确定占空比,这个值决定了有效电平的时间。 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性,低电平有效 TIM_OC2Init(TIM3, &TIM_OCInitStructure); //配置定时器输出模式,比较参数等 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器 //TIM2_Configuration TIM_DeInit(TIM2); //TIM2重新配置为缺省值,默认状态 TIM_TimeBaseStructure.TIM_Period = 359; //自动重装载寄存器 TIM_TimeBaseStructure.TIM_Prescaler = 199; //时钟预分频器 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器向上计数模式 TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //时钟分频因子 TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); //配置TIM2寄存器各参数 TIM_ClearFlag(TIM2,TIM_FLAG_Update); //中断标志位清零 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //允许捕获/比较2中断 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn ; //选择定时器TIM3 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //选择抢先式优先级(与中断嵌套级别有关) NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //选择子优先级(同抢先式优先级的响应顺序) NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //选择使能中断源 NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ; //选择定时器TIM2 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //选择抢先式优先级(与中断嵌套级别有关) NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //选择子优先级(同抢先式优先级的响应顺序) NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //选择使能中断源 NVIC_Init(&NVIC_InitStructure); } void TIM3_Configuration(u32 period) { TIM3->ARR = period-1; TIM3->CCR2 = period >> 2; //TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //TIM_OCInitTypeDef TIM_OCInitStructure; //TIM_TimeBaseStructure.TIM_Period = period-1; //自动重装载寄存器 //TIM_TimeBaseStructure.TIM_Prescaler = 29; //预分频器,f=72M/[(period+1)*(29+1)], ft = 2400000 //TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器向上计数模式 //TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //时钟分频因子 //TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0; //每次溢出都产生事件更新 //TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); //写TIM3各寄存器参数 //TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2 TIM3_CCMR1[14:12]=111 在向上计数时,一旦TIMx_CNT //TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输入/捕获2输出允许 //TIM_OCInitStructure.TIM_Pulse = period >> 2; //确定占空比,25% //TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性,低电平有效 //TIM_OC2Init(TIM3, &TIM_OCInitStructure); //配置定时器输出模式,比较参数等 } //void MOTOR_RUN(u32 acc, u32 dec, u32 topspeed, u32 dis) //步进电机运行参数 //acc -- 加速度,单位: round/min/s //dec -- 减速度,单位: round/min/s //topspeed -- 最高速度,单位: round/min //dis -- 总角位移,单位: round/10000 void MOTOR_RUN(u32 acc, u32 dec, u32 topspeed, u32 dis) { u32 t_acc,t_dec,step_all,step_acc,step_dec,step_run; u32 i,tim_cnt,tim_rest,tim_cnt_temp; step_all = (float)dis * (N_MOTOR * 0.0001); t_acc = topspeed * 1000 / acc; //unit: ms t_dec = topspeed * 1000 / dec; //unit: ms if(topspeed * (t_acc + t_dec) / 12 > dis) //达不到最高速度 // topspeed/60/1000 * (t_acc + t_dec) / 2 > dis / 10000 { topspeed = sqrt(dis * acc * dec * 12 / (acc + dec) / 1000); t_acc = topspeed * 1000 / acc; //unit: ms t_dec = topspeed * 1000 / dec; //unit: ms } step_acc = N_MOTOR * ((float)topspeed*topspeed/(acc*120)); step_dec = N_MOTOR * ((float)topspeed*topspeed/(dec*120)); if(step_all > step_acc + step_dec) step_run = step_all - step_acc - step_dec; else step_run = 0; //tim_cnt = 5.2363 * ft / (sqrt(acc*N_MOTOR/2)); //(ft * sqrt(60)*0.676) / sqrt(acc*N_MOTOR/2); tim_cnt = 7.7460 * ft / (sqrt(acc*N_MOTOR/2)); tim_rest = 0; i = 0; TIM3_Configuration(tim_cnt); run_state = run_state_acc; TIM_Cmd(TIM3,ENABLE); step_done = 0; while(step_done==0); while(i { i++; //tim_cnt_temp = tim_cnt; //tim_cnt = tim_cnt - (2*tim_cnt+tim_rest) / (4*i+1); //tim_rest = (2*tim_cnt_temp+tim_rest) % (4*i+1); tim_cnt_temp = tim_cnt / ( sqrt((float)(i+1)) + sqrt((float)(i)) ); TIM3_Configuration(tim_cnt_temp); step_done = 0; while(step_done==0); } if(step_run > 0) { run_state = run_state_run; tim_cnt = ft * 60 / (N_MOTOR*topspeed); i = 0; TIM3_Configuration(tim_cnt); while(i { step_done = 0; while(step_done==0); i++; } } run_state = run_state_dec; tim_rest = 0; i=0; tim_cnt = tim_cnt + (2*tim_cnt+tim_rest) / (4*(step_dec-i)-1); while(i { TIM3_Configuration(tim_cnt); step_done = 0; while(step_done==0); i++; tim_cnt_temp = tim_cnt; tim_cnt = tim_cnt + (2*tim_cnt+tim_rest) / (4*(step_dec-i)-1); tim_rest = (2*tim_cnt_temp+tim_rest) % (4*(step_dec-i)-1); } run_state = run_state_stop; TIM_Cmd(TIM3,DISABLE); } void TIM2_IRQHandler(void) { } void TIM3_IRQHandler(void) { TIM_ClearFlag(TIM3,TIM_FLAG_Update); step_done = 1; //PUL_CNT++; } 文件:stepmotor.h 声明步进电机控制头文件 #define N_MOTOR 10000 //步进电机细分 #define ft 24000000 void STEPMOTOR_CTRL_INIT(void); void MOTOR_RUN(u32 acc, u32 dec, u32 topspeed, u32 dis); 文件:main.c 主函数,设置加速度,减速度,最大速度和步数的参数值 #include "main.h" #define LED_SET() GPIO_SetBits(GPIOB,GPIO_Pin_8) #define LED_RST() GPIO_ResetBits(GPIOB,GPIO_Pin_8) #define SET_DIR_CW() GPIO_SetBits(GPIOA,GPIO_Pin_6) #define SET_DIR_CCW() GPIO_ResetBits(GPIOA,GPIO_Pin_6) void NVIC_Configuration(void); void LED_init(void); void soft_delayms(u16 t); int main(void) { SystemInit(); STEPMOTOR_CTRL_INIT(); soft_delayms(1000); while(1) { SET_DIR_CW(); MOTOR_RUN(600,600,1000,500000); soft_delayms(1000); SET_DIR_CCW(); MOTOR_RUN(600,600,1000,500000); soft_delayms(1000); } return 0; } void NVIC_Configuration(void) { NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000); //将中断矢量放到Flash的0地址 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //设置优先级配置的模式,详情请阅读原材料中的文章 } void LED_init(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); } void soft_delayms(u16 t) { u16 tt; while(t--) { tt = 10000; while(tt--); } } #ifndef _MAIN_H #define _MAIN_H #include "stm32f10x.h" #include "stepmotor.h" #endif |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1641 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1562 浏览 1 评论
988 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
691 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1608 浏览 2 评论
1869浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
655浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
525浏览 3评论
540浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
512浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 03:20 , Processed in 0.663824 second(s), Total 75, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号