官方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*/} 关注一下 好奇怪,这个DMA通道的选择跟手册上面并不对应啊,而且AN2820文档里面的例子也不对应。
http://cache.amobbs.com/bbs_upload782111/files_28/ourdev_547954.png
(原文件名:QQ截图未命名3.png) 回复【楼主位】qwerttt
-----------------------------------------------------------------------
请问楼主这个问题的进展怎样啊? 我也在试,可是还是只能发出不变频率的波形 回复【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()才正常输出
可以输出变化的频率,应该是你程序问题 回复【5楼】qwerttt
-----------------------------------------------------------------------
果真是,现在可以输出可变频率了。多谢指点!
不过虽然示波器可以看到预期的波形,可是电机还是没法正常运转,不停地来回抖加间歇性的转动。我把SRC_Buffer数组拉长十倍和100倍,还是不行,也不知道是不是电机本身的问题。 回复【6楼】ouyangqu
-----------------------------------------------------------------------
这个跟SRC_Buffer数组长度没关系,AN2820里面是加减速的
如果电机驱动没问题,应该跟你的脉冲频率大小,加速度大小有关系
先让电机固定频率正常转了
注意的是要等Buffer数组执行完了,才再一次启动DMA
用DMA效率比较高,在控制电机上我觉得比较耗RAM,要发1000个脉冲就得要2000的数组空间 回复【7楼】qwerttt
-----------------------------------------------------------------------
固定频率的可以正常转。我是把SRC_Buffer数组首尾不变,拉长十倍和100倍,这样不就相当于加速度降低十倍和100倍吗?
从理论上计算的话,例子里面的加速过程需要大约0.05s,0.05s就加速四倍是不是也太快了一点。
确实,我把1802的数组弄进去也觉得比较吓人,编译都变慢了。现在也在试其他方法。
对了,不知qwerttt兄有没有试过http://group.ednchina.com/619/25416.aspx?page=3那位代号544852010的朋友发的代码,我是没试出来。他说他的步进电机运行很正常,可是我看定时器输出设置都没有,很疑惑。 回复【8楼】ouyangqu
-----------------------------------------------------------------------
现在我做的自动控制系统,其中用到了步进电机,控制步进电机相对还是容易些
估计你需要时间慢慢研究TIM
结贴
需要帮助话加我QQ 5 6 1 1 1 4 5 8 好贴,是不是要加这一句。{:lol:}
页:
[1]