打印

请香主帮忙解答DMA同时更新TIM1_CCR1和TIM1_CCR2寄存器的问题

[复制链接]
6159|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jw_andy|  楼主 | 2010-12-21 15:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我想用TIM1的Update DMA同时更新TIM1_CCR1和TIM1_CCR2寄存器,但只有TIM1_CCR1被更新,而TIM1_CCR2的值不变,请香主帮忙说明如何才能实现同时更新
CCR1和CCR2,谢谢!

设置如下:

#define TIM1_CCR1_Address    0x40012C34
#define Max_Samples  30  //定义最大数组值
uint32_t  Sin_Table[Max_Samples];
void DMA_Configuration(void)
{
  DMA_InitTypeDef DMA_InitStructure;
  /* DMA1 Channel5 Config */
  DMA_DeInit(DMA1_Channel5);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR1_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Sin_Table[0];// SRC1_Buffer;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize =30;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority =DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel5, &DMA_InitStructure);
  DMA_Cmd(DMA1_Channel5, ENABLE);
}
int main(void)
{
int  i;
unsigned int dwVal;

for( i=0;i<30;i++)
{
  dwVal = i*10;
  Sin_Table[i]= ((dwVal<<16)|(600-dwVal));
}
  
  RCC_Configuration();
  GPIO_Configuration();
  DMA_Configuration();
  TIM_TimeBaseStructure.TIM_Prescaler =0;
  TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_CenterAligned2;
  TIM_TimeBaseStructure.TIM_Period = 600;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_RepetitionCounter =1;// 0;
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OutputNState =TIM_OutputNState_Enable;
  TIM_OCInitStructure.TIM_Pulse = (unsigned short)(Sin_Table[0]);
  TIM_OCInitStructure.TIM_OCPolarity =  TIM_OCPolarity_High;
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
  TIM_OCInitStructure.TIM_Pulse = (unsigned short)(Sin_Table[0]>>16);
  TIM_OC2Init(TIM1, &TIM_OCInitStructure);
  //设置 Burst 模式,分别传输一个HalfWord给TIM1_CCR1和TIM1_CCR2
  TIM_DMAConfig(TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_2Bytes );  
  
  TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
  TIM_OC1FastConfig(TIM1, TIM_OCFast_Enable );
  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
  TIM_OC2FastConfig(TIM1, TIM_OCFast_Enable );
  TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
  TIM_ARRPreloadConfig(TIM1, ENABLE);//ARR预装载缓冲器
  TIM_Cmd(TIM1, ENABLE);
  TIM_CtrlPWMOutputs(TIM1, ENABLE);
  while (1) ;
}
沙发
香水城| | 2010-12-21 17:42 | 只看该作者
你在哪里配置了更新TIM1_CCR2?

使用特权

评论回复
板凳
jw_andy|  楼主 | 2010-12-21 17:50 | 只看该作者
TIM_OCInitStructure.TIM_Pulse = (unsigned short)(Sin_Table[0]>>16);
  TIM_OC2Init(TIM1, &TIM_OCInitStructure);
  //设置 Burst 模式,分别传输一个HalfWord给TIM1_CCR1和TIM1_CCR2
  TIM_DMAConfig(TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_2Bytes );

使用特权

评论回复
地板
jw_andy|  楼主 | 2010-12-21 17:51 | 只看该作者
请问如何更新TIM1_CCR2呢?

使用特权

评论回复
5
airwill| | 2010-12-22 08:47 | 只看该作者
TIM_DMAConfig(TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_2Bytes );

这一行, 就是说 TIM_CCR1 的地址, 更新长度为 2 个字. 不过这个功能, 我也发现问题了.

有的时候只能更新一个字, 后来我在程序中毫不相干的其他地方修改了, 重新编译, 发现莫名其妙地问题又解决了, 纳闷呢

使用特权

评论回复
6
jw_andy|  楼主 | 2010-12-22 09:31 | 只看该作者
我这里怎么样改,TIM_CCR2的寄存器都不变,请香主帮忙看看原因吧

使用特权

评论回复
7
lut1lut| | 2010-12-22 10:15 | 只看该作者
本帖最后由 lut1lut 于 2010-12-22 10:34 编辑

看了一下LZ的代码,你的目的是:

有一个30个元素组成的数组Sin_Table,数组每个元素是32位的。低16位存储的是以后更新TIM1_CCR1的值;高16位存储的是以后更新TIM1_CCR2的值。

在每次TIM1的update event,触发DMA传输,这个DMA是把数组每个元素的,低/高各16位数据分别传给TIM1_CCR1/CCR2。

首先,DMA的外设地址寄存器设置错了,应该是TIM1_DMAR_Address

其次,DMA的初始化结构中的BufferSize设置,这里是30,你改成30*2=60。

另外,最好你还是按照u16来定义Sin_Table[30*2];否则在大端/小端的不同平台上,可能CCR1被更新成了高16位;CCR2又被更新成了低16位。

使用特权

评论回复
8
jw_andy|  楼主 | 2010-12-22 10:45 | 只看该作者
谢谢7楼的建议,昨天我都试了一天,程序启动后, 在任意点中断程序,TIM1_CCR1是改变的,TIM1_CCR2的值是不变的,一直停留在初始值,用示波器观察,第一通道脉宽是变化的,第二通道脉宽是固定不变的,这个还是DMA的设置不对造成的,但我对STM32的设置不是很熟,请帮忙看看是什么原因,另外30个元素的数组定义我是专门为了其它模块计算方便而设计的,不过以后看情况再考虑这点。

使用特权

评论回复
9
香水城| | 2010-12-22 10:54 | 只看该作者
谢谢7楼的建议,昨天我都试了一天,程序启动后, 在任意点中断程序,TIM1_CCR1是改变的,TIM1_CCR2的值是不变的,一直停留在初始值,用示波器观察,第一通道脉宽是变化的,第二通道脉宽是固定不变的,这个还是DMA的 ...
jw_andy 发表于 2010-12-22 10:45


哈哈,如果你昨天试了一天,但不是按照7楼建议的那样做,肯定是有问题的。

如果想进一步地了解7楼建议的背景,我建议你看看TIM1的TIMx_DCR和TIMx_DMAR寄存器的说明。5楼指出的那一行语句实际操作的是TIM1_DCR寄存器。

使用特权

评论回复
10
jw_andy|  楼主 | 2010-12-22 11:14 | 只看该作者
#define TIM1_DMAR_Address    0x40012C4C
把这行
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR1_Address;
改成
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_DMAR_Address;
哈哈,SPWM波形出来了,太高兴了,谢谢7楼的帮助

使用特权

评论回复
11
airwill| | 2010-12-23 20:36 | 只看该作者
首先恭喜楼主, 不过我遇到的问题还在后头呢, 继续关注楼主的进展

使用特权

评论回复
12
jw_andy|  楼主 | 2011-1-12 16:36 | 只看该作者
当把这句 TIM_TimeBaseStructure.TIM_Period = 600;改为 TIM_TimeBaseStructure.TIM_Period = 1600;时,只传了一半的数据即15个就不传了,如果是600就可以传30个,请问还有其它方面的设置影响到传输的数目吗?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

47

帖子

1

粉丝