STM32的PWM控制步进电机脉冲频率,怎么实现精确控制输出脉冲数

(碧海蓝天)stm32_定时器3控制PWM的输出脉冲_步进电机的控制
碧海蓝天的步进电机控制程序采用定时器TIM3来控制PWM的输出来产生频率变化的脉冲。
过程:加速——匀速——减速——停止
文件:stepmotor.c&
定义步进电机控制程序
//用到的tim2为了实现另外的功能可以忽视
#include "stepmotor.h"
u32 PUL_CNT;&& //
TIM3脉冲计数
vu32 step_
#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_InitS
&NVIC_InitTypeDef NVIC_InitS
&TIM_TimeBaseInitTypeDef
TIM_TimeBaseS
&TIM_OCInitTypeDef TIM_OCInitS
&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&&&&&&&&
//预分频器,t=(23999+1)*(2+1)/72M
&TIM_TimeBaseStructure.TIM_CounterMode&&&&&&
= TIM_CounterMode_Up;
//计数器向上计数模式&&&&&
&TIM_TimeBaseStructure.TIM_ClockDivision&&&&
//时钟分频因子
&TIM_TimeBaseStructure.TIM_RepetitionCounter =
//每次溢出都产生事件更新
&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_E&&
//输入/捕获2输出允许
&TIM_OCInitStructure.TIM_Pulse&&&&&&
&&&&&&//确定占空比,这个值决定了有效电平的时间。
&TIM_OCInitStructure.TIM_OCPolarity&
= TIM_OCPolarity_L
//输出极性,低电平有效&&&
&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_IRQ& //选择定时器TIM3
&NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
1;&&&&&&&&&
//选择抢先式优先级(与中断嵌套级别有关)
&NVIC_InitStructure.NVIC_IRQChannelSubPriority&&&&&&&
//选择子优先级(同抢先式优先级的响应顺序)
&NVIC_InitStructure.NVIC_IRQChannelCmd&&&&&&&&&&&&&&&
= ENABLE;& & //选择使能中断源
&NVIC_Init(&NVIC_InitStructure);
&NVIC_InitStructure.NVIC_IRQChannel
= TIM2_IRQ& //选择定时器TIM2
&NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
1;&&&&&&&&&
//选择抢先式优先级(与中断嵌套级别有关)
&NVIC_InitStructure.NVIC_IRQChannelSubPriority&&&&&&&
//选择子优先级(同抢先式优先级的响应顺序)
&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_TimeBaseS
&//TIM_OCInitTypeDef TIM_OCInitS
&//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&&&&
//时钟分频因子
&//TIM_TimeBaseStructure.TIM_RepetitionCounter =
//每次溢出都产生事件更新
&//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_E&&
//输入/捕获2输出允许
&//TIM_OCInitStructure.TIM_Pulse&&&&&&
= period && 2;
&&&&//确定占空比,25%
&//TIM_OCInitStructure.TIM_OCPolarity&
= TIM_OCPolarity_L
//输出极性,低电平有效&&&
&//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)
t_acc,t_dec,step_all,step_acc,step_dec,step_
i,tim_cnt,tim_rest,tim_cnt_
&&step_all = (float)dis *
(N_MOTOR * 0.0001);
&&t_acc = topspeed * 1000 /
&//unit: ms
&&t_dec = topspeed * 1000 /
&//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);
= topspeed * 1000 /&//unit: ms
= topspeed * 1000 /&//unit:
&&step_acc = N_MOTOR *
((float)topspeed*topspeed/(acc*120));
&&step_dec = N_MOTOR *
((float)topspeed*topspeed/(dec*120));
&&if(step_all & step_acc +
&&&step_run =
step_all - step_acc - step_
&&&step_run =
&&//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;
&&TIM3_Configuration(tim_cnt);
&&run_state =
run_state_
&&TIM_Cmd(TIM3,ENABLE);
&&step_done = 0;
&&while(step_done==0);
&&&&//tim_cnt_temp
&&&&//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
&&&&while(step_done==0);
&&if(step_run & 0)
&&&&run_state
= run_state_
&&&&tim_cnt
= ft * 60 / (N_MOTOR*topspeed);
&&&&TIM3_Configuration(tim_cnt);
&&&&while(i
&&&&&&step_done
&&&&&&while(step_done==0);
&&&&&&i++;
&&run_state =
run_state_
&&tim_rest = 0;
&&tim_cnt = tim_cnt +
(2*tim_cnt+tim_rest) / (4*(step_dec-i)-1);
&&&&TIM3_Configuration(tim_cnt);
&&&&step_done
&&&&while(step_done==0);
&&&&tim_cnt_temp
&&&&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_
&&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
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);
&&SET_DIR_CW();
&&MOTOR_RUN(600,600,);
&&soft_delayms(1000);
&&SET_DIR_CCW();
&&MOTOR_RUN(600,600,);
&&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_InitS
&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)
&while(t--)
&&tt = 10000;
&&while(tt--);
#ifndef& _MAIN_H
#define& _MAIN_H
#include "stm32f10x.h"
#include "stepmotor.h"
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。查看: 3107|回复: 10
求教怎么用PWM精确输出脉冲数控制步进电机的转动
主题帖子精华
初级会员, 积分 56, 距离下一级还需 144 积分
在线时间7 小时
求求各位帮帮忙,我们是真没时间了,就卡在这里,马上就要比赛了但是这个搞不定...........我也是半路出家才搞了两个星期,能正常输出pwm但是确定脉冲数真的不行了。求给代码,F4的板子,我也不想伸手的,可是5月3日就校内比赛了,对不起各位求求帮帮忙,现在就差这块了
/thread-.html
主题帖子精华
在线时间556 小时
主题帖子精华
高级会员, 积分 526, 距离下一级还需 474 积分
在线时间53 小时
利用外部中断计数来知道你的脉冲数。
比如说你的PA0用来输出PWm脉冲。把PA0和PA1短接在一起(条件允许中间也可以接一个电阻),PA1使用外部中断上升沿触发,这样一个脉冲就会进入一次中断。在中断中你可以知道脉冲出现的次数的。你说的这些描述,没有贴代码,别人给不了你代码,给了不一定实用。看我给你说的方法你是否可以操作。(这个操作简单计数准,但是你必须可以修改硬件)
假设你不能短接,你做一个和PWM同频率的定时器。用定时器来计算PWM输出多少个周期了。(计数可能有偏差,但程序逻辑控制的好可以做到没有偏差)
或许STM32内部有可以计数的,但是我不会。(你请教一下高手吧)
另外,你是那个学校的?
祝你比赛拿到好成绩!
主题帖子精华
初级会员, 积分 56, 距离下一级还需 144 积分
在线时间7 小时
利用外部中断计数来知道你的脉冲数。
比如说你的PA0用来输出PWm脉冲。把PA0和PA1短接在一起(条件允许中间 ...
谢谢我试试看,我们是上大的, 马上要参加机械创新大赛了,先校内选拔再去,我们做好了三轴移动平台准备做钱币分类。我当时也是失策了,我们小组全是机械的,我也是机械生,不过当年参加飞思卡尔智能车有点基础........结果程序都得我来...........所以我压力特别大,还不停地遇到各种各样的麻烦(昨天是matlab与stm32的串口收发问题.......)
主题帖子精华
初级会员, 积分 56, 距离下一级还需 144 积分
在线时间7 小时
利用外部中断计数来知道你的脉冲数。
比如说你的PA0用来输出PWm脉冲。把PA0和PA1短接在一起(条件允许中间 ...
我之前使用TIM3定时器,想在里面设置个中断,在中断中计数控制脉冲个数,根本不行,停不下来
主题帖子精华
高级会员, 积分 526, 距离下一级还需 474 积分
在线时间53 小时
我之前使用TIM3定时器,想在里面设置个中断,在中断中计数控制脉冲个数,根本不行,停不下来
计数的数据你得到了吗?是什么停不下来?
主题帖子精华
初级会员, 积分 56, 距离下一级还需 144 积分
在线时间7 小时
#include &sys.h&
#include &delay.h&
#include &usart.h&
#include &led.h&
#include &timer.h&
//ALIENTEK ̽Ë÷ÕßSTM32F407¿ª·¢°å ʵÑé10
//ÊäÈ벶»ñʵÑé -¿âº¯Êý°æ±¾
//¼¼ÊõÖ§³Ö£º
//ÌÔ±¦µêÆÌ£º&&
//¹ãÖÝÊÐÐÇÒíµç×ӿƼ¼ÓÐÏÞ¹«Ë¾&&
//×÷ÕߣºÕýµãÔ­×Ó @ALIENTEK
extern u8&&TIM5CH1_CAPTURE_STA;& & & & & & & & //ÊäÈ벶»ñ״̬& & & & & & & && &&&& & & & & & & & & & & & & & & &
extern u32& & & & TIM5CH1_CAPTURE_VAL;& & & & //ÊäÈ벶»ñÖµ&&
&&u32 run_com=3200*5;
& & & & u32 run_cnt=0;
int main(void)
& & & & long long temp=0;&&
& & & & NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é2
& & & & delay_init(168);&&//³õʼ»¯ÑÓʱº¯Êý
& & & & uart_init(115200);//³õʼ»¯´®¿Ú²¨ÌØÂÊΪ115200
& & & & TIM3_PWM_Init(-1);& && & & & & & //84M/84=1MhzµÄ¼ÆÊýƵÂʼÆÊýµ½500,PWMƵÂÊΪ1M/500=2Khz& &&&
& & & & TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1); //ÒÔ1MhzµÄƵÂʼÆÊý
& && & & & while(1)
& & & & & & & & delay_ms(10);
& & & & & & & & TIM_SetCompare1(TIM14,150);
& & & & & & & & if(TIM5CH1_CAPTURE_STA&0X80)& && &&&//³É¹¦²¶»ñµ½ÁËÒ»´Î¸ßµçƽ
& & & & & & & & {
& & & & & & & & & & & & temp=TIM5CH1_CAPTURE_STA&0X3F;
& & & & & & & & & & & & temp*=0XFFFFFFFF;& & & & & & & &&&& & & & & & & && && && & //Òç³öʱ¼ä×ܺÍ
& & & & & & & & & & & & temp+=TIM5CH1_CAPTURE_VAL;& & & & & & & && & //µÃµ½×ܵĸߵçƽʱ¼ä
& & & & & & & & & & & & printf(&HIGH:%lld us\r\n&,temp); //´òÓ¡×ܵĸߵãƽʱ¼ä
& & & & & & & & & & & & run_cnt++;
& & & & & & & & & & & & if(run_cnt==run_com)TIM_Cmd(TIM3,DISABLE);
& & & & & & & & & & & & TIM5CH1_CAPTURE_STA=0;& & & & & & & & & & & && && &//¿ªÆôÏÂÒ»´Î²¶»ñ
& & & & & & & & & & & &
& & & & & & & & }
捕获到了,但是停不下来
主题帖子精华
初级会员, 积分 56, 距离下一级还需 144 积分
在线时间7 小时
计数的数据你得到了吗?是什么停不下来?
用捕获的方法成功了,谢谢大神。还有个问题,我现在想用按钮打开定时器,但是不行,代码如下
#include &sys.h&
#include &delay.h&
#include &usart.h&
#include &led.h&
#include &timer.h&
#include &key.h&
//ALIENTEK ̽Ë÷ÕßSTM32F407¿ª·¢°å ʵÑé10
//ÊäÈ벶»ñʵÑé -¿âº¯Êý°æ±¾
//¼¼ÊõÖ§³Ö£º
//ÌÔ±¦µêÆÌ£º&&
//¹ãÖÝÊÐÐÇÒíµç×ӿƼ¼ÓÐÏÞ¹«Ë¾&&
//×÷ÕߣºÕýµãÔ­×Ó @ALIENTEK
extern u8&&TIM5CH1_CAPTURE_STA;& & & & & & & & //ÊäÈ벶»ñ״̬& & & & & & & && &&&& & & & & & & & & & & & & & & &
extern u32& & & & TIM5CH1_CAPTURE_VAL;& & & & //ÊäÈ벶»ñÖµ&&
u32 run_cnt=1;
int main(void)
& & & & u8
& & & & long long temp=0;&&
& & & & NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é2
& & & & delay_init(168);&&//³õʼ»¯ÑÓʱº¯Êý
& & & & uart_init(115200);//³õʼ»¯´®¿Ú²¨ÌØÂÊΪ115200
& & & & KEY_Init();
& & & & TIM3_PWM_Init(-1);& && & & & & & //84M/84=1MhzµÄ¼ÆÊýƵÂʼÆÊýµ½500,PWMƵÂÊΪ1M/500=2Khz& &
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,DISABLE);& & & &
& & & & TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1); //ÒÔ1MhzµÄƵÂʼÆÊý
& & & & TIM_SetCompare1(TIM3,150);
& &while(1)
& & & & & & & & key=KEY_Scan(0);
& & & & & & & & switch(key)
& & & & & & & &&&{
& & & & & & & & & & & &&&case KEY0_PRES:
& & & & & & & & & & & & & & & &&&run_cnt=0;
& & & & & & & & & & & &&&TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);& & & &
& & & & & & & & & & & &&&TIM_Cmd(TIM5,ENABLE);
& & & & & & & & & & & &&&TIM_Cmd(TIM3,ENABLE);
& & & & & & & & & & & &&&while(run_cnt&=312)
& & & & & & & & & & & &&&{
& & & & & & & & & & & &&&if(TIM5CH1_CAPTURE_STA&0X80)
& & & & & & & & & & & &&&{
& & & & & & & & & & & & & & & && & run_cnt++;
& & & & & & & & & & & & & & & &&&& & & &&&temp=TIM5CH1_CAPTURE_STA&0X3F;
& & & & & & & & & & & && && &temp*=0XFFFFFFFF;& & & & & & & &&&& & & & & & & && && && & //Òç³öʱ¼ä×ܺÍ
& & & & & & & & & & & && && &temp+=TIM5CH1_CAPTURE_VAL;& & & & & & & && & //µÃµ½×ܵĸߵçƽʱ¼ä
& & & & & & & & & & & && && &printf(&HIGH:%lld us\r\n&,temp); //´òÓ¡×ܵĸߵãƽʱ¼ä
& & & & & & & & & & & && && &TIM5CH1_CAPTURE_STA=0;& & & & & & & & & & & && && &//¿ªÆôÏÂÒ»´Î²¶»ñ
& & & & & & & & & & & &&&}
& & & & & & & & & & & &&&}
& & & & & & & & & & & &&&TIM_Cmd(TIM3,DISABLE);
& & & & & & & & & & & &&&TIM_Cmd(TIM5,DISABLE);
& & & & & & & & & & & && &TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,DISABLE);& & & &
& & & & & & & & & & & &&&
& & & & & & & &&&}
主题帖子精华
初级会员, 积分 56, 距离下一级还需 144 积分
在线时间7 小时
我再发一遍有乱码
#include &sys.h&
#include &delay.h&
#include &usart.h&
#include &led.h&
#include &timer.h&
#include &key.h&
extern u8&&TIM5CH1_CAPTURE_STA;& & & & & & & && &&&& & & & & & & & & & & & & & & &
extern u32& & & & TIM5CH1_CAPTURE_VAL;& & & &
u32 run_cnt=1;
int main(void)
& & & & u8
& & & & long long temp=0;&&
& & & & NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
& & & & delay_init(168);&&
& & & & uart_init(115200);
& & & & KEY_Init();
& & & & TIM3_PWM_Init(-1);& && & & & & &
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,DISABLE);& & & &
& & & & TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1);
& & & & TIM_SetCompare1(TIM3,150);
& &while(1)
& & & & & & & & key=KEY_Scan(0);
& & & & & & & & switch(key)
& & & & & & & &&&{
& & & & & & & & & & & &&&case KEY0_PRES:
& & & & & & & & & & & & & & & &&&run_cnt=0;
& & & & & & & & & & & &&&TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);& & & &
& & & & & & & & & & & &&&TIM_Cmd(TIM5,ENABLE);
& & & & & & & & & & & &&&TIM_Cmd(TIM3,ENABLE);
& & & & & & & & & & & &&&while(run_cnt&=312)
& & & & & & & & & & & &&&{
& & & & & & & & & & & &&&if(TIM5CH1_CAPTURE_STA&0X80)
& & & & & & & & & & & &&&{
& & & & & & & & & & & & & & & && & run_cnt++;
& & & & & & & & & & & & & & & &&&& & & &&&temp=TIM5CH1_CAPTURE_STA&0X3F;
& & & & & & & & & & & && && &temp*=0XFFFFFFFF;& & & & & & & &&&& & & & & & & && && &
& & & & & & & & & & & && && &temp+=TIM5CH1_CAPTURE_VAL;& & & & & & & &
& & & & & & & & & & & && && &printf(&HIGH:%lld us\r\n&,temp);
& & & & & & & & & & & && && &TIM5CH1_CAPTURE_STA=0;& & & & & & & & & & & &&&
& & & & & & & & & & & &&&}
& & & & & & & & & & & &&&}
& & & & & & & & & & & &&&TIM_Cmd(TIM3,DISABLE);
& & & & & & & & & & & &&&TIM_Cmd(TIM5,DISABLE);
& & & & & & & & & & & && &TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,DISABLE);& & & &
& & & & & & & & & & & &&&
& & & & & & & &&&}
主题帖子精华
高级会员, 积分 543, 距离下一级还需 457 积分
在线时间78 小时
我之前使用TIM3定时器,想在里面设置个中断,在中断中计数控制脉冲个数,根本不行,停不下来
中断里设置一个标志位,然后设一个变量,每中断一次变量+1,电机要启动前变量清零,开标志位,变量到的你需要的参数时候标志位清除,使能关,时钟关不关看你程序了,电机就停了
主题帖子精华
高级会员, 积分 526, 距离下一级还需 474 积分
在线时间53 小时
我再发一遍有乱码
#include &sys.h&
这几天放假了,没在公司。你把关断的部分放在你的捕获的中断里面。我不知道你键盘检测如何写的,但我觉得如果你一直按着按键不丢,也许在某一个时刻可以关掉。可能是逻辑上的一点问题,但也不敢十分确定,只有做了实验我才能确定!
Powered bySTM32如何控制PWM脉冲输出数量 - 【stm32/stm8】 - 电子工程世界-论坛
后使用快捷导航没有帐号?
请完成以下验证码
查看: 17734|回复: 17
STM32如何控制PWM脉冲输出数量
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&STM32如何控制PWM脉冲输出数量,,我用PWM脉冲来做我外设的同步时钟所以需要确切的数值!
&&&&&&&&&&
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 1, 距离下一级还需 4 积分
一粒金砂(初级), 积分 1, 距离下一级还需 4 积分
用到了Timer Master Slave中的Gate模式
比如TIM1输出PWM, 频率为F
可以用TIM2通过Gate来控制TIM1的输出
将TIM2预分频设为<font color="#/(F*<font color="#),则TIM2的Period 就是 脉冲个数*<font color="# - <font color="#/*& && && &&&1& &&&2& &&&3& &&&4& &&&5& &&&6& &&&7& &&&8& &&&9
& && && && & __& & __& & __& & __& & __& & __& & __& & __& & __& && && && & & && && && &|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|&&|& && && && &
TIM1:& & ___|&&|__|&&|__|&&|__|&&|__|&&|__|&&|__|&&|__|&&|__|&&|_ & && && & -&| Period1|&-
& && && && & 1) 2) 3) 4) 5) 6) 7) 8) 9) 10)11)12)13)14)15)16)17)
& && && && & __________________________________________________& & & && && && &|& && && && && && && && && && && && && && && && &&&|& & TIM2:& & ___|& && && && && && && && && && && && && && && && &&&|_ & && && & -&|&&|&--- Pres2 = Period1/2
& && && && &|&------------&&Period2 =&&N*2-1 = 17 ------------&|
*/ 复制代码
<p id="rate_013" onmouseover="showTip(this)" tip="很给力!&芯币 + 1 枚
威望 + 1 分
" class="mtn mbn">
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&开中断,每输出一个脉冲进一次中断,计数器+1,到点了关掉。
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&我的PWM的更新事件是用来做SRAM-&GPIO的触发源的,这样GPIO送数就可以达到5M的速度,但需要严格控制PWM更新事件的数量,如果想2楼说的操作,是可以实现计数,估计DMA送数就没法达到这样高的数量级了,可能就1M~!&&有更好的办法吗,比如TIME1的PWM模式有哪里可以设置输出脉冲数量的!
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
IAR <font color="#.42限制版
ST库& & <font color="#.01
万利<font color="#9开发板 STM3210B-LK1
/* Includes ------------------------------------------------------------------*/
#include &stm32f10x_lib.h&
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
ErrorStatus HSEStartUpS
/* Private function prototypes -----------------------------------------------*/
void&&RCC_Configuration(void);
void&&NVIC_Configuration(void);
/* Private functions ---------------------------------------------------------*/
#define& &PWM_Period& && &<font color="#0
int main(void)
&&u16& && & waveNumber = <font color="#;
&&/* System Clocks Configuration */
&&RCC_Configuration();
&&/* Enable related peripheral clocks */
&&RCC_APB2PeriphClockCmd(&&RCC_APB2Periph_GPIOA,ENABLE);
&&RCC_APB2PeriphClockCmd(&&RCC_APB2Periph_GPIOB,ENABLE);
&&RCC_APB2PeriphClockCmd(&&RCC_APB2Periph_TIM1,ENABLE);
&&RCC_APB1PeriphClockCmd(&&RCC_APB1Periph_TIM3,ENABLE);
&&/* Config IO for related timers */
& & GPIO_InitTypeDef GPIO_InitS
& & /* Timer1 Channel 2, PA9 */
& & GPIO_InitStructure.GPIO_Pin =&&GPIO_Pin_9;
& & GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
& & GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
& & GPIO_Init(GPIOA, &GPIO_InitStructure);
& & /* Timer3 Channel 4, PB1*/
& & GPIO_InitStructure.GPIO_Pin =&&GPIO_Pin_1;
& & GPIO_Init(GPIOB, &GPIO_InitStructure);
&&/* Setup Timer3 channel 4, Timer3 is master timer
& &&&This timer is used to control the waveform count of timer1 */
& & TIM_TimeBaseInitTypeDef&&TIM_TimeBaseS
& & TIM_OCInitTypeDef&&TIM_OCInitS
& & TIM_DeInit(TIM3);
& & TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
& & TIM_OCStructInit(&TIM_OCInitStructure);
& & TIM_TimeBaseStructure.TIM_Prescaler = PWM_Period/<font color="# - <font color="#;
& & TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
& & TIM_TimeBaseStructure.TIM_Period = waveNumber*<font color="#;
& & TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
& & TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
& & /* Timer2 Channel 3 Configuration in PWM2 mode, this is used for enable Recive clcok */
& & TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
& & TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E
& & TIM_OCInitStructure.TIM_Pulse = waveNumber*<font color="# - <font color="#;
& & TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_H
& & TIM_OC4Init(TIM3,&TIM_OCInitStructure);
& & TIM_CtrlPWMOutputs(TIM3, ENABLE);
& & TIM_SelectOnePulseMode(TIM3, TIM_OPMode_Single);
&&/* Setup timer1 channel 2, Timer1 is slave timer&&
& &&&This timer is used to output waveforms */
& & TIM_TimeBaseInitTypeDef&&TIM_TimeBaseS
& & TIM_OCInitTypeDef&&TIM_OCInitS
& & TIM_DeInit(TIM1);
& & TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
& & TIM_OCStructInit(&TIM_OCInitStructure);
& & TIM_TimeBaseStructure.TIM_Prescaler = <font color="#;
& & TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
& & TIM_TimeBaseStructure.TIM_Period = PWM_P
& & TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
& & TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
& & /* Timer2 Channel 3 Configuration in PWM2 mode, this is used for enable Recive clcok */
& & TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
& & TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_E
& & TIM_OCInitStructure.TIM_Pulse = PWM_Period/<font color="#;
& & TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_H
& & TIM_OC2Init(TIM1,&TIM_OCInitStructure);
& & TIM_CtrlPWMOutputs(TIM1, ENABLE);
&&/* Create relationship between timer1 and timer3, timer3 is master, timer1 is slave
& & timer1 is work under gate control mode, and controled by timer3
& & timer3's channel 4 is used as the control signal
& & /* Enable timer's master/slave work mode */
& & TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Enable);
& & TIM_SelectMasterSlaveMode(TIM1,TIM_MasterSlaveMode_Enable);
& & /* timer3's channel 4 is used as the control signal */
& & TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_OC4Ref );
& & /* Check the master/slave is valid or not */
& & compile_assert((u16)GetInternalTrigger(TIM1,TIM3) != (u16)-1);&&
& & /* Config timer1's external clock */
& & TIM_ITRxExternalClockConfig(TIM1, GetInternalTrigger(TIM1,TIM3));
& & TIM_SelectSlaveMode(TIM1,TIM_SlaveMode_Gated);
&&/* Enable the slave tiemr*/
&&TIM_Cmd(TIM1,ENABLE);
&&//SetupAlltimers();
&&while(<font color="#){
& & /* Check whether the previous action is done or not */
& & if(!(TIM3-&CR1 & <font color="#)){
& && &TIM1-&CNT = <font color="#; /* It would be very perfect if gate mode can&&
& && && && && && && && &reset the slave timer automatically */
& && &TIM3-&ARR = waveNumber*<font color="#;&&/* Reload wave number*/
& && &TIM3-&CCR4 = waveNumber*<font color="# - <font color="#;
& && &TIM3-&CR1|=<font color="#; /* Re-enable the timer */
& && &/* update waveform number */
& && &waveNumber++;
& && &if(waveNumber == <font color="#){
& && &&&waveNumber = <font color="#;
/*******************************************************************************
* Function Name&&: RCC_Configuration
* Description& & : Configures the different system clocks.
* Input& && && & : None
* Output& && && &: None
* Return& && && &: None
*******************************************************************************/
void RCC_Configuration(void)
&&/* RCC system reset(for debug purpose) */
&&RCC_DeInit();
&&/* Enable HSE */
&&RCC_HSEConfig(RCC_HSE_ON);
&&/* Wait till HSE is ready */
&&HSEStartUpStatus = RCC_WaitForHSEStartUp();
&&if(HSEStartUpStatus == SUCCESS)
& & /* Enable Prefetch Buffer */
& & FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
& & /* Flash 2 wait state */
& & FLASH_SetLatency(FLASH_Latency_2);
& & /* HCLK = SYSCLK */
& & RCC_HCLKConfig(RCC_SYSCLK_Div1);&&
& & /* PCLK2 = HCLK */
& & RCC_PCLK2Config(RCC_HCLK_Div1);&&
& & /* PCLK1 = HCLK/2 */
& & RCC_PCLK1Config(RCC_HCLK_Div2);
& & /* PLLCLK = 8MHz * 9 = 72 MHz */
& & RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
& & /* Enable PLL */&&
& & RCC_PLLCmd(ENABLE);
& & /* Wait till PLL is ready */
& & while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
& & /* Select PLL as system clock source */
& & RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
& & /* Wait till PLL is used as system clock source */
& & while(RCC_GetSYSCLKSource() != <font color="#x08)
输出波形如下图
在线时间1 小时
TA的帖子TA的资源
提示: 作者被禁止或删除 内容自动屏蔽
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&5楼的代码好长啊
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&还是没看到问题的解决方法
在线时间170 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
5楼的代码好长啊
这只能怪ST的库了
用寄存器直接操作意思会很不明确
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
谢谢5楼给的信息,我测试了下,确实能出现你说的那波形,10、11、12脉冲间隔输出,但理论上如果我的主TIME3只让他运行一次,即产生一次脉冲,当主TIME3结束后从TIME1 的波形应该当也更随结束,但我测试结果是TIME1小停后产生连续的PWM波形,就是说TIME1 没停止工作!
在线时间1 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_OC4Ref );& &比较成功后,产生一次TRGO脉冲(即时是高电平),那就是说在正常情况下TRGO 都是高电平,只有在强制产生脉冲的时候,才有一瞬间的低电平,只有这个时候从TIM3才会停止PWM输出,又因为&&TIM_SelectSlaveMode(TIM1,TIM_SlaveMode_Gated); 从TIME1的TRGI模式是 TIM_SlaveMode_Gated(当触发信号TRGI为高电平计数器时钟时能),所以即时主TIM1做一个周期后停止工作,TRGO能然是高电平,TIME3继续PWM输出!
这个我的理解,能否找出个解决的办法,可以使主TIM1停止后TIM3也立即停止,使用中断除外!
在线时间1 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
TIM3作为主时钟,配置为OnePulse模式,OC4为PWM模式1
TRGO设置为OC4的Ref信号,OC4Ref在CNT&CCR4时输出高电平(TIM1工作),这之后输出低电平(TIM1停止)
由于TIM3是OnePulse,CNT=ARR之后TIM3就停了,不会再输出了,会保持低电平状态
在线时间2 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&不可能,我今天用示波器跟踪了,TIM1在TIM3停止工作后,还是输出PWM脉冲,后来我用了TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_Enable); 来触发,当主TIM3计数器使能,产生TRGO信号触发从TIM3开始工作,当TIM3计数完毕后,TIM3失效,相应的TRGO应该也是低电压,才是得从TIME1停止工作
在线时间3 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
你的这个配置能达到你的要求,只要把Prescaler和Period设置得合适就行了
我的那个没有仔细测试过,楼主最好用你的试过可行的方法来做
回头我再看看我的为什么不行
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
& & & & & & & & & & & & & & & &&&强&&都是牛人呀
在线时间17 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
一粒金砂(初级), 积分 2, 距离下一级还需 3 积分
STM32如何控制PWM脉冲输出数量
在线时间1417 小时
威望6300分
芯币21629枚
E金币300枚
TA的帖子TA的资源
STM32如何控制PWM脉冲输出数量
溢出计数就是个数
在线时间5 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
一粒金砂(初级), 积分 4, 距离下一级还需 1 积分
学习学习!
EEWORLD 官方微信
EE福利 唾手可得
Powered by}

我要回帖

更多关于 步进电机脉冲发生器 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信