Главная › Форумы › Программирование микроконтроллеров › Программирование МК STM32 › Ответ в теме: Программирование МК STM32
Пробую написать программу на STM32 используя HAL библиотеки. В программе инициализируются три таймера номер 3 (TIM3), номер 5 (TIM5), номер 2 (TIM2).
TIM3 тактируется от внутреннего источника (от шины), работает в режиме ШИМ и формирует на выходе меандр с частотой 1,2 МГц.
TIM5 тактируется от TIM3, работает в режиме ШИМ.
TIM2 тактируется от TIM3, работает в режиме сравнения.
Как хотелось бы чтобы работало:
Таймеры запускаются одновременно. Разрешается прерывание по TIM2 по значению Pulse в STM32CubeMX. TIM2 отсчитывает интервал времени в течение которого TIM5 сформирует на выходе два импульса ШИМ с заданной частотой и заполнением. Когда TIM2 досчитывает до конца временного интервала (значение Pulse в STM32CubeMX), формируется прерывание.
В обработчике прерывания меняется заполнение импульсов, которые формирует TIM5. Запрещается прерывание TIM2 по значению Pulse и разрешается прерывание TIM2 по переполнению.
Далее таймеры продолжают считать. TIM5 формирует один импульс с измененным заполнением и возникает переполнение по переполнению TIM2.
В обработчике прерывания меняется заполнение импульсов, которые формирует TIM5, на изначальное значение. Запрещается прерывание TIM2 по переполнению, разрешается прерывание TIM2 по значению Pulse.
И так по кругу… TIM5 на выходе должен формировать последовательность импульсов: два с одинаковым заполнением, один с меньшим, опять два с одинаковым, опять один с меньшим и т.д.
Написал такой код main.c:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
MX_GPIO_Init(); MX_TIM3_Init(); MX_TIM2_Init(); MX_TIM5_Init(); HAL_TIM_PWM_Start (&htim2, TIM_CHANNEL_1); HAL_TIM_PWM_Start (&htim2, TIM_CHANNEL_2); HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_3); HAL_TIM_PWM_Start (&htim5, TIM_CHANNEL_1); HAL_TIM_PWM_Start (&htim3, TIM_CHANNEL_1); while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } |
Обработка прерываний такая:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
void HAL_TIM_OC_DelayElapsedCallback (TIM_HandleTypeDef *htim) { if (htim->Instance == TIM2) { if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3) { HAL_TIM_PWM_Stop (&htim3, TIM_CHANNEL_1); HAL_TIM_PWM_Stop (&htim2, TIM_CHANNEL_1); HAL_TIM_PWM_Stop (&htim2, TIM_CHANNEL_2); HAL_TIM_OC_Stop_IT (&htim2, TIM_CHANNEL_3); HAL_TIM_PWM_Stop (&htim5, TIM_CHANNEL_1); TIM5->CCR1 = 4; __HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE); HAL_TIM_PWM_Start (&htim2, TIM_CHANNEL_1); HAL_TIM_PWM_Start (&htim2, TIM_CHANNEL_2); HAL_TIM_OC_Start (&htim2, TIM_CHANNEL_3); HAL_TIM_PWM_Start (&htim5, TIM_CHANNEL_1); HAL_TIM_PWM_Start (&htim3, TIM_CHANNEL_1); } else return; } } //---Прерывание по переполнению счетчика------------------------------- void HAL_TIM_PeriodElapsedCallback (TIM_HandleTypeDef *htim) { if(htim->Instance == TIM2) { HAL_TIM_PWM_Stop (&htim3, TIM_CHANNEL_1); HAL_TIM_PWM_Stop (&htim2, TIM_CHANNEL_1); HAL_TIM_PWM_Stop (&htim2, TIM_CHANNEL_2); HAL_TIM_OC_Stop (&htim2, TIM_CHANNEL_3); HAL_TIM_PWM_Stop (&htim5, TIM_CHANNEL_1); __HAL_TIM_DISABLE_IT (&htim2, TIM_IT_UPDATE ); TIM5->CCR1 = 3; HAL_TIM_PWM_Start (&htim2, TIM_CHANNEL_1); HAL_TIM_PWM_Start (&htim2, TIM_CHANNEL_2); HAL_TIM_OC_Start_IT(&htim2, TIM_CHANNEL_3); HAL_TIM_PWM_Start (&htim5, TIM_CHANNEL_1); HAL_TIM_PWM_Start (&htim3, TIM_CHANNEL_1); } else return; } |
Начинаю отлаживать. Пробую сначала работу без второго обработчика прерывания. Вижу следующую картину