For TIM2-TIM5
void PwmInit(void)
{
//ch1 -PA0
GPIOA->CRL |= GPIO_CRL_MODE0; //50Mhz
GPIOA->CRL &= ~GPIO_CRL_CNF0; //clear CNF[1:0] for PA0
GPIOA->CRL |= GPIO_CRL_CNF0_1; //output Push-Pull in alternative function mode
//ch2 - PA1
GPIOA->CRL |= GPIO_CRL_MODE1; //50Mhz
GPIOA->CRL &= ~GPIO_CRL_CNF1; //clear CNF[1:0] for PA1
GPIOA->CRL |= GPIO_CRL_CNF1_1; //output Push-Pull in alternative function mode
//ch3 - PA2
GPIOA->CRL |= GPIO_CRL_MODE2; //50Mhz
GPIOA->CRL &= ~GPIO_CRL_CNF2; //clear CNF[1:0] for PA2
GPIOA->CRL |= GPIO_CRL_CNF2_1; //output Push-Pull in alternative function mode
//ch4 - PA3
GPIOA->CRL |= GPIO_CRL_MODE3; //50Mhz
GPIOA->CRL &= ~GPIO_CRL_CNF3; //clear CNF[1:0] for PA3
GPIOA->CRL |= GPIO_CRL_CNF3_1; //output Push-Pull in alternative function mode
//TIM2 Settings
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->CR1 |= TIM_CR1_ARPE; //autorelode mode
TIM2->CCMR1 |= TIM_CCMR1_OC1PE | TIM_CCMR1_OC2PE; //Output Compare Preload enable
TIM2->CCMR2 |= TIM_CCMR2_OC3PE | TIM_CCMR2_OC4PE;
//TIM2->PSC = 71; //1us
TIM2->ARR = 8000; // 8000*14ns = 112us = 8928Hz
TIM2->CCR1 = 4000; //ch1 1duty cycle = 50%
TIM2->CCR2 = 4000; //ch2 1duty cycle = 50%
TIM2->CCR3 = 4000; //ch2 1duty cycle = 50%
TIM2->CCR4 = 4000; //ch2 1duty cycle = 50%
//TIM2->CCER |= TIM_CCER_CC2P; //polarity of output signal
//Capture/Compare 2 output enable
TIM2->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E;
//Output Compare Mode - 110 - PWM mode 1
TIM2->CCMR1 |= (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1);
TIM2->CCMR1 |= (TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1);
TIM2->CCMR2 |= (TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1);
TIM2->CCMR2 |= (TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1);
//start counting
TIM2->CR1 |= TIM_CR1_CEN;
}
void InitTIM1(int enable)
{
TIM1->CR1 = TIM_CR1_ARPE | TIM_CounterMode_Up;
TIM1->ARR = 5*24-1; // период повторения, 0 - останов
TIM1->PSC = 0; // прескалер на 1, один тик = 1/24 мкс
TIM1->RCR = 0; //TIM_RepetitionCounter;
// OC1
TIM1->CCR1 = 12; // 0.5мкс.
TIM1->CCMR1 = TIM_OCMode_Toggle; //TIM_OCMode_PWM2;
TIM1->CCER = TIM_OCPolarity_High | TIM_OutputState_Enable;
// OC2
TIM1->CCR2 = 24; // 1.0us
TIM1->CCMR1 |= TIM_OCMode_Toggle << 8;
TIM1->CCER |= (TIM_OCPolarity_High | TIM_OutputState_Enable) <<4;
// OC 3
TIM1->CCR3 = 36; // 1.5us.
TIM1->CCMR2 |= TIM_OCMode_PWM1;
TIM1->CCER |= ( TIM_OCPolarity_High | TIM_OutputState_Enable
| TIM_OCNPolarity_Low | TIM_OutputNState_Enable)<<8;
// OC4
TIM1->CCR4 = 24; // 1us
TIM1->CCMR2 |= TIM_OCMode_PWM1 << 8;
TIM1->CCER |= (TIM_OCPolarity_High | TIM_OutputState_Enable) <<12;
TIM1->EGR = TIM_EGR_UG; // генерируем update event для загрузки всех теневых регистров
TIM1->BDTR |= TIM_BDTR_MOE + 12; // разрешение выходных сигналов OCx + dead-time 0.5us
// DMA Init
TIM1->DIER = TIM_DIER_UDE;
TIM1->DCR = (0<<8) | (&(TIM1->ARR) - &(TIM1->CR1))/sizeof(TIM1->CR1);
DMA1_Channel5->CCR = 0
| 0*DMA_CCR1_EN // Channel enable
| 0*DMA_CCR1_TCIE // Transfer complete interrupt enable
| DMA_CCR1_DIR // Data transfer direction 1: Mem --> Periph
| DMA_CCR1_CIRC // Circular mode
| 0*DMA_CCR1_PINC // Peripheral increment mode
| DMA_CCR1_MINC // Memory increment mode
| DMA_PeripheralDataSize_Word // DMA_CCR1_PSIZE PSIZE[1:0] bits (Peripheral size)
| DMA_MemoryDataSize_HalfWord // DMA_CCR1_MSIZE MSIZE[1:0] bits (Memory size)
| (3<<12) //*DMA_CCR1_PL // PL[1:0] bits(Channel Priority level)
| 0*DMA_CCR1_MEM2MEM; // Memory to memory mode
DMA1_Channel5->CNDTR = 2;
DMA1_Channel5->CPAR = (uint32_t)&(TIM1->DMAR);
DMA1_Channel5->CMAR = (uint32_t) dmabuf;
DMA1_Channel5->CCR |= DMA_CCR1_EN; // Channel enable
// end DMA Init
if(enable) TIM1->CR1 |= TIM_CR1_CEN; // разрешаем счёт
}
void Timer1_Init (void)
{
RCC->APB2ENR |= (1<<0); //вкл. тактиров. таймера1
TIM1->PSC = 20; //делитель
TIM1->CCMR1 |= (7<<12)|(7<<4); //+ канал 1 и 2 - ШИМ
TIM1->CCMR2 |= (7<<12)|(7<<4); //+ канал 3 и 4 - ШИМ
TIM1->CCER |= (1<<12)|(1<<8)|(1<<4)|(1<<0); //+
TIM1->BDTR |= (1<<15);
TIM1->CCR1 = 0xFFFF; //значение ШИМ канал 1 (ТЕМ1.1) чем меньше тем длиннее 1
TIM1->CCR2 = 0xFFFF; //значение ШИМ канал 2 (ТЕМ1.2)
TIM1->CCR3 = 0xFFFF; //значение ШИМ канал 3 (ТЕМ2.1)
TIM1->CCR4 = 0xFFFF; //значение ШИМ канал 4 (ТЕМ2.2)
TIM1->CR1 |= (1<<0); //вкл. таймер 1
}
void PwmInit(void)
{
//ch1 -PA0
GPIOA->CRL |= GPIO_CRL_MODE0; //50Mhz
GPIOA->CRL &= ~GPIO_CRL_CNF0; //clear CNF[1:0] for PA0
GPIOA->CRL |= GPIO_CRL_CNF0_1; //output Push-Pull in alternative function mode
//ch2 - PA1
GPIOA->CRL |= GPIO_CRL_MODE1; //50Mhz
GPIOA->CRL &= ~GPIO_CRL_CNF1; //clear CNF[1:0] for PA1
GPIOA->CRL |= GPIO_CRL_CNF1_1; //output Push-Pull in alternative function mode
//ch3 - PA2
GPIOA->CRL |= GPIO_CRL_MODE2; //50Mhz
GPIOA->CRL &= ~GPIO_CRL_CNF2; //clear CNF[1:0] for PA2
GPIOA->CRL |= GPIO_CRL_CNF2_1; //output Push-Pull in alternative function mode
//ch4 - PA3
GPIOA->CRL |= GPIO_CRL_MODE3; //50Mhz
GPIOA->CRL &= ~GPIO_CRL_CNF3; //clear CNF[1:0] for PA3
GPIOA->CRL |= GPIO_CRL_CNF3_1; //output Push-Pull in alternative function mode
//TIM2 Settings
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->CR1 |= TIM_CR1_ARPE; //autorelode mode
TIM2->CCMR1 |= TIM_CCMR1_OC1PE | TIM_CCMR1_OC2PE; //Output Compare Preload enable
TIM2->CCMR2 |= TIM_CCMR2_OC3PE | TIM_CCMR2_OC4PE;
//TIM2->PSC = 71; //1us
TIM2->ARR = 8000; // 8000*14ns = 112us = 8928Hz
TIM2->CCR1 = 4000; //ch1 1duty cycle = 50%
TIM2->CCR2 = 4000; //ch2 1duty cycle = 50%
TIM2->CCR3 = 4000; //ch2 1duty cycle = 50%
TIM2->CCR4 = 4000; //ch2 1duty cycle = 50%
//TIM2->CCER |= TIM_CCER_CC2P; //polarity of output signal
//Capture/Compare 2 output enable
TIM2->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E;
//Output Compare Mode - 110 - PWM mode 1
TIM2->CCMR1 |= (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1);
TIM2->CCMR1 |= (TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1);
TIM2->CCMR2 |= (TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1);
TIM2->CCMR2 |= (TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1);
//start counting
TIM2->CR1 |= TIM_CR1_CEN;
}
void InitTIM1(int enable)
{
TIM1->CR1 = TIM_CR1_ARPE | TIM_CounterMode_Up;
TIM1->ARR = 5*24-1; // период повторения, 0 - останов
TIM1->PSC = 0; // прескалер на 1, один тик = 1/24 мкс
TIM1->RCR = 0; //TIM_RepetitionCounter;
// OC1
TIM1->CCR1 = 12; // 0.5мкс.
TIM1->CCMR1 = TIM_OCMode_Toggle; //TIM_OCMode_PWM2;
TIM1->CCER = TIM_OCPolarity_High | TIM_OutputState_Enable;
// OC2
TIM1->CCR2 = 24; // 1.0us
TIM1->CCMR1 |= TIM_OCMode_Toggle << 8;
TIM1->CCER |= (TIM_OCPolarity_High | TIM_OutputState_Enable) <<4;
// OC 3
TIM1->CCR3 = 36; // 1.5us.
TIM1->CCMR2 |= TIM_OCMode_PWM1;
TIM1->CCER |= ( TIM_OCPolarity_High | TIM_OutputState_Enable
| TIM_OCNPolarity_Low | TIM_OutputNState_Enable)<<8;
// OC4
TIM1->CCR4 = 24; // 1us
TIM1->CCMR2 |= TIM_OCMode_PWM1 << 8;
TIM1->CCER |= (TIM_OCPolarity_High | TIM_OutputState_Enable) <<12;
TIM1->EGR = TIM_EGR_UG; // генерируем update event для загрузки всех теневых регистров
TIM1->BDTR |= TIM_BDTR_MOE + 12; // разрешение выходных сигналов OCx + dead-time 0.5us
// DMA Init
TIM1->DIER = TIM_DIER_UDE;
TIM1->DCR = (0<<8) | (&(TIM1->ARR) - &(TIM1->CR1))/sizeof(TIM1->CR1);
DMA1_Channel5->CCR = 0
| 0*DMA_CCR1_EN // Channel enable
| 0*DMA_CCR1_TCIE // Transfer complete interrupt enable
| DMA_CCR1_DIR // Data transfer direction 1: Mem --> Periph
| DMA_CCR1_CIRC // Circular mode
| 0*DMA_CCR1_PINC // Peripheral increment mode
| DMA_CCR1_MINC // Memory increment mode
| DMA_PeripheralDataSize_Word // DMA_CCR1_PSIZE PSIZE[1:0] bits (Peripheral size)
| DMA_MemoryDataSize_HalfWord // DMA_CCR1_MSIZE MSIZE[1:0] bits (Memory size)
| (3<<12) //*DMA_CCR1_PL // PL[1:0] bits(Channel Priority level)
| 0*DMA_CCR1_MEM2MEM; // Memory to memory mode
DMA1_Channel5->CNDTR = 2;
DMA1_Channel5->CPAR = (uint32_t)&(TIM1->DMAR);
DMA1_Channel5->CMAR = (uint32_t) dmabuf;
DMA1_Channel5->CCR |= DMA_CCR1_EN; // Channel enable
// end DMA Init
if(enable) TIM1->CR1 |= TIM_CR1_CEN; // разрешаем счёт
}
void Timer1_Init (void)
{
RCC->APB2ENR |= (1<<0); //вкл. тактиров. таймера1
TIM1->PSC = 20; //делитель
TIM1->CCMR1 |= (7<<12)|(7<<4); //+ канал 1 и 2 - ШИМ
TIM1->CCMR2 |= (7<<12)|(7<<4); //+ канал 3 и 4 - ШИМ
TIM1->CCER |= (1<<12)|(1<<8)|(1<<4)|(1<<0); //+
TIM1->BDTR |= (1<<15);
TIM1->CCR1 = 0xFFFF; //значение ШИМ канал 1 (ТЕМ1.1) чем меньше тем длиннее 1
TIM1->CCR2 = 0xFFFF; //значение ШИМ канал 2 (ТЕМ1.2)
TIM1->CCR3 = 0xFFFF; //значение ШИМ канал 3 (ТЕМ2.1)
TIM1->CCR4 = 0xFFFF; //значение ШИМ канал 4 (ТЕМ2.2)
TIM1->CR1 |= (1<<0); //вкл. таймер 1
}