搜索
bottom↓
回复: 10

官方AN2820控制步进电机实验,DMA更新TIMx_ARR的问题

[复制链接]

出0入0汤圆

发表于 2010-4-9 11:46:22 | 显示全部楼层 |阅读模式
参考AN2820文档
分别使用TIM4_CH4与DMA_CHANNEL7
        TIM3_CH4与DMA_CHANNEL3
        TIM2_CH4与DMA_CHANNEL2
以上3种TIMx工作在TIM_OCMode_Toggle方式,都能正确输出可变的频率

但是用TIM1_CH1与DMA_CHANNEL5时,就不行了,没有波形输出,但能进DMA_CHANNEL5的中断
代码:

/*0001*/  u16 SRC_Buffer_INC[20] ={60000,60000,55000,55000,50000,50000,45000,45000,40000,40000,
/*0002*/                           35000,35000,30000,30000,25000,25000,20000,20000,15000,15000};
/*0003*/  
/*0004*/  void Init_RCC()
/*0005*/  {
/*0006*/                  ...................
/*0007*/                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/*0008*/  }
/*0009*/  
/*0010*/  void DMA_TIM_OCToggle()
/*0011*/  {
/*0012*/          GPIO_InitTypeDef GPIO_InitStructure;
/*0013*/          TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
/*0014*/          TIM_OCInitTypeDef  TIM_OCInitStructure;
/*0015*/          DMA_InitTypeDef DMA_InitStructure;
/*0016*/         
/*0017*/          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
/*0018*/          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
/*0019*/          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
/*0020*/          GPIO_Init(GPIOA, &GPIO_InitStructure);
/*0021*/         
/*0022*/          TIM_TimeBaseStructure.TIM_Period           = 60000;
/*0023*/          TIM_TimeBaseStructure.TIM_Prescaler       = 2;
/*0024*/          TIM_TimeBaseStructure.TIM_ClockDivision  = 0;
/*0025*/          TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
/*0026*/          TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/*0027*/         
/*0028*/          TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
/*0029*/          TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
/*0030*/          TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
/*0031*/          TIM_OCInitStructure.TIM_Pulse = 0;
/*0032*/          TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/*0033*/         
/*0034*/          TIM_ARRPreloadConfig(TIM1, ENABLE);
/*0035*/         
/*0036*/          TIM_Cmd(TIM1, ENABLE);
/*0037*/         
/*0038*/          DMA_DeInit(DMA1_Channel5);
/*0039*/          DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40012C2C;
/*0040*/          DMA_InitStructure.DMA_MemoryBaseAddr     = (u32)SRC_Buffer_INC;
/*0041*/          DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;
/*0042*/          DMA_InitStructure.DMA_BufferSize         = BufferSize;
/*0043*/          DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
/*0044*/          DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
/*0045*/          DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
/*0046*/          DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
/*0047*/          DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;
/*0048*/            DMA_InitStructure.DMA_Priority           = DMA_Priority_High;
/*0049*/            DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;
/*0050*/            DMA_Init(DMA1_Channel5, &DMA_InitStructure);
/*0051*/           
/*0052*/            DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
/*0053*/           
/*0054*/            DMA_Cmd(DMA1_Channel5, ENABLE);
/*0055*/           
/*0056*/            TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
/*0057*/  }
/*0058*/  
/*0059*/  void DMA1_Channel5_IRQHandler(void)
/*0060*/  {
/*0061*/          TIM1->DIER &= ~TIM_DMA_Update;
/*0062*/         
/*0063*/          DMA1_Channel5->CCR &= ((u32)0xFFFFFFFE);  // 通道禁用
/*0064*/         
/*0065*/          if(acceleration == SET)
/*0066*/          {
/*0067*/                  DMA1_Channel5->CMAR  = (u32)SRC_Buffer_INC;
/*0068*/                  DMA1_Channel5->CNDTR = 20;
/*0069*/                  DMA1_Channel5->CCR  |= ((u32)0x00000001);  // 通道使能
/*0070*/                  TIM1->DIER |= TIM_DMA_Update;
/*0071*/                  acceleration = SET;
/*0072*/          }
/*0073*/          else
/*0074*/          {
/*0075*/                  //if(SysTick_Config(SystemFrequency / 8000))
/*0076*/                  //{
/*0077*/                  //        while(1);
/*0078*/          //        }
/*0079*/                  acceleration = SET;
/*0080*/          }
/*0081*/          DMA1->IFCR = DMA1_FLAG_TC5;  // 清中断标志
/*0082*/         
/*0083*/          GPIO_WriteBit(GPIOB, GPIO_Pin_5, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5)));
/*0084*/  }

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2010-4-9 21:35:01 | 显示全部楼层
关注一下

