qwerttt 发表于 2010-4-9 11:46:22

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

参考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_TimeBaseInitTypeDefTIM_TimeBaseStructure;
/*0014*/        TIM_OCInitTypeDefTIM_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*/}

flybird2010 发表于 2010-4-9 21:35:01

关注一下

ouyangqu 发表于 2010-4-21 11:57:07

好奇怪,这个DMA通道的选择跟手册上面并不对应啊,而且AN2820文档里面的例子也不对应。
http://cache.amobbs.com/bbs_upload782111/files_28/ourdev_547954.png
(原文件名:QQ截图未命名3.png)

ouyangqu 发表于 2010-4-21 12:00:05

回复【楼主位】qwerttt
-----------------------------------------------------------------------

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

ouyangqu 发表于 2010-4-21 12:08:48

我也在试,可是还是只能发出不变频率的波形

qwerttt 发表于 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()才正常输出

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

ouyangqu 发表于 2010-4-22 22:10:41

回复【5楼】qwerttt
-----------------------------------------------------------------------

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

qwerttt 发表于 2010-4-23 08:52:48

回复【6楼】ouyangqu
-----------------------------------------------------------------------

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

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

ouyangqu 发表于 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的朋友发的代码,我是没试出来。他说他的步进电机运行很正常,可是我看定时器输出设置都没有,很疑惑。

qwerttt 发表于 2010-4-23 21:37:04

回复【8楼】ouyangqu
-----------------------------------------------------------------------

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

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

nitu 发表于 2014-8-21 09:20:47

好贴,是不是要加这一句。{:lol:}
页: [1]
查看完整版本: 官方AN2820控制步进电机实验,DMA更新TIMx_ARR的问题