天天看點

SMT32輕松輸出帶死區的4路PWM

帶PWM寬度可調,死區時間可……

比較器輸出改變死區時間,定時器的翻轉周期改變PWM寬度。

1個通用定時器最多可以做到16路輸出,不占用系統資源。

主要原理是使用翻轉周期DMA通道改變端口輸出狀态,比較通道DMA關閉端口輸出實作死區調節。

SMT32輕松輸出帶死區的4路PWM

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);

//   

//    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);

    TIM_ARRPreloadConfig(TIM2,ENABLE);

    TIM_ClearITPendingBit(TIM2,0xFFFF);

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    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();

}

繼續閱讀