Например TDA7294

Форум РадиоКот • Просмотр темы - STM32F100 ШИМ 5кГц с постоянно меняющейся скважностью
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Чт апр 18, 2024 21:20:15

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: STM32F100 ШИМ 5кГц с постоянно меняющейся скважностью
СообщениеДобавлено: Чт апр 18, 2019 17:11:15 
Родился

Зарегистрирован: Ср дек 16, 2015 22:58:13
Сообщений: 10
Рейтинг сообщения: 0
Всем привет!

Пытаюсь выжать аппаратно ШИМ сигнал из STM32F100C8T6, частота 4800Гц, фишка в том что скважность меняется каждый такт, импульсы повторяются в таком порядке: 30%, 70%, 95%, 95%, 70%, 30%, это значения скважности в %.
Использую TIM1 и каналы 2й и 4й, это ноги РА9 и РА11.
Скважность меняю в прерывании по сравнению, регистр таймера и регистр сравнения буферизованы, то есть их значения меняются после Update Event, который происходит после переполнения таймера.
На частоте 400Гц или чуть больше всё получается, но при увеличении частоты что-то ломается и пара импульсов идет не с той скважностью, причём у каждого канала это своя пара, но порядок чёткий и не меняется например при увеличении частоты на порядок.

Добавлено after 2 minutes 23 seconds:
Мне кажется проблема в аппаратных возможностях F100, поправьте если ошибаюсь :)

Код инициализации и обработчика прерывания:

Спойлер
Код:
void GPIO_init(void)
{
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
   GPIO_InitTypeDef temp_GPIO_Init;
   
   //PWM
   temp_GPIO_Init.GPIO_Pin = PH1sig|PH2sig;
   temp_GPIO_Init.GPIO_Speed = GPIO_Speed_10MHz;
   temp_GPIO_Init.GPIO_Mode = GPIO_Mode_AF_PP;
   GPIO_Init(GPIOA, &temp_GPIO_Init);
}

void PWM_init(void)
{
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

      TIM1->CCMR1  = 0x0000;
      TIM1->CR1     = 0x0000;
      TIM1->CCER   = 0x0000;
      TIM1->DIER   = 0x0000;
      TIM1->BDTR   = 0x0000;
      TIM1->CCMR1 |= 0x6000;         //PWM1 mode CH2
      TIM1->CCMR2 |= 0x6000;         //PWM1 mode CH4
      TIM1->ARR = 20000;
      TIM1->CCR2   = 1000;   
      TIM1->CCR4   = 1000;   
      //TIM1->PSC    = 0x0009;
      TIM1->CCMR1 |= 0x0800;         //OC2 preload enable
      TIM1->CCMR2 |= 0x0800;         //OC4 preload enable
      TIM1->CR1    |= 0x0080;         //ARR preload enable
      TIM1->CCER  |= 0x0010;         //CC2E = 1
      TIM1->CCER  |= 0x1000;         //CC4E = 1
      TIM1->BDTR  |= 0x8000;         //MOE = 1
      TIM1->EGR   |= 0x0001;         //generate update event
      TIM1->CR1   |= 0x0001;         //counter enable
     
      TIM1->DIER  |= 0x0004;         //compare CH2 interrupt enable
      NVIC_EnableIRQ(TIM1_CC_IRQn);
      __enable_irq();     //вроде не нужно, на всякий случай
     
}

#define         PULSE_A         30
#define         PULSE_B         70
#define         PULSE_C         95

void TIM1_CC_IRQHandler(void)
{
      TIM1->SR &= 0xFFE0;            //5 flags reset
   
      period  = (float)TIM1->ARR;
   
      switch(pulse)
      {
         case 1:
            TIM1->CCR2 = (period/100)*PULSE_A;
            TIM1->CCR4 = (period/100)*PULSE_C;
            pulse += 1;
            break;
         case 2:
            TIM1->CCR2 = (period/100)*PULSE_B;
            TIM1->CCR4 = (period/100)*PULSE_B;
            pulse += 1;
            break;
         case 3:
            TIM1->CCR2 = (period/100)*PULSE_C;
            TIM1->CCR4 = (period/100)*PULSE_A;
            pulse += 1;
            break;
         case 4:
            TIM1->CCR2 = (period/100)*PULSE_C;
            pulse += 1;
            break;
         case 5:
            TIM1->CCR2 = (period/100)*PULSE_B;
            TIM1->CCR4 = (period/100)*PULSE_B;
            pulse += 1;
            break;
         case 6:
            TIM1->CCR2 = (period/100)*PULSE_A;
            TIM1->CCR4 = (period/100)*PULSE_C;
            pulse += 1;
            break;
         case 7:
            TIM1->CCR2 = (period/100)*PULSE_A;
            pulse += 1;
            break;
         case 8:
            TIM1->CCR2 = (period/100)*PULSE_B;
            TIM1->CCR4 = (period/100)*PULSE_B;
            pulse += 1;
            break;
         case 9:
            TIM1->CCR2 = (period/100)*PULSE_C;
            TIM1->CCR4 = (period/100)*PULSE_A;
            pulse += 1;
            break;
         case 10:
            TIM1->CCR2 = (period/100)*PULSE_C;
            pulse += 1;
            break;
         case 11:
            TIM1->CCR2 = (period/100)*PULSE_B;
            TIM1->CCR4 = (period/100)*PULSE_B;
            pulse += 1;
            break;
         case 12:
            TIM1->CCR2 = (period/100)*PULSE_A;
            TIM1->CCR4 = (period/100)*PULSE_C;
            pulse = 1;
            break;
         default:
            break;
      }
   
}


Добавлено after 4 hours 51 minute 7 seconds:
В общем проблема была из-за использования float в прерывании.


Вложения:
Комментарий к файлу: 4800Гц - сигнал портится
4800.PNG [18.14 KiB]
Скачиваний: 305
Комментарий к файлу: 400Гц - нормальный сигнал
400.PNG [10.27 KiB]
Скачиваний: 325


Последний раз редактировалось Millyvolt Чт апр 18, 2019 20:58:10, всего редактировалось 1 раз.
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: F100 ШИМ 5кГц с постоянно меняющейся скважностью
СообщениеДобавлено: Чт апр 18, 2019 20:16:16 
Друг Кота
Аватар пользователя

Карма: 1
Рейтинг сообщений: 157
Зарегистрирован: Пн окт 11, 2010 19:00:08
Сообщений: 3328
Рейтинг сообщения: 0
Судя по описанию и коду, можно заранее вычислить значения для регистров сравнения и загружать их через DMA.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: F100 ШИМ 5кГц с постоянно меняющейся скважностью
СообщениеДобавлено: Чт апр 18, 2019 20:56:59 
Родился

Зарегистрирован: Ср дек 16, 2015 22:58:13
Сообщений: 10
Рейтинг сообщения: 0
Судя по описанию и коду, можно заранее вычислить значения для регистров сравнения и загружать их через DMA.


Через DMA и надо, но это сигнал для двигателя и у него должен быть разгон в течение нескольких секунд, и тут как быть? :)


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 3 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 17


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y