ШИМ
Модераторы: ea, dav, bkolbov, Alis, pip, _sva_
ШИМ
Здравствуйте!
Столкнулся с непонятной ситуацией, помогите пожалуйста разрешить.
Процессор затактирован на 96 МГц. Тактирующий сигнал на ШИМ без делителя, счетчик вверх-вниз по основанию 2000 (96 МГц / 4000 = 24 КГц). Работаю с ШИМ. Включены все 9 блоков. Аппаратная синхронизация (работает, проверено). Комплиментарный режим, мертвое время 120 тиков камня (119 + 1 в соответствии с errata).
Два прерывания:
1) Для PWM0 по событию CTR=PRD (NT_PWM0->ETSEL_bit.INTSEL = 2)
2) Для PWM1 по событию CTR=ZERO (NT_PWM1->ETSEL_bit.INTSEL = 1)
Включена отложенная загрузка из теневого регистра для всех ШИМ:
NT_PWM8->CMPCTL_bit.LOADAMODE = 0;
NT_PWM8->CMPCTL_bit.SHDWAMODE = 0;
Ниже диаграмма иллюстрирует происходящее (нарисовал треугольник - счетчик для лучшего понимания):
На максимальном значении счетчика вырабатывается прерывание (1).
В обработчике (1) принимается решение (2) изменить значение скважности с 0 до 100% (запись в NT_PWM8->CMPA_bit.CMPA и установка флага на запуск для следующего прерывания) и разрешить работу ШИМ (до этого запрещена работа через Trip Zone, выводы подтянуты в высокий уровень).
Далее вырабатывается прерывание (3) по события VTR=ZERO в котором смотрим флаг от предыдущего прерывания (1) и разрешаем работу ШИМ (NT_PWM8->TZCLR_bit.OST = 1). ШИМ включается сразу же и уже здесь я ожидал, что регистр CMPA перезапишется из теневого по событию CTR=ZERO, но этого не происходит. ШИМ включается (4), но на старом значении скважности, а перезапись из теневого происходит (6) только при следующем событии CTR=PRD (5)
При этом изменение значений регистра CMPCTL на любое значение вообще не приводит ни к какому эффекту! Как бы я не настроил этот регистр - картина вообще не меняется.
Подскажите, что я делаю не так? Почему перезапись CMPA из теневого регистра происходит не при том событии?
Столкнулся с непонятной ситуацией, помогите пожалуйста разрешить.
Процессор затактирован на 96 МГц. Тактирующий сигнал на ШИМ без делителя, счетчик вверх-вниз по основанию 2000 (96 МГц / 4000 = 24 КГц). Работаю с ШИМ. Включены все 9 блоков. Аппаратная синхронизация (работает, проверено). Комплиментарный режим, мертвое время 120 тиков камня (119 + 1 в соответствии с errata).
Два прерывания:
1) Для PWM0 по событию CTR=PRD (NT_PWM0->ETSEL_bit.INTSEL = 2)
2) Для PWM1 по событию CTR=ZERO (NT_PWM1->ETSEL_bit.INTSEL = 1)
Включена отложенная загрузка из теневого регистра для всех ШИМ:
NT_PWM8->CMPCTL_bit.LOADAMODE = 0;
NT_PWM8->CMPCTL_bit.SHDWAMODE = 0;
Ниже диаграмма иллюстрирует происходящее (нарисовал треугольник - счетчик для лучшего понимания):
На максимальном значении счетчика вырабатывается прерывание (1).
В обработчике (1) принимается решение (2) изменить значение скважности с 0 до 100% (запись в NT_PWM8->CMPA_bit.CMPA и установка флага на запуск для следующего прерывания) и разрешить работу ШИМ (до этого запрещена работа через Trip Zone, выводы подтянуты в высокий уровень).
Далее вырабатывается прерывание (3) по события VTR=ZERO в котором смотрим флаг от предыдущего прерывания (1) и разрешаем работу ШИМ (NT_PWM8->TZCLR_bit.OST = 1). ШИМ включается сразу же и уже здесь я ожидал, что регистр CMPA перезапишется из теневого по событию CTR=ZERO, но этого не происходит. ШИМ включается (4), но на старом значении скважности, а перезапись из теневого происходит (6) только при следующем событии CTR=PRD (5)
При этом изменение значений регистра CMPCTL на любое значение вообще не приводит ни к какому эффекту! Как бы я не настроил этот регистр - картина вообще не меняется.
Подскажите, что я делаю не так? Почему перезапись CMPA из теневого регистра происходит не при том событии?
Re: ШИМ
Забыл указать среду разработки - Vector IDE
- Лашкевич
- Сообщения: 372
- Зарегистрирован: 13 май 2015, 13:10
- Предприятие: ООО "НПФ Вектор"
- Откуда: Москва
- Контактная информация:
Re: ШИМ
Тонкий эксперимент описан. Пока непонятно. Хочу спросить про уточнения:
Вы пишете, что в обработчике 1 вы делаете
Вы пишете, что в обработчике 1 вы делаете
При этом в обработчике 3 вы делаете как бы тоже самоеразрешить работу ШИМ (до этого запрещена работа через Trip Zone, выводы подтянуты в высокий уровень).
Можете привести чуть больше кода, выборочно, что именно делается там и сям и заодно инициализацию? LOADAMODE и SHDWAMODE настраиваются заранее в инициализации или прямо в прерывании?NT_PWM8->TZCLR_bit.OST = 1
Re: ШИМ
Я делаю программный отложенный запуск ШИМ. В обработчике (1) я только принимаю решение о необходимости запуска (или останова) и выставляю соответствующий программный флаг (переменная). В обработчике (3) этот флаг читается и именно там (и только там) делается NT_PWM8->TZFRC_bit.OST = 1 для остановки или NT_PWM8->TZCLR_bit.OST = 1 для запуска ШИМ. Это делается для того, чтобы включать ШИМ в начале периода счетчика, когда значение скважности из теневого регистра уже перезагрузится. Чтобы как раз избежать ШИМ на старом значении скважности до перезаписи.
Все ШИМ у меня настроены одинаково. Код настройки ног, тактирования и т.д. я опущу для компактности.
Настройка ШИМ контроллера:
Настройка прерываний:
Обработчик (1):
Обработчик (3):
Моя проблема заключается в том, что перезагрузка из теневых регистров CMPA и CMPB происходит не при событииCTR=ZERO, а при событии CTR=PRD. И значение регистров LOADAMODE и SHDWAMODE никак не влияют на происходящее, хотя должны!
Все ШИМ у меня настроены одинаково. Код настройки ног, тактирования и т.д. я опущу для компактности.
Настройка ШИМ контроллера:
Код: Выделить всё
// Настройка синхронизации блоков - последовательное включение
NT_COMMON_REG->PWM_CTRL_bit.SYNCSELECT = 0;
// *** PWM0 ***
// Режим работы
NT_PWM0->TBCTL_bit.PRDLD = 0; // Отложенная загрузка
NT_PWM0->TBCTL_bit.CTRMODE = 2; // Режим работы счетчика вверх-вниз
NT_PWM0->TBCTL_bit.PHSEN = 1; // Загрузка фазы запрещена
NT_PWM0->TBCTL_bit.PHSDIR = 1; // Фазовое направление - вверх
NT_PWM0->TBCTL_bit.CLKDIV = 0; // Первый делитель тактовой частоты
NT_PWM0->TBCTL_bit.HSPCLKDIV = 0; // Второй делитель тактовой частоты
NT_PWM0->TBCTL_bit.SYNCOSEL = 1; // Выдаем тактовый сигнал при CTR=0
// Настройка компараторов
NT_PWM0->CMPCTL_bit.SHDWAMODE = 0; // Отложенная загрузка значений
NT_PWM0->CMPCTL_bit.SHDWBMODE = 0; // CMPA и CMPB через теневой регистр
NT_PWM0->CMPCTL_bit.LOADAMODE = 0; // Загрузка CMPA при CTR=Zero
NT_PWM0->CMPCTL_bit.LOADBMODE = 0; // Загрузка CMPB при CTR=Zero
NT_PWM0->CMPA_bit.CMPA = 0;
// Действия при событиях
// 01b - переключение в 0; 10b - переключение в 1
NT_PWM0->AQCTLA = 0; // Сначала очищаем
NT_PWM0->AQCTLB = 0;
NT_PWM0->AQCTLA_bit.CAU = 2; // Группа A на фронте
NT_PWM0->AQCTLA_bit.CAD = 1; // Группа A на спаде
NT_PWM0->AQCTLB_bit.CAU = 2; // Группа B на фронте
NT_PWM0->AQCTLB_bit.CAD = 1; // Группа B на спаде
Код: Выделить всё
// Прерывание по вершине счетчика
NT_PWM0->ETSEL_bit.INTSEL = 2; // Прерывание по события CTR=PRD
NT_PWM0->ETSEL_bit.INTEN = 1; // Разрешить прерывание
// Запуск секвенсоров по вершине счетчика
NT_PWM0->ETSEL_bit.SOCASEL = 2; // Запуск секвенсоров при CTR=PRD
NT_PWM0->ETSEL_bit.SOCAEN = 1; // Разрешить запуск секвенсоров
NT_PWM0->ETSEL_bit.SOCBSEL = 2; // Запуск секвенсоров при CTR=PRD
NT_PWM0->ETSEL_bit.SOCBEN = 1; // Разрешить запуск секвенсоров
// Прерывание прир пересечении счетчиком НУЛЯ
NT_PWM1->ETSEL_bit.INTSEL = 1; // Прерывание по события CTR=ZERO
NT_PWM1->ETSEL_bit.INTEN = 1; // Разрешить прерывание
Код: Выделить всё
void EPWM_0_IRQHandler(void)
{
WD_RESET;
if(dbgDutyCounter == 1)
{
NT_PWM8->CMPA_bit.CMPA = 0; // Минимальная скважности
pwmFan.enableA = TRUE;
}
else if(dbgDutyCounter == 100)
{
pwmFan.enableA = FALSE;
}
else if(dbgDutyCounter == 200)
{
NT_PWM8->CMPA_bit.CMPA = 2000; // Максимальная скважности
pwmFan.enableA = TRUE;
}
else if(dbgDutyCounter == 300)
{
pwmFan.enableA = FALSE;
}
else if(dbgDutyCounter >= 400)
{
dbgDutyCounter = 0;
}
dbgDutyCounter++;
NT_PWM0->ETCLR_bit.INT = 1;
NT_PWM0->ETCLR_bit.SOCA = 1;
NT_PWM0->ETCLR_bit.SOCB = 1;
NT_PWM0->INTCLR_bit.INT = 1;
Энвик_ClearPendingIRQ(PWM0_IRQn);
}
Код: Выделить всё
#define PWM6_ENABLE NT_PWM6->TZCLR_bit.OST = 1
#define PWM7_ENABLE NT_PWM7->TZCLR_bit.OST = 1
#define PWM8_ENABLE NT_PWM8->TZCLR_bit.OST = 1
#define PWM6_DISABLE NT_PWM6->TZFRC_bit.OST = 1
#define PWM7_DISABLE NT_PWM7->TZFRC_bit.OST = 1
#define PWM8_DISABLE NT_PWM8->TZFRC_bit.OST = 1
void EPWM_1_IRQHandler(void)
{
// Фаза C
if(pwmFan.enableC) PWM6_ENABLE;
else PWM6_DISABLE;
// Фаза B
if(pwmFan.enableB) PWM7_ENABLE;
else PWM7_DISABLE;
// Фаза A
if(pwmFan.enableA) PWM8_ENABLE;
else PWM8_DISABLE;
Энвик_ClearPendingIRQ(PWM1_IRQn);
NT_PWM1->ETCLR_bit.INT = 1;
NT_PWM1->INTCLR_bit.INT = 1;
}
- Лашкевич
- Сообщения: 372
- Зарегистрирован: 13 май 2015, 13:10
- Предприятие: ООО "НПФ Вектор"
- Откуда: Москва
- Контактная информация:
Re: ШИМ
Я пока не почитал ваш код, но поэкспериментировал с софтом MotorControlDemo с битбакета и поснимал им осцы для проверки работы SHDWAMODE и LOADAMODE. С виду все работает. Я поставил частоту ШИМ 1кГц и снимал в осциллограмму данные на частоте 10кГц. Получил вот такой график для загрузки по нулю:
здесь голубой это счетчик таймера ШИМ, осциллографированный непосредственно как Debug1=NT_PWM0->TBCTR;
фиолетовый синус - это формируемое и присваиваемое на каждом периоде на 10кГц задание в уставку сравнения NT_PWM0->CMPA_bit.CMPA = (Uint16) p->GammaA;
Синий - это прочитываемое из регистра уставки сравнения значение: Debug3= NT_PWM0->CMPA_bit.CMPA;
а красный - значение ножки ШИМ, считанное прямо с GPIO как Debug2=(NT_GPIOG->DATA>>2)&1;
Как видно по синему графику, скважность из теневого регистра попадает в уставку сравнения как и нужно по нулю, и верно воспроизводится.
Далее тоже самое для загрузки по периоду:
Для нуля и периода:
И с отключенным теневым регистром:
здесь голубой это счетчик таймера ШИМ, осциллографированный непосредственно как Debug1=NT_PWM0->TBCTR;
фиолетовый синус - это формируемое и присваиваемое на каждом периоде на 10кГц задание в уставку сравнения NT_PWM0->CMPA_bit.CMPA = (Uint16) p->GammaA;
Синий - это прочитываемое из регистра уставки сравнения значение: Debug3= NT_PWM0->CMPA_bit.CMPA;
а красный - значение ножки ШИМ, считанное прямо с GPIO как Debug2=(NT_GPIOG->DATA>>2)&1;
Как видно по синему графику, скважность из теневого регистра попадает в уставку сравнения как и нужно по нулю, и верно воспроизводится.
Далее тоже самое для загрузки по периоду:
Для нуля и периода:
И с отключенным теневым регистром:
- Лашкевич
- Сообщения: 372
- Зарегистрирован: 13 май 2015, 13:10
- Предприятие: ООО "НПФ Вектор"
- Откуда: Москва
- Контактная информация:
Re: ШИМ
Попробуйте повторить мой эксперимент - запустите ШИМ на постоянную работу без всяких пусков/остановов, меняйте быстро скважность, раз 5 за один период ШИМ, и смотрите, как меняется результат в зависимости от конфигурирования регистров LOADAMODE и SHDWAMODE. В зависимости от результата эксперимента можно будет думать дальше.
Re: ШИМ
Проделал опыт. Дело, похоже, действительно не в этом.Лашкевич писал(а): ↑19 июн 2017, 13:44 Попробуйте повторить мой эксперимент - запустите ШИМ на постоянную работу без всяких пусков/остановов, меняйте быстро скважность, раз 5 за один период ШИМ, и смотрите, как меняется результат в зависимости от конфигурирования регистров LOADAMODE и SHDWAMODE. В зависимости от результата эксперимента можно будет думать дальше.
Если не останавливать и запускать ШИМ-контроллер механизмом Trip Zone, то перезапись из теневого регистра в CMPA происходит в верный момент времени.
Все выглядит так, будто бы при активном сигнале аварии не осуществляется перезапись CMPA из теневого регистра в момент CTR=ZERO. Перезапись происходит в момент CTR=PRD.
В прерывании по событию CTR=ZERO я снимаю сигнал аварии, но на момент CTR=ZERO он еще был активен и перезапись из теневого регистра в CMPA не выполнилась, а ШИМ заработал на старом значении. Это мое предположение. Такого (блокировка перезаписи CMPA из теневого регистра), насколько я понимаю, быть не должно. Думаю капать надо в этом направлении.
Re: ШИМ
Хотя нет, проверил, немного иначе все. Перезапись осуществляется, но не в момент CTR=ZERO, а в момент CTR=PRD.MR.Smith писал(а): ↑19 июн 2017, 17:05 В прерывании по событию CTR=ZERO я снимаю сигнал аварии, но на момент CTR=ZERO он еще был активен и перезапись из теневого регистра в CMPA не выполнилась, а ШИМ заработал на старом значении. Это мое предположение. Такого (блокировка перезаписи CMPA из теневого регистра), насколько я понимаю, быть не должно. Думаю капать надо в этом направлении.
После запуска ШИМ продолжается со старым значением некоторое время. Но только на первой итерации после запуска.
Re: ШИМ
Добрый день!
Когда вы говорите, что CMPA обновился/не обновился - это значит что в прерывании вы его вычитываете и видите, что он обновляется не в (3), а в (5), верно?
Есть предположение, что наблюдаются проблемы с синхронизацией счетчиков ШИМ. Они у вас точно все работают синхронно? Не может ли быть работы в противофазе, т.е. когда в PWM1 - CTR=ZERO (3), то в PWM8 в этот момент CTR=PRD, а PWM8 CTR=ZERO наступает соответсвенно когда PWM1 CTR=PRD (5)?
Каким образом вы включаете предделители ШИМ (поле TBCLKSYNC регистра PWM_SYNC регистров общего назначения)?
До настройки всех ШИМ или после? По хорошему, запись должна быть одна, вида NT_COMMON_REG->PWM_SYNC=0xFFFFFFFF, и идти лишь после настройки всех ШИМ.
Механизм TZ никак не влияет на теневую перезагрузку, однозначно. Здесь наблюдаются некоторые другие эффекты, причину которых нужно выяснить.Если не останавливать и запускать ШИМ-контроллер механизмом Trip Zone, то перезапись из теневого регистра в CMPA происходит в верный момент времени.
Когда вы говорите, что CMPA обновился/не обновился - это значит что в прерывании вы его вычитываете и видите, что он обновляется не в (3), а в (5), верно?
Есть предположение, что наблюдаются проблемы с синхронизацией счетчиков ШИМ. Они у вас точно все работают синхронно? Не может ли быть работы в противофазе, т.е. когда в PWM1 - CTR=ZERO (3), то в PWM8 в этот момент CTR=PRD, а PWM8 CTR=ZERO наступает соответсвенно когда PWM1 CTR=PRD (5)?
Каким образом вы включаете предделители ШИМ (поле TBCLKSYNC регистра PWM_SYNC регистров общего назначения)?
До настройки всех ШИМ или после? По хорошему, запись должна быть одна, вида NT_COMMON_REG->PWM_SYNC=0xFFFFFFFF, и идти лишь после настройки всех ШИМ.
Что вы понимаете под первой итерацией после запуска? Момент после включения мк, когда ШИМы только настроились и начали работать?Хотя нет, проверил, немного иначе все. Перезапись осуществляется, но не в момент CTR=ZERO, а в момент CTR=PRD.
После запуска ШИМ продолжается со старым значением некоторое время. Но только на первой итерации после запуска.
Re: ШИМ
Богдан, здравствуйте!
Пока я временно вышел из ситуации путем переноса кода разрешения работы (NT_PWM8->TZCLR_bit.OST = 1) ШИМ из прерывания CTR=ZERO в прерывание CTR=PRD.
Я этот момент еще раз проверил. Ранее не пытался вычитывать этот регистр, делал предположения основываясь на осциллограммах. Так вот, в (3) перезапись из теневого регистра осуществляется, NT_PWM8->CMPA_bit.CMPA вычитывается именно как то значение. которое я ожидаю получить. Но на осциллограмме я вижу, что значение скважности стоит старое - это момент с (4) по (6).
Синхронизацию я проверял так: запускал все 9 ШИМ на одном и том-же значении CMPA. Далее на многоканальном осциллографе накладывал друг на друга выходные сигналы и убедился, что они полностью совпадают на всех каналах. Возможно, такой проверки недостаточно.bkolbov писал(а): ↑20 июн 2017, 14:35 Есть предположение, что наблюдаются проблемы с синхронизацией счетчиков ШИМ. Они у вас точно все работают синхронно? Не может ли быть работы в противофазе, т.е. когда в PWM1 - CTR=ZERO (3), то в PWM8 в этот момент CTR=PRD, а PWM8 CTR=ZERO наступает соответсвенно когда PWM1 CTR=PRD (5)?
В последней строчке функции настройки я делаю так: NT_COMMON_REG->PWM_SYNC_bit.TBCLKSYNC = 0x01FF;
Под "первой итерацией" я понимаю первый период счетчика ШИМ после того, как программа разрешает выдачу ШИМ. После того, как делается NT_PWM8->TZCLR_bit.OST = 1 в прерывании CTR=ZERO. На рисунке это период с момента (3) и далее.
Пока я временно вышел из ситуации путем переноса кода разрешения работы (NT_PWM8->TZCLR_bit.OST = 1) ШИМ из прерывания CTR=ZERO в прерывание CTR=PRD.