|
问题,如何使同一个定时器(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来反美的!
|