OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3834|回复: 20

PWM脉冲输出,调节步进电机

[复制链接]

6

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2016-4-25
在线时间
16 小时
发表于 2016-4-26 11:45:46 | 显示全部楼层 |阅读模式
2金钱
我现在做到用stm32使用TIM3生成PWM波控制电机旋转,但是一直产生PWM,现在我想让电机转一定的角度,怎么产生若干个脉冲控制电机?

最佳答案

查看完整内容[请看2#楼]

[mw_shl_code=c,true]static void TIM2_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* TIM2 开启时钟 */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* TIM2基本配置 */ TIM_TimeBaseStructure.TIM_Period = Speed; TIM_TimeBaseStructure.TIM_Prescaler = 0 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

21

主题

144

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1132
金钱
1132
注册时间
2015-7-31
在线时间
155 小时
发表于 2016-4-26 11:45:47 | 显示全部楼层
本帖最后由 lx911gt 于 2016-4-28 12:37 编辑
kaiyuan123 发表于 2016-4-28 11:38
是用一个定时器吗,怎么设置输出比较的,能不能发个代码

[mw_shl_code=c,true]static void TIM2_Config(void)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
        
        /* TIM2 开启时钟 */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
        
        /* TIM2基本配置 */                 
  TIM_TimeBaseStructure.TIM_Period = Speed;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;                                                                                    //设置预分频:不预分频,即为72MHz
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;                                //设置时钟分频系数:不分频
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;                  //向上计数模式

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
        
        /* PWM2模式通道1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;                                                    //配置为PWM模式2
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;                //使能比较输出
  TIM_OCInitStructure.TIM_Pulse = 200;                                                                                                           //设置跳变值,当计数器计数到这个值时,电平发生跳变
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;                          //当定时器计数值小于跳变值时为高电平

  TIM_OC2Init(TIM2, &TIM_OCInitStructure);                                                                                                 //使能通道2
  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(TIM2, ENABLE);                                                                                                                         //使能TIM2重载寄存器ARR
        
        TIM_ClearFlag(TIM2,TIM_FLAG_CC2);                                                                                                                                //清除中断标志
        
        TIM_ITConfig(TIM2,TIM_IT_CC2,ENABLE);                                                                                                         //使能指定的TIM2中断,允许比较输出

  TIM_Cmd(TIM2, DISABLE);                                                                                                                                        //关闭TIM2,在用的时候打开
}[/mw_shl_code]
中断函数:大概写一下,具体按自己要求写
[mw_shl_code=c,true]void TIM2_IRQHandler(void)
{
        if (TIM_GetITStatus(TIM2, TIM_FLAG_CC2) != RESET)         //检查指定的TIM中断发生与否:TIM 中断源
        {
                TIM_ClearITPendingBit(TIM2, TIM_FLAG_CC2);                          //清除TIMx的中断待处理位:TIM 中断源
                if(CW)
                        Rotate_Cnt++;
                if(CCW)
                        Rotate_Cnt--;
        }
}[/mw_shl_code]

方波的输出通道是tim2->ch2,你看看你的片子是多少脚自己改一下
中断配置
[mw_shl_code=c,true]NVIC_InitTypeDef NVIC_InitStructure;

        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                 
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                
        NVIC_Init(&NVIC_InitStructure);                                          [/mw_shl_code]
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-4-26 17:00:01 | 显示全部楼层
为什么做步进电机控制非要用PWM呢, 你又不是做驱动器, 而是做个脉冲线方向线控制, 用个定时器中断就完成了,  而且加减速, 多轴插补都能实现。
回复

使用道具 举报

6

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2016-4-25
在线时间
16 小时
 楼主| 发表于 2016-4-26 17:01:27 | 显示全部楼层
likunxue 发表于 2016-4-26 17:00
为什么做步进电机控制非要用PWM呢, 你又不是做驱动器, 而是做个脉冲线方向线控制, 用个定时器中断就完成 ...

恩,我试试
回复

使用道具 举报

6

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2016-4-25
在线时间
16 小时
 楼主| 发表于 2016-4-26 17:07:31 | 显示全部楼层
likunxue 发表于 2016-4-26 17:00
为什么做步进电机控制非要用PWM呢, 你又不是做驱动器, 而是做个脉冲线方向线控制, 用个定时器中断就完成 ...

使用PWM输出是不是实时性比较高,使能一下就能输出,不用非得通过延时来处理。使能同时可以处理其他的任务。是不是可以这样?
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-4-26 17:41:56 | 显示全部楼层
kaiyuan123 发表于 2016-4-26 17:07
使用PWM输出是不是实时性比较高,使能一下就能输出,不用非得通过延时来处理。使能同时可以处理其他的任 ...

定时中断不是硬件自动完成吗, 起动定时器后, 其它的事情都是硬件自动完成了, 需要的脉冲输出完成后, 定时器自动关闭,
回复

使用道具 举报

21

主题

144

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1132
金钱
1132
注册时间
2015-7-31
在线时间
155 小时
发表于 2016-4-26 19:52:46 | 显示全部楼层
可以实现的办法很多啊,开环的么 ? 如果机械部分非常理想也可以尝试输出比较,然后使能输出比较中断,电机需要跑多少步就是多少次中断,但是这样的弊病就是中断频率太高,也可以尝试让DMA来做,这些我都实验过了
回复

使用道具 举报

6

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2016-4-25
在线时间
16 小时
 楼主| 发表于 2016-4-27 08:42:27 | 显示全部楼层
lx911gt 发表于 2016-4-26 19:52
可以实现的办法很多啊,开环的么 ? 如果机械部分非常理想也可以尝试输出比较,然后使能输出比较中断,电机 ...

开环的,还有其他方法吗,这个我没看明白。。
回复

使用道具 举报

6

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2016-4-25
在线时间
16 小时
 楼主| 发表于 2016-4-27 08:46:51 | 显示全部楼层
likunxue 发表于 2016-4-26 17:41
定时中断不是硬件自动完成吗, 起动定时器后, 其它的事情都是硬件自动完成了, 需要的脉冲输出完成后,  ...

我现在想要实现的是,通过IO口输出比如5个脉冲的PWM波。你说的用定时器中断完成,中断的启动和结束,PWM波的产生,可以用一个定时器完成吗?
回复

使用道具 举报

20

主题

72

帖子

0

精华

初级会员

Rank: 2

积分
182
金钱
182
注册时间
2015-11-11
在线时间
22 小时
发表于 2016-4-27 10:31:50 | 显示全部楼层
可以通过控制其中任何一个通道的输入输出。
回复

使用道具 举报

62

主题

903

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3567
金钱
3567
注册时间
2016-1-8
在线时间
544 小时
发表于 2016-4-27 10:34:55 | 显示全部楼层
定时器中断
回复

使用道具 举报

6

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2016-4-25
在线时间
16 小时
 楼主| 发表于 2016-4-27 10:44:54 | 显示全部楼层

是额外加一个定时器吧?
这个我试了,不过仿真结果总是有一个冲击?
回复

使用道具 举报

6

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2016-4-25
在线时间
16 小时
 楼主| 发表于 2016-4-27 10:45:22 | 显示全部楼层
C:\Users\Administrator\Desktop
回复

使用道具 举报

7

主题

63

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2013-1-23
在线时间
4 小时
发表于 2016-4-27 11:20:24 | 显示全部楼层
lx911gt 发表于 2016-4-26 19:52
可以实现的办法很多啊,开环的么 ? 如果机械部分非常理想也可以尝试输出比较,然后使能输出比较中断,电机 ...

定时器中断在频率比较高的情况下,很影响其他进程的,你说的DMA来做是什么意思
回复

使用道具 举报

21

主题

144

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1132
金钱
1132
注册时间
2015-7-31
在线时间
155 小时
发表于 2016-4-27 11:33:24 | 显示全部楼层
kaiyuan123 发表于 2016-4-27 08:42
开环的,还有其他方法吗,这个我没看明白。。

以TIM3做为时基,然后开启输出比较,使能比较中断,开启定时器就会输出方波,如果频率太高的话有可能会变形,这个先不考虑。使能的中断不要使能定时器更新中断,要使能对应输出通道的中断,比如CC1  CC2什么的,这时候计数器递增到你设定的频率值时会自动清零,并产生一个中断,这个中断是比较来的并不是更新来的,这个中断一产生表明一个方波输出完毕,这个方波给步进电机,步进电机就动一步,如何来记步就在中断里做文章,比如定义一个Cnt,每中断一次Cnt++,在大循环里判断Cnt等于多少,到需要的数量后关闭TIM3,这样就可以控制步进电机走多少步了。
回复

使用道具 举报

21

主题

144

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1132
金钱
1132
注册时间
2015-7-31
在线时间
155 小时
发表于 2016-4-27 11:38:39 | 显示全部楼层
浮生长恨 发表于 2016-4-27 11:20
定时器中断在频率比较高的情况下,很影响其他进程的,你说的DMA来做是什么意思

没错,过于频繁的中断就是作死,我试过4通道的,也是这种方式产生中断,还有一些别的中断,比如CAN,Usart,心跳什么的,虽然没有出现问题,但隐隐觉得还是有巨大的隐患,我试过把中断要做的事让DMA来分担,然后DMA在极限值的时候产生一个中断给CPU表明已经达到极限位置,这种中断只在DMA到达极限时给出,在大循环里判断DMA的剩余值就解决了频繁中断的问题
回复

使用道具 举报

9

主题

507

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3347
金钱
3347
注册时间
2013-4-10
在线时间
333 小时
发表于 2016-4-27 12:56:34 | 显示全部楼层
lx911gt 发表于 2016-4-27 11:38
没错,过于频繁的中断就是作死,我试过4通道的,也是这种方式产生中断,还有一些别的中断,比如CAN,Usar ...

无语
回复

使用道具 举报

21

主题

144

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1132
金钱
1132
注册时间
2015-7-31
在线时间
155 小时
发表于 2016-4-27 13:03:22 | 显示全部楼层

怎么了?????????
回复

使用道具 举报

6

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2016-4-25
在线时间
16 小时
 楼主| 发表于 2016-4-28 11:38:28 | 显示全部楼层
lx911gt 发表于 2016-4-27 11:33
以TIM3做为时基,然后开启输出比较,使能比较中断,开启定时器就会输出方波,如果频率太高的话有可能会变 ...

是用一个定时器吗,怎么设置输出比较的,能不能发个代码
回复

使用道具 举报

6

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
68
金钱
68
注册时间
2016-4-25
在线时间
16 小时
 楼主| 发表于 2016-4-28 15:19:35 | 显示全部楼层
lx911gt 发表于 2016-4-28 11:51
[mw_shl_code=c,true]static void TIM2_Config(void)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBas ...

恩,谢谢了,刚才试了一下实现了,正准备用到程序试试
回复

使用道具 举报

7

主题

63

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2013-1-23
在线时间
4 小时
发表于 2016-5-4 16:06:25 | 显示全部楼层
我有做过用一个定时器监视另一个定时器的实验,监视的定时器运行在比较输入模式,被监视的运行在pwm模式,这样就不用频繁中断了,pwm到达设定值,会进入监视定时器的中断,关闭被监视的定时器就可以了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-9 15:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表