出0入0汤圆

发表于 2010-4-21 11:57:07 | 显示全部楼层
好奇怪,这个DMA通道的选择跟手册上面并不对应啊,而且AN2820文档里面的例子也不对应。

(原文件名:QQ截图未命名3.png)

出0入0汤圆

发表于 2010-4-21 12:00:05 | 显示全部楼层
回复【楼主位】qwerttt
-----------------------------------------------------------------------

请问楼主这个问题的进展怎样啊?

出0入0汤圆

发表于 2010-4-21 12:08:48 | 显示全部楼层
我也在试,可是还是只能发出不变频率的波形

出0入0汤圆

 楼主| 发表于 2010-4-21 14:47:11 | 显示全部楼层
回复【4楼】ouyangqu
-----------------------------------------------------------------------

TIM要与DMA关联,刚开始看手册是以为是对上
而且AN2820也是对上的
后来才注意TIMx要与DMA通道关联,一定要是TIMx_UP对应的DMA通道
所以我做了TIM4_CH4与DMA_CHANNEL7
          TIM3_CH4与DMA_CHANNEL3
          TIM2_CH4与DMA_CHANNEL2 这3个实验,换其他DMA通道不行
在用TIM1时,要加上TIM_CtrlPWMOutput()才正常输出

可以输出变化的频率,应该是你程序问题

出0入0汤圆

发表于 2010-4-22 22:10:41 | 显示全部楼层
回复【5楼】qwerttt
-----------------------------------------------------------------------

果真是,现在可以输出可变频率了。多谢指点!
不过虽然示波器可以看到预期的波形,可是电机还是没法正常运转,不停地来回抖加间歇性的转动。我把SRC_Buffer数组拉长十倍和100倍,还是不行,也不知道是不是电机本身的问题。

出0入0汤圆

 楼主| 发表于 2010-4-23 08:52:48 | 显示全部楼层
回复【6楼】ouyangqu
-----------------------------------------------------------------------

这个跟SRC_Buffer数组长度没关系,AN2820里面是加减速的
如果电机驱动没问题,应该跟你的脉冲频率大小,加速度大小有关系
先让电机固定频率正常转了

注意的是要等Buffer数组执行完了,才再一次启动DMA
用DMA效率比较高,在控制电机上我觉得比较耗RAM,要发1000个脉冲就得要2000的数组空间

出0入0汤圆

发表于 2010-4-23 17:03:39 | 显示全部楼层
回复【7楼】qwerttt
-----------------------------------------------------------------------

固定频率的可以正常转。我是把SRC_Buffer数组首尾不变,拉长十倍和100倍,这样不就相当于加速度降低十倍和100倍吗?
从理论上计算的话,例子里面的加速过程需要大约0.05s,0.05s就加速四倍是不是也太快了一点。

确实,我把1802的数组弄进去也觉得比较吓人,编译都变慢了。现在也在试其他方法。

对了,不知qwerttt兄有没有试过http://group.ednchina.com/619/25416.aspx?page=3那位代号544852010的朋友发的代码,我是没试出来。他说他的步进电机运行很正常,可是我看定时器输出设置都没有,很疑惑。

出0入0汤圆

 楼主| 发表于 2010-4-23 21:37:04 | 显示全部楼层
回复【8楼】ouyangqu
-----------------------------------------------------------------------

现在我做的自动控制系统,其中用到了步进电机,控制步进电机相对还是容易些
估计你需要时间慢慢研究TIM

结贴
需要帮助话加我QQ 5 6 1 1 1 4 5 8

出0入0汤圆

发表于 2014-8-21 09:20:47 | 显示全部楼层
好贴,是不是要加这一句。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 01:17

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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