Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Настройка скважности ШИМ в STM32F103

Ср май 25, 2022 19:37:27

Здравствуйте, уважемые коты.

Я пытаюсь настраивать ШИМ в STM32F103C8T6. Почему-то не получается настроить скважность.
Делаю следующее:
Порт, настроенный на 72 МГц, настраиваю на выход таймера TIM1. Хочу генерировать ШИМ, например, с частотой 18кГц, соответственно выбираю делитель частоты, равным 8, а счетчик периода выбираю равным 500.

Код инициализации таймера, соответственно:
Код:
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 8;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 500;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;


Далее запускаю сам таймер, записывая в CCR1 400 (насколько я понял, скважность должна получиться 400/500).

Код:
   HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
   TIM1->CCR1 = 400;


В итоге получаю импульсы с частотой около 16 кГц и скважностью 5/57

Где я ошибаюсь?
Вложения
Cube.jpg
(123.07 KiB) Скачиваний: 62
PWM.jpg
(51.52 KiB) Скачиваний: 63

Re: Настройка скважности ШИМ в STM32F103

Чт май 26, 2022 08:19:47

1. 57.14/6268 = 0.91 = 91%. Хотя и не совпадает с ожидаемыми 400/500
2. Используйте что-то одно - либо HAL, либо обращение к регистрам.

Взял код от проекта контроллера кулеров, по быстрому переделал под ваш вашиант.
Какой канал используете - не знаю, потому оставил как есть - все.
Код:
   SystemCoreClockUpdate();
   TIM1->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1PE | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2PE;
   TIM1->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3PE | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4PE;
   TIM1->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E;
   TIM1->ARR = SystemCoreClock / 18000;

   TIM1->CCR1 = TIM2->ARR * Percent / 100;

Значение Percent - поставьте своё. У меня код работает именно таким образом, максимально самостоятельно вычисляя значения. Хотя это и имеет некоторые проблемы при нечётных значениях.

Re: Настройка скважности ШИМ в STM32F103

Чт май 26, 2022 11:26:57

Спасибо, но непонятно: куда именно внедрять этот код и как быть с параметрами таймера в Cube?

Код:
SystemCoreClockUpdate();


найдена аж в system_stm32f10x.c, т.е. править этот файл?

Добавлено after 1 hour 41 minute 28 seconds:
1. 57.14/6268 = 0.91 = 91%. Хотя и не совпадает с ожидаемыми 400/500



Откуда Вы взяли число 6268?
В том-то и дело, что скважность (и по графику это видно невооруженным взглядом) скорее похожа на 1/10 (фактически 5/57), чем на 400/500 = 8/10

При этом замена числа в регистре CCR1 на скважность заметным образом не влияет. Это если редактировать связку

Код:
   HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
   TIM1->CCR1 = 400;
Вложения
PWM.jpg
(51.52 KiB) Скачиваний: 50

Re: Настройка скважности ШИМ в STM32F103

Чт май 26, 2022 13:42:44

Я в этом вашем калокубе не разбираюсь, но таки если "прескалер" - это TIM1->PSC, то от желаемого единичку надо отнимать. Т.е. если хочется 9МГц, то и писать нужно туда 7!
Аналогично с регистрами ARR и CCRx. В общем, нужно было написать:
Код:
TIM1->PSC = 7;
TIM1->ARR = 499;
TIM1->PSC1 = 399;

но даже с 500 и 400 должно было быть заполнение 401/501=0.800, а никак не 5/57=0.088…

P.S. Если бы у вас там был инвертированный выход, заполнение (длительность 1 / полная длительность) составляло бы не 401/501, а 100/501=0.200. Откуда взялось 5/57 — одному калу известно!

Re: Настройка скважности ШИМ в STM32F103

Чт май 26, 2022 13:51:45

Вот лежали функции инициализации шим на хал и на регистрах. Вроде работали
Инициализация на хал
Код:
void init_PWM(void)
{
   __HAL_RCC_TIM4_CLK_ENABLE();
   TMR4.Instance = TIM4;
   TMR4.Init.Period = 19999;
   TMR4.Init.CounterMode = TIM_COUNTERMODE_UP;
   TMR4.Init.Prescaler = 0;
   TMR4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
   HAL_TIM_PWM_Init (&TMR4);  //

   PWM4.OCMode  = TIM_OCMODE_PWM1;
   PWM4.Pulse =10000;
   PWM4.OCPolarity = TIM_OCPOLARITY_HIGH;
   PWM4.OCFastMode = TIM_OCFAST_ENABLE;
   HAL_TIM_PWM_ConfigChannel(&TMR4, &PWM4, TIM_CHANNEL_1);
   HAL_TIM_PWM_Start(&TMR4, TIM_CHANNEL_1);
}


на регистрах
Код:
void init_servo_port(void) {
   __HAL_RCC_GPIOF_CLK_ENABLE();

   GPIOF->MODER |= GPIO_MODER_MODE6_1; // Alternate function mode
   GPIOF->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6; // very high
   GPIOF->PUPDR |= GPIO_PUPDR_PUPD6_1; // pull-down
   GPIOF->AFR[0] |= (0x03 << 6 * 4);
}

void init_servo_PWM(void) {
   __HAL_RCC_TIM10_CLK_ENABLE();
   /* f = 50 Гц. Время периода 20 мс */
   TIM10->ARR = (20000 - 1); // период в микросекундах
   TIM10->PSC = (120 - 1); // предделитель

   TIM10->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // режим ШИМ1
   TIM10->CCMR1 |= TIM_CCMR1_OC1PE; // буферизируем CCR1. необходимо в шиме. Подгрузка осуществляется только после события обновления
   TIM10->CCMR1 &= ~TIM_CCMR1_CC1S; //канал на выход

   TIM10->CCR1 = TIM10->ARR/2; // коэффициент заполнения 50%
   TIM10->CCER &= ~TIM_CCER_CC1P;
   TIM10->CCER |= TIM_CCER_CC1E; //   активировать выход OC1
   TIM10->EGR = TIM_EGR_UG;

   TIM10->CR1|= TIM_CR1_CEN; // Запуск таймера
}

Re: Настройка скважности ШИМ в STM32F103

Чт май 26, 2022 21:17:16

Всё заработало на другом таймере

Re: Настройка скважности ШИМ в STM32F103

Сб май 28, 2022 07:06:10

Спасибо, но непонятно: куда именно внедрять этот код и как быть с параметрами таймера в Cube?

Код:
SystemCoreClockUpdate();


найдена аж в system_stm32f10x.c, т.е. править этот файл?

Нет. Этот файл обычно компилируется совместно с проектом. Сам.
Добавлено after 1 hour 41 minute 28 seconds:
1. 57.14/6268 = 0.91 = 91%. Хотя и не совпадает с ожидаемыми 400/500



Откуда Вы взяли число 6268?

Пардон, опечатался. Должно быть 62,68. А взял из вашего скриншота логического анализатора. Вы не на ту строку смотрели.
Ответить