打印

紧急求助:TIM1 与DMA配合问题

[复制链接]
5013|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhongvv|  楼主 | 2011-3-2 18:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
DMA, TI, ST, IO, ni
本帖最后由 zhongvv 于 2011-3-2 18:22 编辑

在移植官方例程的时候,发现当采用例程所用的DMACHN2 TIM2 ,可以输出文档所描述的波形。但如果用TIM1 DMACHN5 却不能够输出波形。而且,定时器好像变慢了,调试时进入DMA中断要等很久。不知道是为什么?希望各位大侠能够帮忙。谢谢!
能够正常运行的设置
中断配置
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQChannel ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

#define   TIM2_ARR_Address    0x4000002C

    定时器与DMA设置
    /* GPIOA Configuration:TIM2 Channel1 in Output */
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   
     GPIO_Init(GPIOA, &GPIO_InitStructure);

      /* TIM2 clock enable */
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
     /* ---------------------------------------------------------------
     TIM2 Configuration: Output Compare Toggle Mode:
     --------------------------------------------------------------- */
      /* Time base configuration */
     TIM_TimeBaseStructure.TIM_Period =60000;
     TIM_TimeBaseStructure.TIM_Prescaler = 2;
     TIM_OCInitStructure.TIM_Pulse = 0;  
     TIM_TimeBaseStructure.TIM_ClockDivision = 0;
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
     TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
   
     /* Output Compare Toggle Mode configuration: Channel1 */
     TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_Toggle;  
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
     TIM_OC1Init(TIM2, &TIM_OCInitStructure);
   
     TIM_ARRPreloadConfig(TIM2, ENABLE);
     
     /* TIM enable counter */
     TIM_Cmd(TIM2, ENABLE);
     
     /* -------------------------------------------------------------------
     DMA1 configuration
     ---------------------------------------------------------------------- */
     
     /* DMA1 channel2 configuration ----------------------------------*/
     DMA_DeInit(DMA1_Channel2);
     DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)TIM2_ARR_Address;
     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SRC_Buffer_INC;
     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
     DMA_InitStructure.DMA_BufferSize = BufferSize;
     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_Normal;
     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
     DMA_Init(DMA1_Channel2, &DMA_InitStructure);
     
     /* Enable DMA1 Channel2 Transfer Complete interrupt */
     DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);
     
     /* Enable DMA1 Channel2 */
     DMA_Cmd(DMA1_Channel2, ENABLE);
     
     /* Enable TIM2 DMA update request */
     TIM_DMACmd(TIM2,TIM_DMA_Update, ENABLE);
中断服务程序
void SysTickHandler(void)
{
               /* Change the DMA_MemoryBaseAddr to the decrement buffer */
  DMA1_Channel2->CMAR = (u32)SRC_Buffer_DEC;
  
  /* Define the DMA_BufferSize */  
  DMA1_Channel2->CNDTR = BufferSize;
  
  /* Enable DMA1 Channel2 */
  DMA1_Channel2->CCR |= ((u32)0x00000001);

  /* Enable TIM2 DMA request */
  TIM2->DIER |= TIM_DMA_Update;
  
  /* Disable SysTick Counter */
  SysTick->CTRL &= 0xFFFFFFFE;
  
  /* Clear SysTick Counter */
  SysTick->VAL = ((u32)0x00000000);
  
  acceleration = SET;

}

void DMA1_Channel2_IRQHandler(void)
{
     
          /* Disable TIM2 DMA */  
           TIM2->DIER &= ~TIM_DMA_Update;
                 
           /* Disable DMA Channel2 request */  
           DMA1_Channel2->CCR &= ((u32)0xFFFFFFFE);
           
           if(acceleration == SET)
           {           
                     /* Change the DMA_MemoryBaseAddr to the decrement buffer */
                     DMA1_Channel2->CMAR =(u32)SRC_Buffer_INC;
               
                     /* Define the DMA_BufferSize */  
                     DMA1_Channel2->CNDTR = BufferSize;
               
                     /* Enable DMA Channel2 */
                     DMA1_Channel2->CCR |= ((u32)0x00000001);
            
                     /* Enable TIM2 DMA request */
                     TIM2->DIER |= TIM_DMA_Update;
                     
                     acceleration = RESET;
           }
           else
           {        
          Systick_Config();
              #if 0
               /* SysTick end of count event each 8ms  */
               /* Setup SysTick Timer for 1 msec interrupts */
               if (SysTick_Config(72000000 / 8000)) /* SystemFrequency is defined in
              “system_stm32f10x.h” and equal to HCLK frequency */
               {
                 /* Capture error */
                  while (1);
               }
               #endif

               
               acceleration = SET;
           }
           /* Clear DMA1 Channel2 Transfer Complete pending bit */
           DMA1->IFCR = DMA1_FLAG_TC2;
         
}






不能够正常运行的相应设置为:
中断服务程序配置
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQChannel ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

#define   TIM1_ARR_Address    TIM1_BASE+0x2c//0x4000002C//
定时器与DMA设置
  //RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
     /* GPIOA Configuration:TIM1 Channel1 in Output */
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOB, &GPIO_InitStructure);
     
