К1921ВК01Т (арм Cortex-M4F)

32-разрядные микроконтроллеры разработки АО "НИИЭТ"

Модераторы: ea, dav, bkolbov, Alis, pip, _sva_

Аватара пользователя
Лашкевич
Сообщения: 372
Зарегистрирован: 13 май 2015, 13:10
Предприятие: ООО "НПФ Вектор"
Откуда: Москва
Контактная информация:

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение Лашкевич »

Какой драйвер имеется ввиду? Из проекта motorcontroldemo? Его накладные расходы напрямую зависят от размера словаря объектов. Для словаря порядка 10-20 элементов должно хватать прерывания и 10кГц. Какой у вас размер словаря? Замерьте время выполнения при помощи счетчика NT_TIMER, как сделано в этом проекте для замера времени выполнения прерываний, и попробуйте найти наиболее вычислительно-ёмкую часть. Также проверьте, включена ли оптимизация кода.
С уважением,
Лашкевич Максим.
Инженер-программист ООО "НПФ Вектор", Москва.
http://motorcontrol.ru/
bahoo08
Сообщения: 15
Зарегистрирован: 10 сен 2018, 14:15
Предприятие: .

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение bahoo08 »

Да, я использовал драйвер из проекта motorcontroldemo. Странно, у меня простые операции в виде сложения могут занимать от пары сотен, до тысяч по значению счётчика NT_TIMER. Сам таймер тоже показывает сильные, но не на столько сильные различия внутри входа и выхода в прерывания по таймеру, но иногда проскакивают отличия значения таймера как в период счётчика, так и в 10 раз меньшие. (в прошлый раз я ошибся, у меня в мэйне было сравнение которое переставало выполняться. Его убрал, в условии наличия второго прерывания, даже пустого, не позволяет возвращаться в бесконечный цикл.)
В целом у меня примитивное скалярное управление успевает обработаться, даже не смотря на то, что если оставить только модбас и пустой прерывание по шиму, то в бесконечный цикл, почему-то, он уже не возвращается.
Аватара пользователя
Лашкевич
Сообщения: 372
Зарегистрирован: 13 май 2015, 13:10
Предприятие: ООО "НПФ Вектор"
Откуда: Москва
Контактная информация:

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение Лашкевич »

Разберитесь с прерываниями, замерьте время каждого, выведите на внешний осциллограф время входа и выхода из прерывания, проверьте приоритеты, включите оптимизацию, проверьте используется ли аппаратная плавающая точка. Запустите целиком проект motorcontroldemo, замерьте время расчета драйвера там, сравните с вашим ПО.
С уважением,
Лашкевич Максим.
Инженер-программист ООО "НПФ Вектор", Москва.
http://motorcontrol.ru/
bahoo08
Сообщения: 15
Зарегистрирован: 10 сен 2018, 14:15
Предприятие: .

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение 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;		//сброс прерывания
Аватара пользователя
Disona
Сообщения: 81
Зарегистрирован: 06 дек 2016, 11:18
Предприятие: НПФ Вектор
Откуда: Москва
Контактная информация:

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение 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;		//сброс прерывания
Последний раз редактировалось Disona 22 окт 2018, 12:48, всего редактировалось 1 раз.
С уважением, Дмитрий Шпак
ООО "НПФ Вектор"
bahoo08
Сообщения: 15
Зарегистрирован: 10 сен 2018, 14:15
Предприятие: .

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение bahoo08 »

period = 20 000, dead time = 200
Аватара пользователя
Disona
Сообщения: 81
Зарегистрирован: 06 дек 2016, 11:18
Предприятие: НПФ Вектор
Откуда: Москва
Контактная информация:

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение Disona »

А это, а вы в прерывании, в самом конце, очищаете флажок прерывания? Если этого не сделать, то прерывание будет вечно висеть и обрабатываться. Речь идёт о флаге внутри EPwm модуля.
С уважением, Дмитрий Шпак
ООО "НПФ Вектор"
Аватара пользователя
Лашкевич
Сообщения: 372
Зарегистрирован: 13 май 2015, 13:10
Предприятие: ООО "НПФ Вектор"
Откуда: Москва
Контактная информация:

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение Лашкевич »

Код: Выделить всё

NT_PWM_0->ETCLR.bit.INT=1;
NT_PWM_0->INTCLR.bit.INT=1;
С уважением,
Лашкевич Максим.
Инженер-программист ООО "НПФ Вектор", Москва.
http://motorcontrol.ru/
bahoo08
Сообщения: 15
Зарегистрирован: 10 сен 2018, 14:15
Предприятие: .

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение bahoo08 »

Действительно, я очищал только один флаг, NT_PWM_0->ETCLR.bit.INT=1. Спасибо
user_1983
Сообщения: 21
Зарегистрирован: 19 сен 2018, 08:33
Предприятие: ЦНИИ Электроприбор

Re: К1921ВК01Т (арм Cortex-M4F)

Сообщение user_1983 »

Добрый день!
Продолжаю осваивать 1921вк01т. И меня начинают терезать смутные сомнения... Как же этот 1921вк01т сильно похож на XMC4500 Infineon! Модуль CAN - практически один в один. Я просто копирую все настройки из своего проекта для XMC4500.
Это хорошо, но если бы у вас еще были AppNotes как у Infineon было бы просто замечательно!
Ответить

Вернуться в «32-разрядные микроконтроллеры»