OpenEdv-开源电子网

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

STM32高级定时器控制电机,TIM1_CH1N和TIM1_CH1可以同时输出高(已解决)

[复制链接]

57

主题

431

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
886
金钱
886
注册时间
2011-12-25
在线时间
12 小时
发表于 2014-2-18 19:28:16 | 显示全部楼层 |阅读模式

高级定时器控制电机,我使用互补PWM输出,,但是项目一种情况要同时输出高或低电平,才可以使得电机不因为惯性而立刻停。。

下面是配置的代码。。停止时TIM_SetCompare1(TIM1,1800); 就可以停。但是不是立刻停,因为惯性吧
void MotorTIM1_INIT(void)
{   
          TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
          TIM_OCInitTypeDef  TIM_OCInitStructure;
          TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
                     
          /* TIM1, GPIOA, GPIOB, GPIOE and AFIO clocks enable */
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);
        
          /* GPIO Configuration */
          GPIO_Configuration();
          TIM_DeInit(TIM1);
        
          /* Time Base configuration */
          TIM_TimeBaseStructure.TIM_Period = 3600-1;    //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         80K    
          TIM_TimeBaseStructure.TIM_Prescaler = 0;         //设置用来作为TIMx时钟频率除数的预分频值  不分频
          TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式  /* 向上计数模式 */
          TIM_TimeBaseStructure.TIM_ClockDivision = 0;        //设置时钟分割:TDTS = Tck_tim
          TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;        //设置 周期 计数值
        
          TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
          
        
          /* Channel 1, 2,3 and 4 Configuration in PWM mode */
          TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;           //选择定时器模式:TIM脉冲宽度调制模式2
          TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;         //使能输出比较状态
          TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //使能  互补 输出状态
          TIM_OCInitStructure.TIM_Pulse = 1800;                //设置待装入捕获比较寄存器的脉冲值         占空时间 
          TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;       //输出极性:TIM输出比较极性低
          TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;     //互补 输出极性高
          TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;     //MOE=0 设置 TIM1输出比较空闲状态
          TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;  //MOE=0 重置 TIM1输出比较空闲状态
          TIM_OC1Init(TIM1, &TIM_OCInitStructure);        //设定好的参数 初始化TIM  
          TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
          //设置刹车特性  死区时间  锁电平 OSSI OSSR 状态 AOE(自动输出使能)
          /* Automatic Output enable, Break, dead time and lock configuration*/
          TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;  //设置在运行模式下 非工作状态选项 OSSR
          TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;  //设置在运行模式下 非工作状态选项 OSSI
          TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;  //使用锁电平1
          TIM_BDTRInitStructure.TIM_DeadTime = 0x7F;                //指定了输出和打开 关闭状态之间的延时  13.89nsX127=1.7us 
          /* UTG[7:0]: 死区发生器设置(Dead-time generator setup)  位7:0
                这些位定义了插入互补输出之间的死区持续时间。假设DT表示其持续时间:
                DTG[7:5]=0xx => DT=DTG[7:0] ×Tdtg,Tdtg = TDTS;
                DTG[7:5]=10x => DT=(64+DTG[5:0]) ×Tdtg,Tdtg = 2 ×TDTS;
                DTG[7:5]=110 => DT=(32+DTG[4:0]) ×Tdtg,Tdtg = 8 ×TDTS;
                DTG[7:5]=111 => DT=(32+DTG[4:0])×Tdtg,Tdtg = 16 ×TDTS;
                例:若TDTS = 125ns(8MHZ),可能的死区时间为:
                0到15875ns,若步长时间为125ns;
                16us到31750ns,若步长时间为250ns;
                32us到63us,若步长时间为1us;
                64us到126us,若步长时间为2us;
                注:一旦LOCK级别(TIMx_BDTR寄存器中的LOCK位)设为1、2或3,则不能修改这些位。
          */
          TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;  //使能刹车 
          TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;         //刹车输入管脚 极性高
          TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;//自动输出功能使能
        
          TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);        //初始化设定好的参数
          TIM_ARRPreloadConfig(TIM1,ENABLE);        
          /* TIM1 counter enable */
          TIM_Cmd(TIM1, DISABLE);
          /* Main Output Enable */
          TIM_CtrlPWMOutputs(TIM1, DISABLE);
          
          Motor_Stop();
}

很喜爱电子行业
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

57

主题

431

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
886
金钱
886
注册时间
2011-12-25
在线时间
12 小时
 楼主| 发表于 2014-2-18 19:34:31 | 显示全部楼层
望各位玩过高级定时器,教导一下。。谢谢!
很喜爱电子行业
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-2-18 20:23:09 | 显示全部楼层
回复【2楼】冰是睡着的水:
---------------------------------
这,可以把1个IO分成2个用么?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

57

主题

431

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
886
金钱
886
注册时间
2011-12-25
在线时间
12 小时
 楼主| 发表于 2014-2-18 20:25:32 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
设置IO的时候,我也要用到PWM....难道IO口弄过PWM,有点烦。。。。我觉得定时器很强大,自己没有吃透。。。个人觉得还是行,还是看手册吧
很喜爱电子行业
回复 支持 反对

