Страница 33 из 62
Re: К1921ВК01Т (арм Cortex-M4F)
Добавлено: 18 окт 2018, 18:27
Лашкевич
Какой драйвер имеется ввиду? Из проекта motorcontroldemo? Его накладные расходы напрямую зависят от размера словаря объектов. Для словаря порядка 10-20 элементов должно хватать прерывания и 10кГц. Какой у вас размер словаря? Замерьте время выполнения при помощи счетчика NT_TIMER, как сделано в этом проекте для замера времени выполнения прерываний, и попробуйте найти наиболее вычислительно-ёмкую часть. Также проверьте, включена ли оптимизация кода.
Re: К1921ВК01Т (арм Cortex-M4F)
Добавлено: 18 окт 2018, 19:29
bahoo08
Да, я использовал драйвер из проекта motorcontroldemo. Странно, у меня простые операции в виде сложения могут занимать от пары сотен, до тысяч по значению счётчика NT_TIMER. Сам таймер тоже показывает сильные, но не на столько сильные различия внутри входа и выхода в прерывания по таймеру, но иногда проскакивают отличия значения таймера как в период счётчика, так и в 10 раз меньшие. (в прошлый раз я ошибся, у меня в мэйне было сравнение которое переставало выполняться. Его убрал, в условии наличия второго прерывания, даже пустого, не позволяет возвращаться в бесконечный цикл.)
В целом у меня примитивное скалярное управление успевает обработаться, даже не смотря на то, что если оставить только модбас и пустой прерывание по шиму, то в бесконечный цикл, почему-то, он уже не возвращается.
Re: К1921ВК01Т (арм Cortex-M4F)
Добавлено: 19 окт 2018, 15:56
Лашкевич
Разберитесь с прерываниями, замерьте время каждого, выведите на внешний осциллограф время входа и выхода из прерывания, проверьте приоритеты, включите оптимизацию, проверьте используется ли аппаратная плавающая точка. Запустите целиком проект motorcontroldemo, замерьте время расчета драйвера там, сравните с вашим ПО.
Re: К1921ВК01Т (арм Cortex-M4F)
Добавлено: 22 окт 2018, 12:36
bahoo08
Я понял в чём проблема, но не понимаю, почему так получается. У меня прерывание по ШИМу срабатывает на каждые ~100 значений счётчика TBCTR, хотя настроено прерывание на каждый период, который равен 20000.
Код: Выделить всё
//генерирование событий 358
NT_PWM0->ETSEL_bit.INTSEL = 0x1; // Прерывание при CTR = PRD
NT_PWM0->ETSEL_bit.INTEN = 1; // разрешение прерывания
NT_PWM0->ETPS_bit.INTPRD = 0x0; // Прерывание по каждому событию
// NT_PWM0->ETPS_bit.INTCNT = 0x1;
NT_PWM0->TBCTL_bit.FREE_SOFT = 0; //поведение счётчика в режиме отладки
Весь код инициализации ШИМ, от которого формируется событие для прерывания
- | Показать
Код: Выделить всё
//Включение альтернативной функции и выбор её
NT_COMMON_REG->GPIOPCTLG_bit.PIN2 = 0; // PWM_A0
NT_GPIOG->ALTFUNCSET_bit.ALTFUNCSET |= (1 << 2);
NT_COMMON_REG->GPIOPCTLA_bit.PIN10 = 2; //PWM_B0
NT_GPIOA->ALTFUNCSET_bit.ALTFUNCSET |= (1 << 10);
//Устанавливаем флаги OSHT, CBC, INT (запрос на прерывание)
// смотрим детектор сигнала аварий 110 стр. (356)
NT_PWM0->TZCLR = 0x7;
NT_PWM0->TZINTCLR_bit.TZINT = 1;
// PWMA
NT_PWM0->TBPRD = period_; // устанавливается период ШИМ
NT_PWM0->TBPHS_bit.TBPHS = 0x0000; // Начальная фаза
NT_PWM0->TBCTR = 0x0000; //
NT_PWM0->TBCTL_bit.PRDLD = TB_SHADOW; //управляем загрузкой регистра TBPRD через теневой регистр (0 - отложенная загрузка)
NT_PWM0->TBCTL_bit.CTRMODE = TB_COUNT_UPDOWN; // режим счёта счётчика такой вот /\ .
NT_PWM0->TBCTL_bit.PHSEN = TB_DISABLE; //нет фазной синхранизации (сихранизацию задаёт, но сам не подстраивается)
NT_PWM0->TBCTL_bit.HSPCLKDIV = 0; // устанавливаем делитель = 1
NT_PWM0->TBCTL_bit.CLKDIV = 0; // и этот делитель = 1
NT_PWM0->TBCTL_bit.SYNCOSEL = TB_CTR_ZERO; //источник синхросигнала CTR
NT_PWM0->CMPCTL_bit.SHDWAMODE = CC_SHADOW; // CMPA через теневой регистр
NT_PWM0->CMPCTL_bit.LOADAMODE = CC_CTR_ZERO; //управляем загрузкой CTR = zero
NT_PWM0->CMPCTL_bit.SHDWBMODE = CC_SHADOW; // CMPB через теневой регистр
NT_PWM0->CMPCTL_bit.LOADBMODE = CC_CTR_ZERO; // управляем загрузкой CTR = zero
NT_PWM0->CMPA_bit.CMPA = 0; // Что-то вроде скважности
// Реализуем события
NT_PWM0->AQCTLA = 0; // обнуляем всё и по изи заполняем
NT_PWM0->AQCTLA_bit.ZRO = 1; // CTR=zero (выводим ШИМ в 0)
NT_PWM0->AQCTLA_bit.CAU = 2; // CTR=CMPA (при счёте вверх) PWM = 1
NT_PWM0->AQCTLA_bit.CAD = 1; // CTR = CMPA (при счёте в низ) PWM = 0
NT_PWM0->AQCTLB = NT_PWM0->AQCTLA; // события как в для порта А
NT_PWM0->AQSFRC_bit.RLDCSF = 3;
NT_PWM0->DBRED = deadTime_; //мёртвое время
NT_PWM0->DBFED = NT_PWM0->DBRED; // мёртвое время с другой стороны
NT_PWM0->DBCTL_bit.IN_MODE = DBA_RED_DBB_FED; // контроль по переднему и заднему фронту
NT_PWM0->DBCTL_bit.OUT_MODE = DB_FULL_ENABLE; // выбор фронта, для которого включена задержка (оба фронта)
NT_PWM0->DBCTL_bit.POLSEL = DB_ACTV_HIC; // инверсия полярности сигнала на выходе
//генерирование событий 358
NT_PWM0->ETSEL_bit.INTSEL = 0x1; // Прерывание при CTR = PRD
NT_PWM0->ETSEL_bit.INTEN = 1; // разрешение прерывания
NT_PWM0->ETPS_bit.INTPRD = 0x0; // Прерывание по каждому событию
// NT_PWM0->ETPS_bit.INTCNT = 0x1;
NT_PWM0->TBCTL_bit.FREE_SOFT = 0; //поведение счётчика в режиме отладки
NT_PWM0->TZSEL_bit.OSHT0 = TZ_DISABLE; // разрешение источника сигнала аварий
NT_PWM0->TZSEL_bit.OSHT1 = TZ_DISABLE;
NT_PWM0->TZSEL_bit.OSHT2 = TZ_DISABLE;
NT_PWM0->TZSEL_bit.OSHT3 = TZ_DISABLE;
NT_PWM0->TZSEL_bit.OSHT4 = TZ_DISABLE;
NT_PWM0->TZSEL_bit.OSHT5 = TZ_DISABLE;
NT_PWM0->TZEINT_bit.OST = 0; // генерация прерывания в одноканальном режиме обр аварии( 0 - выкл)
//Разрешаем генерацию сигнала пуска АЦП (357 стр)
NT_PWM0->ETSEL_bit.SOCAEN = 1;
NT_PWM0->ETSEL_bit.SOCASEL = 1;
NT_PWM0->TZCTL_bit.TZA = 0;//выбор переключения PWM_B/PWM_A
NT_PWM0->TZCTL_bit.TZB = 0;
NT_PWM0->ETCLR_bit.INT = 1; //сброс прерывания
Re: К1921ВК01Т (арм Cortex-M4F)
Добавлено: 22 окт 2018, 12:47
Disona
Скажите, пожалуйста, чему равно значение переменной period? Вернее даже, не чему равно (ну это тоже интересно), а как оно передаётся в функцию инициализации. Вы проверяли, что после прохождения инициализации период действительно равен 2000? Не может где-то в другом месте переиничиваться период?
bahoo08 писал(а): ↑22 окт 2018, 12:36
Весь код инициализации ШИМ, от которого формируется событие для прерывания
- | Показать
Код: Выделить всё
//Включение альтернативной функции и выбор её
NT_COMMON_REG->GPIOPCTLG_bit.PIN2 = 0; // PWM_A0
NT_GPIOG->ALTFUNCSET_bit.ALTFUNCSET |= (1 << 2);
NT_COMMON_REG->GPIOPCTLA_bit.PIN10 = 2; //PWM_B0
NT_GPIOA->ALTFUNCSET_bit.ALTFUNCSET |= (1 << 10);
//Устанавливаем флаги OSHT, CBC, INT (запрос на прерывание)
// смотрим детектор сигнала аварий 110 стр. (356)
NT_PWM0->TZCLR = 0x7;
NT_PWM0->TZINTCLR_bit.TZINT = 1;
// PWMA
NT_PWM0->TBPRD = period_; // устанавливается период ШИМ
NT_PWM0->TBPHS_bit.TBPHS = 0x0000; // Начальная фаза
NT_PWM0->TBCTR = 0x0000; //
NT_PWM0->TBCTL_bit.PRDLD = TB_SHADOW; //управляем загрузкой регистра TBPRD через теневой регистр (0 - отложенная загрузка)
NT_PWM0->TBCTL_bit.CTRMODE = TB_COUNT_UPDOWN; // режим счёта счётчика такой вот /\ .
NT_PWM0->TBCTL_bit.PHSEN = TB_DISABLE; //нет фазной синхранизации (сихранизацию задаёт, но сам не подстраивается)
NT_PWM0->TBCTL_bit.HSPCLKDIV = 0; // устанавливаем делитель = 1
NT_PWM0->TBCTL_bit.CLKDIV = 0; // и этот делитель = 1
NT_PWM0->TBCTL_bit.SYNCOSEL = TB_CTR_ZERO; //источник синхросигнала CTR
NT_PWM0->CMPCTL_bit.SHDWAMODE = CC_SHADOW; // CMPA через теневой регистр
NT_PWM0->CMPCTL_bit.LOADAMODE = CC_CTR_ZERO; //управляем загрузкой CTR = zero
NT_PWM0->CMPCTL_bit.SHDWBMODE = CC_SHADOW; // CMPB через теневой регистр
NT_PWM0->CMPCTL_bit.LOADBMODE = CC_CTR_ZERO; // управляем загрузкой CTR = zero
NT_PWM0->CMPA_bit.CMPA = 0; // Что-то вроде скважности
// Реализуем события
NT_PWM0->AQCTLA = 0; // обнуляем всё и по изи заполняем
NT_PWM0->AQCTLA_bit.ZRO = 1; // CTR=zero (выводим ШИМ в 0)
NT_PWM0->AQCTLA_bit.CAU = 2; // CTR=CMPA (при счёте вверх) PWM = 1
NT_PWM0->AQCTLA_bit.CAD = 1; // CTR = CMPA (при счёте в низ) PWM = 0
NT_PWM0->AQCTLB = NT_PWM0->AQCTLA; // события как в для порта А
NT_PWM0->AQSFRC_bit.RLDCSF = 3;
NT_PWM0->DBRED = deadTime_; //мёртвое время
NT_PWM0->DBFED = NT_PWM0->DBRED; // мёртвое время с другой стороны
NT_PWM0->DBCTL_bit.IN_MODE = DBA_RED_DBB_FED; // контроль по переднему и заднему фронту
NT_PWM0->DBCTL_bit.OUT_MODE = DB_FULL_ENABLE; // выбор фронта, для которого включена задержка (оба фронта)
NT_PWM0->DBCTL_bit.POLSEL = DB_ACTV_HIC; // инверсия полярности сигнала на выходе
//генерирование событий 358
NT_PWM0->ETSEL_bit.INTSEL = 0x1; // Прерывание при CTR = PRD
NT_PWM0->ETSEL_bit.INTEN = 1; // разрешение прерывания
NT_PWM0->ETPS_bit.INTPRD = 0x0; // Прерывание по каждому событию
// NT_PWM0->ETPS_bit.INTCNT = 0x1;
NT_PWM0->TBCTL_bit.FREE_SOFT = 0; //поведение счётчика в режиме отладки
NT_PWM0->TZSEL_bit.OSHT0 = TZ_DISABLE; // разрешение источника сигнала аварий
NT_PWM0->TZSEL_bit.OSHT1 = TZ_DISABLE;
NT_PWM0->TZSEL_bit.OSHT2 = TZ_DISABLE;
NT_PWM0->TZSEL_bit.OSHT3 = TZ_DISABLE;
NT_PWM0->TZSEL_bit.OSHT4 = TZ_DISABLE;
NT_PWM0->TZSEL_bit.OSHT5 = TZ_DISABLE;
NT_PWM0->TZEINT_bit.OST = 0; // генерация прерывания в одноканальном режиме обр аварии( 0 - выкл)
//Разрешаем генерацию сигнала пуска АЦП (357 стр)
NT_PWM0->ETSEL_bit.SOCAEN = 1;
NT_PWM0->ETSEL_bit.SOCASEL = 1;
NT_PWM0->TZCTL_bit.TZA = 0;//выбор переключения PWM_B/PWM_A
NT_PWM0->TZCTL_bit.TZB = 0;
NT_PWM0->ETCLR_bit.INT = 1; //сброс прерывания
Re: К1921ВК01Т (арм Cortex-M4F)
Добавлено: 22 окт 2018, 12:48
bahoo08
period = 20 000, dead time = 200
Re: К1921ВК01Т (арм Cortex-M4F)
Добавлено: 22 окт 2018, 12:53
Disona
А это, а вы в прерывании, в самом конце, очищаете флажок прерывания? Если этого не сделать, то прерывание будет вечно висеть и обрабатываться. Речь идёт о флаге внутри EPwm модуля.
Re: К1921ВК01Т (арм Cortex-M4F)
Добавлено: 22 окт 2018, 12:57
Лашкевич
Код: Выделить всё
NT_PWM_0->ETCLR.bit.INT=1;
NT_PWM_0->INTCLR.bit.INT=1;
Re: К1921ВК01Т (арм Cortex-M4F)
Добавлено: 22 окт 2018, 13:03
bahoo08
Действительно, я очищал только один флаг, NT_PWM_0->ETCLR.bit.INT=1. Спасибо
Re: К1921ВК01Т (арм Cortex-M4F)
Добавлено: 08 ноя 2018, 16:32
user_1983
Добрый день!
Продолжаю осваивать 1921вк01т. И меня начинают терезать смутные сомнения... Как же этот 1921вк01т сильно похож на XMC4500 Infineon! Модуль CAN - практически один в один. Я просто копирую все настройки из своего проекта для XMC4500.
Это хорошо, но если бы у вас еще были AppNotes как у Infineon было бы просто замечательно!