SMT32轻松输出带死区的4路PWM

来源:互联网 发布:能效监控中心 大数据 编辑:程序博客网 时间:2024/05/16 09:17

带PWM宽度可调,死区时间可……

比较器输出改变死区时间,定时器的翻转周期改变PWM宽度。

1个通用定时器最多可以做到16路输出,不占用系统资源。

主要原理是使用翻转周期DMA通道改变端口输出状态,比较通道DMA关闭端口输出实现死区调节。


typedef struct

{
    uint32_t volatile Width[4];  //肪宽
    uint32_t DeadZone;             //死区

}Scan_Package;


Scan_Package PWM;


/*******************************
函数功能:定时器比较模式
********************************/
void TIM2_Compare (void)
{
//    NVIC_InitTypeDef NVIC_InitStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    
    TIM_OCStructInit(&TIM_OCInitStructure);
    TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_Timing;
    TIM_OCInitStructure.TIM_Pulse = 17000;                           //翻转周期:1700个脉冲
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;   //使能TIM2_CH3通道
    TIM_OCInitStructure.TIM_OCPolarity  = TIM_OCPolarity_Low;        //输出为负逻辑
    TIM_OC3Init(TIM2, &TIM_OCInitStructure);
    
    TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Disable);       
    TIM_ForcedOC3Config(TIM2,TIM_ForcedAction_InActive);
    
//    TIM_ITConfig(TIM2,TIM_IT_CC3,ENABLE);     //比较中断
//    
//    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
//    /* Enable the TIMER15 Interrupt */
//    NVIC_InitStructure.NVIC_IRQChannel= TIM15_IRQn;
//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;
//    NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;
//    NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
//    NVIC_Init(&NVIC_InitStructure);
}

/*******************************
函数功能:输出端口设置
********************************/
void Port_Out_init (GPIO_TypeDef* GPIOx,uint32_t GPIO_Pin_x)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin     = GPIO_Pin_x;
    GPIO_InitStructure.GPIO_Mode     = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Speed     = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType     = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd     = GPIO_PuPd_UP;
    GPIO_Init(GPIOx , &GPIO_InitStructure);
}


void TIM2_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    TIM_TimeBaseInitTypeDef TIMER_TimeBaseStructure;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    TIM_DeInit(TIM2);
    TIMER_TimeBaseStructure.TIM_Prescaler= 0x05;    //定时最大时间2.5ms
    TIMER_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up;
    TIMER_TimeBaseStructure.TIM_Period= 30000;
    TIMER_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1;
    TIMER_TimeBaseStructure.TIM_RepetitionCounter=0;
    TIM_TimeBaseInit(TIM2,&TIMER_TimeBaseStructure);
    
    Port_Out_init(GPIOA,GPIO_Pin_0);
    Port_Out_init(GPIOA,GPIO_Pin_1);
    Port_Out_init(GPIOA,GPIO_Pin_2);
    Port_Out_init(GPIOA,GPIO_Pin_3);

    /* Auto-reload preload enable */
    TIM_ARRPreloadConfig(TIM2,ENABLE);

    /* Clear the CH1 Interrupt flag an Enable the CH1 Interrupt Request */
    TIM_ClearITPendingBit(TIM2,0xFFFF);

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    /* Enable the TIMER2 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel= TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;//先占优先级2级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;       //从优先级0级
    NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
 
    TIM_ITConfig(TIM2,TIM_IT_Update,DISABLE);//允许更新中断和捕获中断
    NVIC_DisableIRQ(TIM2_IRQn);
 // TIM_ITConfig(TIM2,TIM_IT_CC2,ENABLE);     //捕获中断     

    TIM_Cmd( TIM2, ENABLE );    
}




/*******************************
函数功能:
********************************/

void DMA_DeInit_MITSUBISHI (void)
{
    DMA_InitTypeDef DMA_InitStructure;
    DMA_DeInit(DMA1_Channel1);    //TIM2_CC3
    DMA_DeInit(DMA1_Channel2);    //TIM2_UP

    
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&GPIOA->BSRR;          //外设地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&PWM.Width[0];                //内存地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                             //dma传输方向单向  内存到外设
    DMA_InitStructure.DMA_BufferSize = 4;                                         //设置DMA在传输时缓冲区的长度          
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            //设置DMA的外设递增模式,一个外设           
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                    //设置DMA的内存递增模式   
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;     //外设数据字长     
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;             //内存数据字长    
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                              //设置DMA的传输模式    
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;                     //设置DMA的优先级别         
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                //设置DMA的2个memory中的变量互相访问  
    DMA_Init(DMA1_Channel2,&DMA_InitStructure);
    TIM_DMACmd(TIM2,TIM_DMA_Update,ENABLE);    
    
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&GPIOA->BSRR;          //外设地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&PWM.DeadZone;                //内存地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                             //dma传输方向单向  内存到外设
    DMA_InitStructure.DMA_BufferSize = 1;                                         //设置DMA在传输时缓冲区的长度          
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            //设置DMA的外设递增模式,一个外设           
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;                    //设置DMA的内存递增模式   
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;     //外设数据字长     
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;             //内存数据字长    
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                              //设置DMA的传输模式    
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;                     //设置DMA的优先级别         
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                //设置DMA的2个memory中的变量互相访问  
    DMA_Init(DMA1_Channel1,&DMA_InitStructure);
    TIM_DMACmd(TIM2,TIM_DMA_CC3,ENABLE);

    DMA_Cmd(DMA1_Channel1,ENABLE);
    DMA_Cmd(DMA1_Channel2,ENABLE);    
//    DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);    //通道中断使能
//    DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE);
//    DMA_ITConfig(DMA1_Channel3,DMA_IT_TC,ENABLE);
//    DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);
    
//    NVIC_EnableIRQ(DMA1_Channel4_5_IRQn);
//    NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);     
//    NVIC_EnableIRQ(DMA1_Channel1_IRQn);
        
}

void TIM2_APP_Config(void)
{
    TIM2_Config();
    DMA_DeInit_MITSUBISHI();
    TIM2_Compare();
}

原创粉丝点击