帶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);
//
// 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();
}