/* * timers.c * * Created on: 4 янв. 2026 г. * Author: v0stap */ #include "main.h" void Timers_Init(void) { var.Send_Data_IRQ = 0; TIM1_Init(); TIM2_Init(); TIM3_Init(); TIM7_Init(); TIM14_Init(); TIM15_Init(); TIM16_Init(); TIM17_Init(); TIM6_Init(); //Init Timer1 PWM Input 1 } void TIM1_Init(void) { //configure IN1 as Iddle input PA8 TIM1 CH1 // PB4 AF1 TIM3 Input1 RCC->AHBENR |= RCC_AHBENR_GPIOAEN; GPIOA->MODER &= ~(3 << (8 * 2)); GPIOA->MODER |= (2 << (8 * 2)); GPIOA->OTYPER &= ~(1 << (8 * 1)); GPIOA->OSPEEDR &= ~(3 << (8 * 2)); GPIOA->PUPDR &= ~(3 << (8 * 2)); GPIOA->AFR[1] &= ~(15 << (0 * 4)); GPIOA->AFR[1] |= (2 << (0 * 4)); RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; /* (1) Select the active input TI1 for TIM3_CCR1 (CC1S = 01), select the active input TI1 for TIM3_CCR2 (CC2S = 10) */ /* (2) Select TI1FP1 as valid trigger input (TS = 101) configure the slave mode in reset mode (SMS = 100) */ /* (3) Enable capture by setting CC1E and CC2E select the rising edge on CC1 and CC1N (CC1P = 0 and CC1NP = 0, reset value), select the falling edge on CC2 (CC2P = 1). */ /* (4) Enable interrupt on Capture/Compare 1 */ /* (5) Enable counter */ TIM1->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_1; /* (1)*/ TIM1->SMCR |= TIM_SMCR_TS_2 | TIM_SMCR_TS_0 | TIM_SMCR_SMS_2; /* (2) */ TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC2P; /* (3) */ TIM1->DIER |= TIM_DIER_CC1IE; /* (4) */ TIM1->CR1 |= TIM_CR1_CEN; /* (5) */ NVIC_EnableIRQ(TIM1_CC_IRQn); } void TIM2_Init(void) { //configure IN1 as PWM input PA15 TIM2 // PB4 AF1 TIM3 Input1 RCC->AHBENR |= RCC_AHBENR_GPIOBEN; GPIOA->MODER &= ~(3 << (15 * 2)); GPIOA->MODER |= (2 << (15 * 2)); GPIOA->OTYPER &= ~(1 << (15 * 1)); GPIOA->OSPEEDR &= ~(3 << (15 * 2)); GPIOA->PUPDR &= ~(3 << (15 * 2)); GPIOA->AFR[1] &= ~(15 << (7 * 4)); GPIOA->AFR[1] |= (2 << (7 * 4)); RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; /* (1) Select the active input TI1 for TIM3_CCR1 (CC1S = 01), select the active input TI1 for TIM3_CCR2 (CC2S = 10) */ /* (2) Select TI1FP1 as valid trigger input (TS = 101) configure the slave mode in reset mode (SMS = 100) */ /* (3) Enable capture by setting CC1E and CC2E select the rising edge on CC1 and CC1N (CC1P = 0 and CC1NP = 0, reset value), select the falling edge on CC2 (CC2P = 1). */ /* (4) Enable interrupt on Capture/Compare 1 */ /* (5) Enable counter */ TIM2->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_1; /* (1)*/ TIM2->SMCR |= TIM_SMCR_TS_2 | TIM_SMCR_TS_0 | TIM_SMCR_SMS_2; /* (2) */ TIM2->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC2P; /* (3) */ TIM2->DIER |= TIM_DIER_CC1IE; /* (4) */ TIM2->CR1 |= TIM_CR1_CEN; /* (5) */ NVIC_EnableIRQ(TIM2_IRQn); } void TIM3_Init(void) { //configure IN1 as Iddle input PB4 TIM3 // PB4 AF1 TIM3 Input1 RCC->AHBENR |= RCC_AHBENR_GPIOBEN; // GPIOB->MODER &= ~(3 << (4 * 2)); // GPIOB->MODER |= (2 << (4 * 2)); // GPIOB->OTYPER &= ~(1 << 4 * 1); // GPIOB->OSPEEDR &= ~(3 << (4 * 2)); // GPIOB->PUPDR &= ~(3 << (4 * 2)); // GPIOB->AFR[0] &= ~(15 << (4 * 4)); // GPIOB->AFR[0] |= (1 << (4 * 4)); GPIOB->MODER &= ~(3 << (5 * 2)); GPIOB->MODER |= (2 << (5 * 2)); GPIOB->OTYPER &= ~(1 << (5 * 1)); GPIOB->OSPEEDR &= ~(3 << (5 * 2)); GPIOB->PUPDR &= ~(3 << (5 * 2)); GPIOB->AFR[0] &= ~(15 << (5 * 4)); GPIOB->AFR[0] |= (1 << (5 * 4)); RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; /* (1) Select the active input TI1 for TIM3_CCR1 (CC1S = 01), select the active input TI1 for TIM3_CCR2 (CC2S = 10) */ /* (2) Select TI1FP1 as valid trigger input (TS = 101) configure the slave mode in reset mode (SMS = 100) */ /* (3) Enable capture by setting CC1E and CC2E select the rising edge on CC1 and CC1N (CC1P = 0 and CC1NP = 0, reset value), select the falling edge on CC2 (CC2P = 1). */ /* (4) Enable interrupt on Capture/Compare 1 */ /* (5) Enable counter */ TIM3->CCMR1 |= TIM_CCMR1_CC1S_1 | TIM_CCMR1_CC2S_0; /* (1)*/ TIM3->SMCR |= TIM_SMCR_TS_2 | TIM_SMCR_TS_0 | TIM_SMCR_SMS_2; /* (2) */ TIM3->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC2P; /* (3) */ TIM3->DIER |= TIM_DIER_CC1IE; /* (4) */ TIM3->CR1 |= TIM_CR1_CEN; /* (5) */ NVIC_EnableIRQ(TIM3_IRQn); } void TIM6_Init(void) { // Init Timer 6 RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; TIM6->PSC = 479; TIM6->ARR = 2000; TIM6->CR1 |= 1 << 0 | 1 << 7; TIM6->CR2 = 0; TIM6->SMCR = 0; TIM6->DIER = 1 << 0; TIM6->CCMR1 = 0; TIM6->CCMR2 = 0; TIM6->CCER = 0x1111; TIM6->SR = 0; NVIC_EnableIRQ(TIM6_IRQn); } void TIM7_Init(void) { // Init Timer 6 RCC->APB1ENR |= RCC_APB1ENR_TIM7EN; TIM7->PSC = 4799; TIM7->ARR = 1000; TIM7->CR1 |= 1 << 0 | 1 << 7; TIM7->CR2 = 0; TIM7->SMCR = 0; TIM7->DIER = 1 << 0; TIM7->CCMR1 = 0; TIM7->CCMR2 = 0; TIM7->CCER = 0x1111; TIM7->SR = 0; NVIC_EnableIRQ(TIM7_IRQn); } void TIM14_Init(void) { /* (1) Set prescaler to 47, so APBCLK/48 i.e 1MHz */ /* (2) Set ARR = 8, as timer clock is 1MHz the period is 9 us */ /* (3) Set CCRx = 4, , the signal will be high during 4 us */ /* (4) Select PWM mode 1 on OC1 (OC1M = 110), enable preload register on OC1 (OC1PE = 1) */ /* (5) Select active high polarity on OC1 (CC1P = 0, reset value), enable the output on OC1 (CC1E = 1)*/ /* (6) Enable output (MOE = 1)*/ /* (7) Enable counter (CEN = 1) select edge aligned mode (CMS = 00, reset value) select direction as upcounter (DIR = 0, reset value) */ /* (8) Force update generation (UG = 1) */ TIM14->PSC = 48 - 1; /* (1) */ TIM14->ARR = 1000; /* (2) */ TIM14->CCR1 = 500; /* (3) */ TIM14->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE; /* (4) */ TIM14->CCER |= TIM_CCER_CC1E; /* (5) */ TIM14->BDTR |= TIM_BDTR_MOE; /* (6) */ TIM14->CR1 |= TIM_CR1_CEN; /* (7) */ TIM14->EGR |= TIM_EGR_UG; /* (8) */ } void TIM15_Init(void) { //configure IN1 as Iddle input PB4 TIM3 // PB4 AF1 TIM3 Input1 RCC->AHBENR |= RCC_AHBENR_GPIOBEN; GPIOB->MODER &= ~(3 << (14 * 2)); GPIOB->MODER |= (2 << (14 * 2)); GPIOB->OTYPER &= ~(1 << (14 * 1)); GPIOB->OSPEEDR &= ~(3 << (4 * 2)); GPIOB->PUPDR &= ~(3 << (4 * 2)); GPIOB->AFR[0] &= ~(15 << (6 * 4)); GPIOB->AFR[0] |= (1 << (6 * 4)); RCC->APB2ENR |= RCC_APB2ENR_TIM15EN; /* (1) Select the active input TI1 for TIM3_CCR1 (CC1S = 01), select the active input TI1 for TIM3_CCR2 (CC2S = 10) */ /* (2) Select TI1FP1 as valid trigger input (TS = 101) configure the slave mode in reset mode (SMS = 100) */ /* (3) Enable capture by setting CC1E and CC2E select the rising edge on CC1 and CC1N (CC1P = 0 and CC1NP = 0, reset value), select the falling edge on CC2 (CC2P = 1). */ /* (4) Enable interrupt on Capture/Compare 1 */ /* (5) Enable counter */ TIM15->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_1; /* (1)*/ TIM15->SMCR |= TIM_SMCR_TS_2 | TIM_SMCR_TS_0 | TIM_SMCR_SMS_2; /* (2) */ TIM15->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC2P; /* (3) */ TIM15->DIER |= TIM_DIER_CC1IE; /* (4) */ TIM15->CR1 |= TIM_CR1_CEN; /* (5) */ NVIC_EnableIRQ(TIM15_IRQn); } void TIM16_Init(void) { /* (1) Set prescaler to 47, so APBCLK/48 i.e 1MHz */ /* (2) Set ARR = 8, as timer clock is 1MHz the period is 9 us */ /* (3) Set CCRx = 4, , the signal will be high during 4 us */ /* (4) Select PWM mode 1 on OC1 (OC1M = 110), enable preload register on OC1 (OC1PE = 1) */ /* (5) Select active high polarity on OC1 (CC1P = 0, reset value), enable the output on OC1 (CC1E = 1)*/ /* (6) Enable output (MOE = 1)*/ /* (7) Enable counter (CEN = 1) select edge aligned mode (CMS = 00, reset value) select direction as upcounter (DIR = 0, reset value) */ /* (8) Force update generation (UG = 1) */ TIM16->PSC = 48 - 1; /* (1) */ TIM16->ARR = 1000; /* (2) */ TIM16->CCR1 = 500; /* (3) */ TIM16->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE; /* (4) */ TIM16->CCER |= TIM_CCER_CC1E; /* (5) */ TIM16->BDTR |= TIM_BDTR_MOE; /* (6) */ TIM16->CR1 |= TIM_CR1_CEN; /* (7) */ TIM16->EGR |= TIM_EGR_UG; /* (8) */ } void TIM17_Init(void) { /* (1) Set prescaler to 47, so APBCLK/48 i.e 1MHz */ /* (2) Set ARR = 8, as timer clock is 1MHz the period is 9 us */ /* (3) Set CCRx = 4, , the signal will be high during 4 us */ /* (4) Select PWM mode 1 on OC1 (OC1M = 110), enable preload register on OC1 (OC1PE = 1) */ /* (5) Select active high polarity on OC1 (CC1P = 0, reset value), enable the output on OC1 (CC1E = 1)*/ /* (6) Enable output (MOE = 1)*/ /* (7) Enable counter (CEN = 1) select edge aligned mode (CMS = 00, reset value) select direction as upcounter (DIR = 0, reset value) */ /* (8) Force update generation (UG = 1) */ TIM17->PSC = 48 - 1; /* (1) */ TIM17->ARR = 1000; /* (2) */ TIM17->CCR1 = 0; /* (3) */ TIM17->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE; /* (4) */ TIM17->CCER |= TIM_CCER_CC1E; /* (5) */ TIM17->BDTR |= TIM_BDTR_MOE; /* (6) */ TIM17->CR1 |= TIM_CR1_CEN; /* (7) */ TIM17->EGR |= TIM_EGR_UG; /* (8) */ } void TIM1_CC_IRQHandler(void) { if ((TIM1->SR & TIM_SR_CC1IF) != 0) { if ((TIM1->SR & TIM_SR_CC1OF) != 0) /* Check the overflow */ { /* Overflow error management */ /* Reinitialize the laps computing */ TIM1->SR &= ~(TIM_SR_CC1OF | TIM_SR_CC1IF); /* Clear the flags */ return; } else { var.dvi_fr[0] = TIM1->CCR1; var.dvi_dt[0] = (TIM1->CCR2) * 100 / var.dvi_fr[0]; //Get DC var.dvi_fr[0] = 48000000 / var.dvi_fr[0]; // printf("data1 =%d; data2 =%d \n",counter0,counter1); } } else { /* Unexpected Interrupt */ /* Manage an error for robust application */ } } void TIM2_IRQHandler(void) { var.tim2_timeout = 0; if ((TIM2->SR & TIM_SR_CC1IF) != 0) { if ((TIM2->SR & TIM_SR_CC1OF) != 0) {/* Check the overflow */ /* Overflow error management */ /* Reinitialize the laps computing */ TIM2->SR &= ~(TIM_SR_CC1OF | TIM_SR_CC1IF); /* Clear the flags */ return; } else { var.dvi_fr[1] = TIM2->CCR1; var.dvi_dt[1] = (TIM2->CCR2) * 100 / var.dvi_fr[1]; //Get DC var.dvi_fr[1] = 48000000 / var.dvi_fr[1]; // printf("data1 =%d; data2 =%d \n",counter0,counter1); } } else { var.dvi_dt[1] = 0xff00; var.dvi_fr[1] = 0; /* Unexpected Interrupt */ /* Manage an error for robust application */ } } void TIM3_IRQHandler(void) { if ((TIM3->SR & TIM_SR_CC1IF) != 0) { if ((TIM3->SR & TIM_SR_CC1OF) != 0) /* Check the overflow */ { /* Overflow error management */ /* Reinitialize the laps computing */ TIM3->SR &= ~(TIM_SR_CC1OF | TIM_SR_CC1IF); /* Clear the flags */ return; } else { var.dvi_fr[2] = TIM3->CCR1; var.dvi_dt[2] = (TIM3->CCR2) * 1000 / var.dvi_fr[2]; //Get DC var.dvi_fr[2] = 48000000 / var.dvi_fr[2]; // printf("data1 =%d; data2 =%d \n",counter0,counter1); } } else { /* Unexpected Interrupt */ /* Manage an error for robust application */ } } void TIM6_DAC_IRQHandler(void) { TIM6->SR &= ~(1 << 0); //TIM2->CNT = 600; var.Send_Data_IRQ = 4; if (var.tim1_timeout < 254) var.tim1_timeout++; if (var.tim2_timeout < 254) var.tim2_timeout++; if (var.tim3_timeout < 254) var.tim3_timeout++; if (var.tim15_timeout < 254) var.tim15_timeout++; if (var.can_timeout < 254) var.can_timeout++; } void TIM7_IRQHandler(void) { TIM7->SR &= ~(1 << 0); if (var.dvo_dt[3] == 0) HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); else HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); } void TIM15_IRQHandler(void) { if ((TIM15->SR & TIM_SR_CC1IF) != 0) { if ((TIM15->SR & TIM_SR_CC1OF) != 0) /* Check the overflow */ { /* Overflow error management */ /* Reinitialize the laps computing */ TIM15->SR &= ~(TIM_SR_CC1OF | TIM_SR_CC1IF); /* Clear the flags */ return; } else { var.dvi_fr[3] = TIM15->CCR1; var.dvi_dt[3] = (TIM15->CCR2) * 100 / TIM15->CCR1; //Get DC var.dvi_fr[3] = 48000000 / var.dvi_fr[3]; // printf("data1 =%d; data2 =%d \n",counter0,counter1); } } else { /* Unexpected Interrupt */ /* Manage an error for robust application */ } }