使用道具 举报

57

主题

431

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
886
金钱
886
注册时间
2011-12-25
在线时间
12 小时
 楼主| 发表于 2014-2-18 22:10:52 | 显示全部楼层


设置这几个寄存器!!手册很详细

很喜爱电子行业
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-2-18 23:51:08 | 显示全部楼层
回复【5楼】冰是睡着的水:
---------------------------------
搞定了?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

57

主题

431

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
886
金钱
886
注册时间
2011-12-25
在线时间
12 小时
 楼主| 发表于 2014-2-18 23:58:38 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
改掉CC1P...就行。。
很喜爱电子行业
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-2-19 00:04:44 | 显示全部楼层
恩,学习。
回复 支持 反对

使用道具 举报

57

主题

431

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
886
金钱
886
注册时间
2011-12-25
在线时间
12 小时
 楼主| 发表于 2014-2-19 00:06:25 | 显示全部楼层
回复【8楼】正点原子:
---------------------------------
现在运行一段时间,不知道这样改,会不会对管子有影响。。。
会不会烧。。。
很喜爱电子行业
回复 支持 反对

使用道具 举报

57

主题

431

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
886
金钱
886
注册时间
2011-12-25
在线时间
12 小时
 楼主| 发表于 2014-2-19 00:07:28 | 显示全部楼层





很喜爱电子行业
回复 支持 反对

使用道具 举报

0

主题

9

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2014-2-9
在线时间
0 小时
发表于 2014-2-19 16:09:58 | 显示全部楼层
学习了,对我很有用,我刚买miniSTM32板子想做的第一个项目就是电机控制的,希望以后能有交流!谢谢!
回复 支持 反对

使用道具 举报

77

主题

198

帖子

0

精华

高级会员

Rank: 4

积分
526
金钱
526
注册时间
2013-11-25
在线时间
0 小时
发表于 2014-3-21 09:09:37 | 显示全部楼层
回复【7楼】冰是睡着的水:
---------------------------------
楼主你好,我把你上面的程序复制到keil中,在其基础上改动程序为TIM1输出6路PWM的程序,但是没有成功。。
请问你具体改掉的是那条语句呢?谢谢!
回复 支持 反对

使用道具 举报

5

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2015-9-5
在线时间
9 小时
发表于 2016-3-8 16:00:12 | 显示全部楼层
冰是睡着的水 发表于 2014-2-18 19:34
望各位玩过高级定时器,教导一下。。谢谢!

输出比较空闲状态是什么意思
回复 支持 反对

使用道具 举报

2

主题

47

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
291
金钱
291
注册时间
2016-6-18
在线时间
40 小时
发表于 2016-8-2 13:57:03 | 显示全部楼层
楼主,你好,你可以给我一些关于寄存器版本的STM32 TI1 PWM 控制电机的学习资料??看了你发的,感觉很好。。。
回复 支持 反对

使用道具 举报

42

主题

141

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
342
金钱
342
注册时间
2015-5-26
在线时间
49 小时
发表于 2016-8-16 02:30:15 | 显示全部楼层
MARK一下,谢谢
回复 支持 反对

使用道具 举报

6

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
293
金钱
293
注册时间
2016-1-7
在线时间
54 小时
发表于 2018-3-29 17:06:19 | 显示全部楼层
大神请教一下,我现在做电机跑20分钟左右后就会有3°左右的丢步。请教一下。目前我的做法如下:
1.用定时器PWM输出脉冲。
2.加减速用滴答定时器扫描,1MS进行一次加减速变化,到时间时进行实时计算并赋值给ARR、PSC、CCR1。
3.定时器中断部分如下:
if(TIM_GetITStatus(TIM_MotorY,TIM_IT_Update)!=RESET)          
        {
                TIM_ClearITPendingBit(TIM_MotorY,TIM_IT_Update);
                Motor_OUT[m_y].pulse_move_cnt++;//当前这次运行的脉冲个数累加,用于加减速变频
                if(Motor_OUT[m_y].dir == 0)Motor_OUT[m_y].pulse_current_cnt++;//实际位移
                else Motor_OUT[m_y].pulse_current_cnt-- ;
                //脉冲发完或者触发暂停进行停止
                if( ((Motor_OUT[m_y].pulse_move_cnt == Motor_OUT[m_y].run_pulse_cnt) &&
                        (Motor_OUT[m_y].pulse_move_cnt!=0) ) || (Motor_OUT[m_y].pause_status == _enable_)) {
                        //关定时器
                        TIM_MotorY->CR1 &= ~0x01;                               
                        //用于暂停时,记录还剩脉冲个数;
                        if( Motor_OUT[m_y].pause_status == _enable_){
                                Motor_OUT[m_y].run_pulse_cnt = Motor_OUT[m_y].run_pulse_cnt -
                                                                                           Motor_OUT[m_y].pulse_move_cnt;
                        }
                        Motor_OUT[m_y].pulse_move_cnt=0;
                }                       
        }
监控过脉冲数,走的和测量的是一样的。
帮忙推测下是什么问题。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-8 14:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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