Перейти к содержанию
    

MPetrovich

Свой
  • Постов

    803
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные MPetrovich


  1. Выставил постоянный Duty Cycle и на оба прерывания ISR(TIMER1_OVF_vect) и ISR(TIMER1_COMPA_vect) вставил такие импульсы. Получилась картинка: один луч - выход ОС1А, второй - бит 0 порта Е. На первом луче собственно ШИМ, на втором импульс после входа в первое прерывание + импульс входа во второе прерывание.

    Итог меня расстроил. Импульсы сдвинуты от начала и от конца Duty Cycle на одну и ту же величину - примерно на 2,4мкСек. Неужели столько времени требуется для вызова прерывания в ATMega128?

     

    IMG_20230807_152210.jpg

  2. On 8/4/2023 at 2:36 PM, Сергей Борщ said:

    для частоты, отличной от 1 МГц нужно вручную подстраивать записью константы (которую надо сначала вычитать программатором из сигнатуры) в регистр OSCCAL

    Попробовал подстроить частоту, получилось только ещё большее расхождение. Да наплевать, в конце концов. Частотник ставят чтобы изменять частоту вращения асинхронника и точность установки частоты, скажем для насоса, вообще по барабану. Главное, что обеспечит для мотора частотник - это плавный старт от нуля оборотов и, соответственно плавное нарастание момента.

    У меня в другом затыка возникла. Мне нужно dead-time обеспечить между верхним и нижним ключом. Я попытался организовать его в прерывании Timer/Counter1 Output Compare A Match Interrupt. По сути, это прерывание в момент окончания PWM Duty Cycle. Я взял и засунул в это прерывание задержку 1мкСек. Но отчего то эта задержка отсутствует при генерации ШИМ. :russian_ru:

    Хотя если просто дёргать порт

    ISR(TIMER1_COMPA_vect)//Output Compare A (PWM_OFF)interrupt
    {
    	PORTE=1;
        _delay_us(1);
        PORTE=0;
    }

    то нормально всё срабатывает - есть импульс примерно 1мкСек.

  3. On 8/4/2023 at 2:36 PM, Сергей Борщ said:

    Я тут подумал, может для таблицы в 36 значений вычислить другой размер фазового аккумулятора? Скажем такой: 36*1024=36864:russian_ru:

     

    On 8/4/2023 at 2:36 PM, Сергей Борщ said:

    Что-то делаете неправильно. Показывайте код.

    ISR(TIMER1_OVF_vect)//PWM_ON interrupt
    {
     if(!(TIFR & (1<<TOV1)))
       {
        TIFR |= (1<<TOV1);//clear TIM1 Overflow flag
        
       num = akk/(36864/36);//for 36-num 
       //num = akk/(65536/32);//2048 for 32-num table
    
       if((OCR1A - 127) <= 255) {PORTA &= ~1; }//PWM is ON, LOW key is OFF
       else { PORTA |= 1;}//PWM is OFF, LOW key is ON
       OCR1A = PH1H[num];  //ШИМ 1  
       if((OCR1B - 127) <= 255) {PORTA &= ~2; /*TCCR1A |= (1<<5);*/}
       else { PORTA |= 2;}
       OCR1B = PH2H[num];  //ШИМ 2  
       if((OCR1C - 127) <= 255) {PORTA &= ~4; /*TCCR1A |= (1<<3);*/}
       else { PORTA |= 4;}
       OCR1C = PH3H[num];  //ШИМ 3
    
       akk += akk_shift;
       }   
    }

    Вот так выглядят две фазы.

    osc.jpg

    Но если в строчке

    num = akk/(36864/36);

    36 заменить на 18, то всё становится всё ОК.

  4. 14 minutes ago, Oleg.normalniy said:

    в нижние ключи я закидываю максимальное число на весь период и получаю BLDC период

     

    Нижние ключи у Вас открыты всего полпериода. Я имею в виду алгоритм на 180гр. Я на нем остановил свой выбор.

    В принципе, я уже накидал прогу. Теперь только "доработать напильником" немножко осталось и с индикацией разобраться.

  5. 1 hour ago, Сергей Борщ said:

    Кстати, а один период ШИМ сколько получается по вашему осциллографу?

    Частоту ШИМ я померил сначала на осциллографе, а уж потом подсчитал в цифрах через тактовую частоту))) Так что точно меряет осциллограф, главное картинку развернуть пошире. Ну, на глаз погрешность процентов до трёх-пяти примерно...

  6. 42 minutes ago, MPetrovich said:

    65536? Это как раз длина таблицы *2^N, где N - количество разрядов дробной части фазового аккумулятора.

    Я тут подумал, может для таблицы в 36 значений вычислить другой размер фазового аккумулятора? Скажем такой: 36*1024=36864:russian_ru:

    Да! Это работает! Только надо аккумулятор во такой сделать: 36*2048=73728 И длина таблицы тогда не влияет на частоту, при одинаковом шаге получается одинаковая частота.

  7. 1 hour ago, Сергей Борщ said:

    Так это в железе определено настройками таймера. Программирование здесь ни при чём. Или вместо 31250 Вы предлагаете определить:

      #define F_PWM   31250  ?

     

    1 hour ago, Сергей Борщ said:

    Ну это не показатель. У меня на работе agilent тоже частоту криво считает, даже при большом усреднении.

    Я на осциллографе ПЕРИОД измеряю. Он поверенный, развёртка точная. Частоту я вижу на экране, но это результат 1/Т.

     

    1 hour ago, Сергей Борщ said:

    Как не участвует? А 65536? Это как раз длина таблицы *2^N, где N - количество разрядов дробной части фазового аккумулятора.

    Длина таблицы 32 или 36. Я так понимаю, что чем длиннее таблица, тем меньше раз повторяется каждое значение при одинаковом шаге аккумулятора. По формуле подсчёта частоты выходит, что длина таблицы на частоту не влияет. Но так ли это я не уверен...

  8. 9 hours ago, Сергей Борщ said:

    У вас же вроде бы получалось около 0.47 Гц на единицу приращения аккумулятора фазы?

    Да, так и получается.

     

    9 hours ago, Сергей Борщ said:

    "магическое число" 31250 тоже заставляет напрягаться. Вот честно-честно - лень думать, откуда оно взялось, приходится верить вам на слово.

    Fcpu=8Mhz; PWM = 8-bit; Fpwm=8000000/2^8=31250Hz. Никакой магии)

     

    9 hours ago, Сергей Борщ said:

    Ну-ка показывайте, как вы частоту считаете. У меня получается с вашими исходными данными для 50 Гц akk_shift = 106, akk_shift * 31250 / 65536 = 50.5447387, т.е. при вычислении в целых должно получиться 50 ровно.

    Так и считаю. Но измеренный на осциллографе курсорами период даёт частоту на 2Гц больше при  akk_shift = 106.

    Да бог с ней, с индикацией. Меня больше всего волнует сейчас вопрос как связать длину таблицы с выходной частотой. В формуле подсчёта частоты длина таблицы вообще не участвует, но на практике при таблице в 36 значений частота уменьшается в 1,67 раза. Откуда это берётся я не могу понять.

  9. 24 minutes ago, Сергей Борщ said:

    Ошибка всегда "в минус"?

    Нет, "в плюс".

     

    25 minutes ago, Сергей Борщ said:

    На большой частоте эта точка таблицы может быть пропущена даже в очень большой таблице.

    Каким образом N-е значение таблицы может быть пропущено? Аккумулятор же перебирает их подряд, а шаг всегда на пару-тройку порядков  меньше аккумулятора. Так что даже при большой частоте все значения таблицы будут по нескольку раз подряд выбраны в прерывании.

  10. Кстати, хотел заметить, что кратное двум количество значений в таблице для ШИМ даёт неприятный побочный эффект - при прямом подсчёте и выводе на индикацию частоты синуса display = (((uint32_t)akk_shift) * 31250)/65536; набегает ошибка примерно в 2Гц на 50ГЦ. И происходит это похоже из-за "некруглости" таблицы.

    То же самое, я думаю, будет наблюдаться и при переключении ключей по фазам. В обоих вариантах коммутации - при сдвиге на 180гр и на 120гр - надо иметь чёткое попадание в точки на синусе, соответствующие 30*N = (Пи/6)*N градусов .

  11. 24 minutes ago, Сергей Борщ said:

    Но на один из них подается ШИМ синуса.

    Да, в схеме управления, которую я пытаюсь реализовать, ШИМ подаётся только на верхние ключи фаз.

    Я мысль вроде ухватил. Только вот мне кажется для схемы со сдвигом на 180гр. надо старший бит синуса использовать.  Тогда можно для нижнего ключа делать if(PWM1 & 0x80)LOW_KEY1 =1; 

    Ну и для остальных фаз так же.

  12. 1 hour ago, Сергей Борщ said:

    А просто анализировать значение фазы

    Так я это и делаю, только через значение синуса.

    1 hour ago, Сергей Борщ said:

     сделать второй массив с состояниями нижних ключей, из которого выбирать используя тот же самый фазовый

    А вот это отчего то не пришло в голову... Действительно просто. Спасибо за очередную подсказку!

     

    1 hour ago, Сергей Борщ said:

    Или забить на младший бит синуса и вместо него хранить состояние нижнего ключа (у вас ведь по одному ключу на каждый выход синуса)?

    На каждую фазу по два ключа - к плюсу и к земле.

  13. Не смог пока придумать приемлемый вариант переключения ШИМ-синуса между верхними и нижними ключами. Реализовал на данный момент такой  вариант: отслеживаю значения синуса и при значении, совпадающим с нужной фазой, переключаюсь. Устраивает в этом методе то, что есть dead-time между выключением верхнего и включением нижнего ключа (и наоборот). Не устраивает то, что всё это делается в прерывании формирования ШИМ и длительность прерывания сильно увеличивается (но, как ни странно, ШИМ по-прежнему формируется нормально).

  14. После преодоления этапа получения синуса через DDS возникла проблема с тем, какая часть этого синуса используется. Судя по коммутационным диаграммам (с замыканием нижних ключей в фазах на землю без ШИМ), используется только половина периода от 0 до 180гр. 

    image.thumb.png.25494a63a2fd1dac0fa1690bb754bcb6.png

    Вот картинка по сигналам на входах драйверов ключей

    гибрид.png

    нечётные - верхние ключи, чётные - нижние.

  15. 3 minutes ago, Сергей Борщ said:

    Тогда надо не синус в таблицу заносить, а вот такой хитрый сигнал (нарисован черным):

    Да, я в курсе. только пока не разобрался как получить эту кракозябру. Преобразованием Фурье не очень хочется заморачиваться)))

  16. 3 minutes ago, Сергей Борщ said:

    Кстати, компилятор умеет вычислять константные выражения на этапе компиляции, поэтому не стоило здесь выносить само выражение в комментарий.

    Я об этом не знал. Благодарю за подсказку.

     

    4 minutes ago, Сергей Борщ said:

    перепишите эту строку от греха подальше в 

    num = akk / (65536 / 32);

    Ок. Переписал)

    Кстати сказать, ни объём данных, ни объём программы не изменились после компиляции...

  17. 8 minutes ago, Сергей Борщ said:

    Можете еще попробовать использовать режим не простого ШИМ, а phase and frequency correct PWM.

    А в чём выгода? Каким образом этот режим ШИМ уменьшит вторую гармонику синуса?

    Мне бы надо третью гармонику прикрутить к синусу, чтобы динамический диапазон по амплитуде на обмотках поднять.

  18. Just now, Сергей Борщ said:

    Все у вас правильно

    Урааа!!! :dance3:

    Спасибо Вам огромное! Особенно за  ангельское терпение в общении с таким тугим собеседником, как я)))

    Это первый DDS, который я написал)

  19. 21 minutes ago, Сергей Борщ said:

    Константа считается один раз, а деление 100x/константа контроллер должен будет выполнять на каждом проходе.

    Я переписал таблицу на 32 значения. Здесь я полностью с Вами согласен)

    22 minutes ago, Сергей Борщ said:

    допустим, прошло 1000000000 циклов приращения фазы. Даже не выполняя вычислений понятно, что результат вашего деления будет во много раз больше размера таблицы. Не говоря уже о том, что для хранения x потребуется переменная бесконечного размера

    Вы меня окончательно сбили с толку. Если не затруднит, напишите пожалуйста как должна выглядеть формула подсчёта номера в таблице значений синуса.

     

    P.S. Я уже получил на выходе МК три фазы и меняю их частоту от 0Гц до 465Гц. Однако, хочется разобраться до конца.

    вот код прерывания, в котором вычисляется номер значения в таблице и подставляются в фазы синусоид:

    ISR(TIMER1_OVF_vect)//PWM_ON interrupt
    {
     if(!(TIFR & (1<<TOV1)))
       {
        TIFR |= (1<<TOV1);//clear TIM1 Overflow flag
    
       OCR1A = PWM1[num];  //ШИМ 1
       OCR1B = PWM2[num];  //ШИМ 2
       OCR1C = PWM3[num];  //ШИМ 3 
       num = akk/2048;//65536/32=2048
       akk += akk_shift;
       }   
    }

     

×
×
  • Создать...