搜索
bottom↓
回复: 0

请教STM32 TIM的不同通道输出数量不同的PWM波的方法 DMA方式

[复制链接]

出0入0汤圆

发表于 2019-6-23 09:38:05 | 显示全部楼层 |阅读模式

问题,如何使同一个定时器(TIM2)的2个通道TIM2_CCR3(DMA1_Channel1)  TIM2_CCR4(DMA1_Channel7) 输出频率相同,数量不同的PWM波 ?

通道3 输出PWM数量为 num_ch3, 通道4 输出PWM数量为 num_ch4, 这两个通道的启动和停止没有任何关系   每个通道传输结束后在DMA通道的中断中 关闭


下面的代码 不能实现这个功能, DMA启动之后,PWM就停不了,会一直输出
请大神指出下面的错误 或者给出可以实现这个功能的代码例子

谢谢 !!!



RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);       
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);        
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);
               
GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;  
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);       

       
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
         
TIM_TimeBaseStructure.TIM_Period = arr ; //999 时; 当定时器从0计数到999,即为1000次,为一个定时周期
TIM_TimeBaseStructure.TIM_Prescaler = psc;            //设置预分频:不预分频,即为72MHz
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;        //设置时钟分频系数:不分频(这里用不到)
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;            //配置为PWM模式1


  /* PWM1 Mode configuration: Channel3 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能
  TIM_OCInitStructure.TIM_Pulse =0 ;  // PWM_Buffer[0];        //设置通道3的电平跳变值,设置待装入捕获比较寄存器的脉冲值
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;        
  TIM_OC3Init(TIM2, &TIM_OCInitStructure);         //使能通道3
  TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel4 *///比较输出使能
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse =0;  // PWM_Buffer[0];        //设置通道4的电平跳变值,设置待装入捕获比较寄存器的脉冲值
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OC4Init(TIM2, &TIM_OCInitStructure);        //使能通道4
  TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
       
  TIM_ARRPreloadConfig(TIM2, ENABLE);                         // 使能TIM3重载寄存器ARR


RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
       
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DMA_Cmd(DMA1_Channel1, DISABLE);                                        // 关DMA通道       
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM2_CCR3_Address;        // physical address of Timer 3 CCR1
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)PWM_Buffer;                // this is the buffer memory
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                                                // data shifted from memory to peripheral
DMA_InitStructure.DMA_BufferSize = 8;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        // automatically increase buffer index
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_Channel1, &DMA_InitStructure);
       
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
/* Enable the DMA Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;        // 发送DMA通道的中断配置
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2 ;      // 优先级设置
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);       
       
DMA_ClearFlag(DMA1_FLAG_GL1);                                           // 清除DMA所有标志
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);                         // 开启发送DMA通道中断       
DMA_Cmd(DMA1_Channel1, DISABLE);                
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DMA_Cmd(DMA1_Channel7, DISABLE);                                        // 关DMA通道       
DMA_DeInit(DMA1_Channel7);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM2_CCR4_Address;        // physical address of Timer 3 CCR1
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)PWM_Buffer;                // this is the buffer memory
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                                                // data shifted from memory to peripheral
DMA_InitStructure.DMA_BufferSize = 8;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                                        // automatically increase buffer index
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                                                        // stop DMA feed after buffer size is reached       

       
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;       
DMA_Init(DMA1_Channel7, &DMA_InitStructure);
       
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
/* Enable the DMA Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;        // 发送DMA通道的中断配置
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1 ;      // 优先级设置
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);       

DMA_ClearFlag(DMA1_FLAG_GL7);                                           // 清除DMA所有标志
DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);                         // 开启发送DMA通道中断       
DMA_Cmd(DMA1_Channel7, DISABLE);        
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////       
       
TIM_DMACmd(TIM2, TIM_DMA_CC3, ENABLE);                       
TIM_DMACmd(TIM2, TIM_DMA_CC4, ENABLE);       
       
TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);
TIM_Cmd(TIM2, DISABLE);                 
}


void DMA1_Channel7_IRQHandler(void)  //PWM 4
{
    if(DMA_GetITStatus(DMA1_FLAG_TC7))
    {
                                DMA_ClearFlag(DMA1_FLAG_GL7);         // 清除标志
                       
        TIM_ARRPreloadConfig(TIM2, DISABLE);                               
        TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable);               
                       
        DMA_Cmd(DMA1_Channel7, DISABLE);      // 关闭DMA通道                               
    }
}

void DMA1_Channel1_IRQHandler(void)  //PWM 4
{
    if(DMA_GetITStatus(DMA1_FLAG_TC1))
    {
        DMA_ClearFlag(DMA1_FLAG_GL1);         // 清除标志
                       
        TIM_ARRPreloadConfig(TIM2, DISABLE);                         //
          TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);                       
                               
        DMA_Cmd(DMA1_Channel1, DISABLE);      // 关闭DMA通道                       
    }
}


开起通道3传输 波形数量为num_ch3
    DMA_SetCurrDataCounter(DMA1_Channel7, num_ch3);         // load number of bytes to be transferred                       
    TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);                  
    TIM_Cmd(TIM2, ENABLE);                   //使能定时器3       
    DMA_Cmd(DMA1_Channel7, ENABLE);                                
         
开起通道4传输 波形数量为num_ch4
    DMA_SetCurrDataCounter(DMA1_Channel1, num_ch4);         // load number of bytes to be transferred                       
    TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);                         
    TIM_Cmd(TIM2, ENABLE);                   //使能定时器3       
    DMA_Cmd(DMA1_Channel1, ENABLE);                        


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

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-25 00:53

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

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