#if 0

         /* GPIOA Configuration:TIM1 Channel1 in Output */
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOA, &GPIO_InitStructure);
#endif

     TIM_DeInit(TIM1);
         /* TIM1 clock enable */
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
     /* ---------------------------------------------------------------
     TIM1 Configuration: Output Compare Toggle Mode:
     --------------------------------------------------------------- */
      /* Time base configuration */
     TIM_TimeBaseStructure.TIM_Period =60000;
     TIM_TimeBaseStructure.TIM_Prescaler = 2;
     TIM_TimeBaseStructure.TIM_ClockDivision = 0;
     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

      TIM_OCInitStructure.TIM_Pulse = 0;
     /* Output Compare Toggle Mode configuration: Channel1 */
     TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_Toggle;  
     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
     //TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;

     //TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCNPolarity_Low;
     TIM_OC1Init(TIM1, &TIM_OCInitStructure);
   
     TIM_ARRPreloadConfig(TIM1, ENABLE);
     
     /* TIM1 enable counter */
     TIM_Cmd(TIM1, ENABLE);
     
     /* -------------------------------------------------------------------
     DMA1 configuration
     ---------------------------------------------------------------------- */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
     /* DMA1 channel2 configuration ----------------------------------*/
     DMA_DeInit(DMA1_Channel5);
     DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)TIM1_ARR_Address;
     DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SRC_Buffer_INC;
     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
     DMA_InitStructure.DMA_BufferSize = BufferSize;
     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_Normal;
     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
     DMA_Init(DMA1_Channel5, &DMA_InitStructure);
     
     /* Enable DMA1 Channel5 Transfer Complete interrupt */
     DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
     
     /* Enable DMA1 Channel5 */
     DMA_Cmd(DMA1_Channel5, ENABLE);
     
     /* Enable TIM1 DMA update request */
     TIM_DMACmd(TIM1,TIM_DMA_Update, ENABLE);
   
中断服务程序
void SysTickHandler(void)
{
               /* Change the DMA_MemoryBaseAddr to the decrement buffer */
  DMA1_Channel5->CMAR = (u32)SRC_Buffer_DEC;
  
  /* Define the DMA_BufferSize */  
  DMA1_Channel5->CNDTR = BufferSize;
  
  /* Enable DMA1 Channel5 */
  DMA1_Channel5->CCR |= ((u32)0x00000001);

  /* Enable TIM1 DMA request */
  TIM1->DIER |= TIM_DMA_Update;
  
  /* Disable SysTick Counter */
  SysTick->CTRL &= 0xFFFFFFFE;
  
  /* Clear SysTick Counter */
  SysTick->VAL = ((u32)0x00000000);
  
  acceleration = SET;

}
void DMA1_Channel5_IRQHandler(void)
{
        /* Disable TIM1 DMA */        
                  TIM1->DIER &= ~TIM_DMA_Update;
                        
                  /* Disable DMA Channel5 request */  
                  DMA1_Channel5->CCR &= ((u32)0xFFFFFFFE);
                  
                  if(acceleration == SET)
                  {           
                                /* Change the DMA_MemoryBaseAddr to the decrement buffer */
                                DMA1_Channel5->CMAR =(u32)SRC_Buffer_INC;
                          
                                /* Define the DMA_BufferSize */  
                                DMA1_Channel5->CNDTR = BufferSize;
                          
                                /* Enable DMA Channel2 */
                                DMA1_Channel5->CCR |= ((u32)0x00000001);
                        
                                /* Enable TIM1 DMA request */
                                TIM1->DIER |= TIM_DMA_Update;
                                
                                acceleration = RESET;
                  }
                  else
                  {   
                         Systick_Config();
         #if 0
                         /* SysTick end of count event each 8ms  */
                         /* Setup SysTick Timer for 1 msec interrupts */
                         if (SysTick_Config(72000000 / 8000)) /* SystemFrequency is defined in
                        “system_stm32f10x.h” and equal to HCLK frequency */
                         {
                           /* Capture error */
                                while (1);
                         }
         #endif
        
                        
                         acceleration = SET;
                  }
                  /* Clear DMA1 Channel5 Transfer Complete pending bit */
                  DMA1->IFCR = DMA1_FLAG_TC5;  


}
谢谢了!@

Printer 可以在PA0输出波形.rar

1.92 MB

Printer无法在PB13中输出波形.rar

1.8 MB

沙发
zhongvv|  楼主 | 2011-3-3 16:31 | 只看该作者
本帖最后由 zhongvv 于 2011-3-3 16:46 编辑

原因已经找到了。

TIM2 配置完成后不用配置TIM_CtrlPWMOutputs 可以输出波形,但TIM1 必须配置TIM_CtrlPWMOutputs 才能输出波形。

/*PWM输出使能*/
TIM_CtrlPWMOutputs(TIM1, ENABLE);
这是为什么呢??

由于程序中TIM1使用的CHN1的N通的,因此配置要改成
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;


同时,还必须使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
DMA中断才能正常工作,这又是为什么呢??请大侠们解释一下。
改了一下其他程序,DMA又不能正常工作了。好像慢了很多,要经过多个周期才能够进行一次DMA传输。

使用特权

评论回复
板凳
airwill| | 2011-3-3 21:30 | 只看该作者
呵呵, 没有遇到楼主的问题. 看来以后也得留意一下. 谢谢楼主.

使用特权

评论回复
地板
lkl10800139| | 2012-3-23 09:40 | 只看该作者
这个很关键:TIM2 配置完成后不用配置TIM_CtrlPWMOutputs 可以输出波形,但TIM1 必须配置TIM_CtrlPWMOutputs 才能输出波形。

使用特权

评论回复
5
cgf1981| | 2014-11-11 14:49 | 只看该作者
不错的帖子!很需要

使用特权

评论回复
6
12ycli| | 2015-7-19 09:52 | 只看该作者
用PWM1模式,不要用toggle模式,被坑了两天

使用特权

评论回复
7
木子不二| | 2015-8-14 20:23 | 只看该作者

使用特权

评论回复
8
598330983| | 2015-8-14 22:10 | 只看该作者
搞不懂这俩模式有什么不同啊

使用特权

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

本版积分规则

7

主题

45

帖子

1

粉丝