flammmable 4 9 июня, 2023 Опубликовано 9 июня, 2023 (изменено) · Жалоба Пытаюсь при помощи кодгенератора STM32CubeIDE вот по этой инструкции вывести для микроконтроллера STM32F030F4P6 (TSSOP-20) на пины PA7 и PB1 ШИМ с таймеров TIM17 и TIM14. И чего-то не получается. Проверил выводы ногодрыгом - контакт есть, всё выводится. Вроде всё, что нужно указал: Channel1 - PWM Generator CH1 auto-reload preload - Enable Counter period - 500 Pulse - 250 В Clock Configuration вроде тоже всё ок, затактировался от HSI, напрямую, не через PLL - 8 МГц. Пробежал глазами по коду, вроде всё должно работать. Но почему-то на выходах PB1 и PA7 полная тишина. Может кто-нибудь подсказать, в чём дело? Spoiler #include "main.h" TIM_HandleTypeDef htim14; TIM_HandleTypeDef htim17; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM14_Init(void); static void MX_TIM17_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM14_Init(); MX_TIM17_Init(); while (1) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4; RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } static void MX_TIM14_Init(void) { TIM_OC_InitTypeDef sConfigOC = {0}; htim14.Instance = TIM14; htim14.Init.Prescaler = 1; htim14.Init.CounterMode = TIM_COUNTERMODE_UP; htim14.Init.Period = 600; htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim14) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_Init(&htim14) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim14, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } HAL_TIM_MspPostInit(&htim14); } static void MX_TIM17_Init(void) { TIM_OC_InitTypeDef sConfigOC = {0}; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; htim17.Instance = TIM17; htim17.Init.Prescaler = 1; htim17.Init.CounterMode = TIM_COUNTERMODE_UP; htim17.Init.Period = 500; htim17.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim17.Init.RepetitionCounter = 0; htim17.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim17) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_Init(&htim17) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 250; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; if (HAL_TIM_PWM_ConfigChannel(&htim17, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; sBreakDeadTimeConfig.DeadTime = 0; sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE; if (HAL_TIMEx_ConfigBreakDeadTime(&htim17, &sBreakDeadTimeConfig) != HAL_OK) { Error_Handler(); } HAL_TIM_MspPostInit(&htim17); } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET); GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } void Error_Handler(void) { __disable_irq(); while (1) { } } #ifdef USE_FULL_ASSERT void assert_failed(uint8_t *file, uint32_t line) { } #endif Изменено 9 июня, 2023 пользователем haker_fox Уточнил название МК. Также длинный код нужно прятать под спойлер! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sidy 1 9 июня, 2023 Опубликовано 9 июня, 2023 · Жалоба Где у Вас в коде настройка пина на альтернативную функцию? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 4 9 июня, 2023 Опубликовано 9 июня, 2023 (изменено) · Жалоба 3 hours ago, sidy said: Где у Вас в коде настройка пина на альтернативную функцию? STM32CubeIDE делает её в отдельном файле - stm32f0xx_hal_msp.c - в функции HAL_TIM_MspPostInit, которая вызывается в конце MX_TIM17_Init, который в main.c. Я попробовал (а вдруг!) вытащить (скопипастить) оттуда инициализацию пинов в MX_GPIO_Init, и поставить его после MX_TIM17_Init в main(void). Но это не помогло. Spoiler #include "main.h" void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); void HAL_MspInit(void) { __HAL_RCC_SYSCFG_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); } void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { if(htim_base->Instance==TIM1) { __HAL_RCC_TIM1_CLK_ENABLE(); } else if(htim_base->Instance==TIM14) { __HAL_RCC_TIM14_CLK_ENABLE(); } else if(htim_base->Instance==TIM17) { __HAL_RCC_TIM17_CLK_ENABLE(); } } void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(htim->Instance==TIM14) { __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF0_TIM14; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } else if(htim->Instance==TIM17) { __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; GPIO_InitStruct.Alternate = GPIO_AF5_TIM17; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } } void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { if(htim_base->Instance==TIM1) { __HAL_RCC_TIM1_CLK_DISABLE(); } else if(htim_base->Instance==TIM14) { __HAL_RCC_TIM14_CLK_DISABLE(); } else if(htim_base->Instance==TIM17) { __HAL_RCC_TIM17_CLK_DISABLE(); } } Причём, когда я в редакторе .ioc , в разделе TIM17 на вкладке GPIO Settings, в выпадающем списке GPIO Pull-up/Pull-down выбрал Pull-up, пин подтянулся к питанию. Изменено 9 июня, 2023 пользователем haker_fox Длинный код нужно прятать под спойлер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 60 9 июня, 2023 Опубликовано 9 июня, 2023 · Жалоба On 6/9/2023 at 3:51 PM, flammmable said: Я попробовал (а вдруг!) Метод научного тыка конечно хорош, но далеко не всегда прокатывает. Может, все-таки, попытаться ознакомиться с документацией на микроконтроллер ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vlad_G 8 9 июня, 2023 Опубликовано 9 июня, 2023 · Жалоба 5 минут назад, flammmable сказал: STM32CubeIDE делает её в отдельном файле "Грешно смеяться над больным человеком"(С) Не особо надейтесь на куб, у меня была ситуация для F030F4, когда куб для ацп генерил тактирование от RC генератора, а не от системной шины как в настройках. Проверьте бит: TIM14->CCER |= TIM_CCER_CC1E; //канал1 как выход TIM14->CR1 |= TIM_CR1_CEN; //включили ШИМ (куб обычно не включает устройства, надо делать это в ручную). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 4 9 июня, 2023 Опубликовано 9 июня, 2023 · Жалоба On 6/9/2023 at 4:00 PM, dimka76 said: Метод научного тыка конечно хорош, но далеко не всегда прокатывает. Может, все-таки, попытаться ознакомиться с документацией на микроконтроллер ? Референс мануал на STM32F0x0 составляет 779 страниц, а попробовать - 1 минута. Моё мнение, нужно идти от простых решений к сложным. On 6/9/2023 at 4:02 PM, Vlad_G said: Проверьте бит: TIM14->CCER |= TIM_CCER_CC1E; //канал1 как выход TIM14->CR1 |= TIM_CR1_CEN; //включили ШИМ (куб обычно не включает устройства, надо делать это в ручную). Спасибо, но не возымело. Ну, видимо, придётся действительно начать ковырять регистры, сверяясь с даташитом. STM32 и его инфраструктура сделаны специально так, чтобы программистов МК никогда не заменил бы ChatGPT. Это и плохо и хорошо одновременно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 60 9 июня, 2023 Опубликовано 9 июня, 2023 · Жалоба On 6/9/2023 at 4:14 PM, flammmable said: Референс мануал на STM32F0x0 составляет 779 страниц, а попробовать - 1 минута. Ну как, уложились в одну минуту ? On 6/9/2023 at 4:14 PM, flammmable said: STM32 и его инфраструктура сделаны специально так, чтобы программистов МК никогда не заменил бы ChatGPT. Все у них с инфраструктурой в порядке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
flammmable 4 9 июня, 2023 Опубликовано 9 июня, 2023 · Жалоба On 6/9/2023 at 4:19 PM, dimka76 said: Ну как, уложились в одну минуту ? Ну да. А что? On 6/9/2023 at 4:19 PM, dimka76 said: Все у них с инфраструктурой в порядке. Учитывая, что "была ситуация для F030F4, когда куб для ацп генерил тактирование от RC генератора, а не от системной шины как в настройках", можно сказать, что ваше заявление противоречит инженерному опыту. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 60 9 июня, 2023 Опубликовано 9 июня, 2023 · Жалоба On 6/9/2023 at 4:23 PM, flammmable said: Ну да. А что? Учитывая, что "была ситуация для F030F4, когда куб для ацп генерил тактирование от RC генератора, а не от системной шины как в настройках", можно сказать, что ваше заявление противоречит инженерному опыту. Я опасаюсь продолжать тему обсуждения Куба и Хала, т.к. это может выльется в очередной холивар. Поэтому оставлю этот вопрос без ответа Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vlad_G 8 9 июня, 2023 Опубликовано 9 июня, 2023 · Жалоба 4 минуты назад, dimka76 сказал: Поэтому оставлю этот вопрос без ответа Отвечу я. Да, такая ситуация была, поначалу понять не мог, что логический анализатор показывает не то, что по настройкам. Дело было когда куб еще был как отдельная сущность. Но и плюс был в этом - перешёл на регистры. Долговато, копать DS надо, но зато работает. Ну а с ШИМ на TIM 14, 16, 17, если всё сделать правильно, то всё работает. Тут точно подводных камней нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 9 июня, 2023 Опубликовано 9 июня, 2023 · Жалоба Внутрисхемный отладчик (ST-Link/Jlink) есть? Можете им прочитать значения нужных GPIOx->MODER, GPIOx->AFR, GPIOx->OTYPER (а вдруг?) и регистров таймера? Убедиться, что их значения соответствуют ожидаемым, что значение TIMx->CNT меняется, если программу запустить и снова остановить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 235 9 июня, 2023 Опубликовано 9 июня, 2023 · Жалоба 3 часа назад, flammmable сказал: Референс мануал на STM32F0x0 составляет 779 страниц Прям вот реально нужно весь его проштудировать от корки до корки, чтобы разобраться в работе простейшего таймера??? Если не набрасывать на вентилятор, то окажется, что достаточно всего с десяток страниц мануала просмотреть. Что в сумме окажется быстрее: лазания по инету в поисках кубо-примеров + ковыряния в натасканном из инета + написания пространных полотенец постов в форум. И к тому же, если пойти путём мануала, то в следующий раз времени потребуется меньше. Так как в голове что-то останется от предыдущего раза. А если искать чужие решения, то и все следующие разы потребуют столько же времени, как первый. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 42 9 июня, 2023 Опубликовано 9 июня, 2023 · Жалоба Может, так проще? Вбиваем в Гугле, качаем, читаем. AN4776_General-purpose_timer_cookbook.pdf AN4013-stm32-crossseries-timer-overview-stmicroelectronics.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 37 9 июня, 2023 Опубликовано 9 июня, 2023 (изменено) · Жалоба Убедиться, что их значения соответствуют ожидаемым, что значение TIMx->CNT меняется, если программу запустить и снова остановить. Больше того, скажу, программу можно остановить сразу после инициализации таймера и пускать\останавливать его в отладчике (TIMx_CNT видно как меняется), и мненять всё что нужно. И на выводе сигнал будет без работающего ядра. AN4776_General-purpose_timer_cookbook.pdf AN4013-stm32-crossseries-timer-overview-stmicroelectronics.pdf А всю доступную "доку" на "подопытного" (тем более у ST это всё на одной странице, хотя и длинной) - выкачивать сразу без вариантов, даже не обсуждается ;-) Изменено 9 июня, 2023 пользователем Obam Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться