Руководство по настройке и использованию открытого ПО

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

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

petrovitch
Сообщения: 106
Зарегистрирован: 15 фев 2017, 19:07

Re: Руководство по настройке и использованию открытого ПО

Сообщение petrovitch »

Добрый день!
Можно. Только распишите, пожалуйста, поподробнее что именно вы хотели бы увидеть.
- в каких задачах применима синхронизация каналов ШИМ;

- механизм реализации на микроконтроллере;

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

Re: Руководство по настройке и использованию открытого ПО

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

-в каких задачах применима синхронизация каналов ШИМ;
При управлении единым устройством с несколькими силовыми ключами для обеспечения согласованного управления. Обычно синхронизируются несущие таймеры, генерирующие ШИМ, чтобы они работали синхронно. Задавая разные уставки сравнения можно получить желаемый ШИМ. Например, для трехфазного двигателя для векторной, скалярной да и любой другой ШИМ все три таймера обычно синхронизируются вместе без сдвига.
При желании можно еще сдвинуть таймеры друг относительно друга заданием фазового сдвига. Тогда можно разнести счетчики ШИМ, что удобно, например, для многоканальных источников питания.
- механизм реализации на микроконтроллере;
Внутри микроконтроллера ШИМы устроены в виде независимых блоков, каждый из которых имеет свой таймер и управляет двумя выходами (двумя ключами). Для шестиключевого инвертора напряжения, например, задействуются три таких блока. Для одновременной работы таймеров используется сигнал синхронизации: можно сконфигурировать, какой блок ШИМ испускает синхросигнал, какие принимают. Например, первый блок ШИМ может испускать синхросигнал по событию обнуления, а остальные блоки по его приему также обнулять свои счетчики. Это самая простая типовая настройка. Также можно синхронизировать ШИМы между двумя разными контролерами, синхросигнал может быть и внешним. Также можно разнести таймеры по фазе, используя регистр фазового сдвига по приему сигнала синхронизации.

Результат: таймеры ШИМов считают синхронно. В зависимости от того, какой режим счета выбран (вверх-вниз, вверх и обнулить и т.п.) и какие уставки сравнения заданы, можно получить разные временные диаграммы.

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

Re: Руководство по настройке и использованию открытого ПО

Сообщение Илья »

Лашкевич писал(а): 19 апр 2017, 18:27 Пример инициализации модулей ШИМ для работы с трехфазным двигателем:

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

	NT_COMMON_REG->PWM_SYNC_bit.TBCLKSYNC = 0; //синхронизация таймеров - сброс внутренних счетчиков
	/* Синхронизировать ШИМы */
	NT_COMMON_REG->PWM_CTRL = 0x8;

// ------------------------------------------------------------------------
	// Настраиваем модуль ePWM1
	// ------------------------------------------------------------------------
	if (p->Frequency < PWM_FREQ_MIN)
		p->Frequency = PWM_FREQ_MIN;
	if (p->Frequency > PWM_FREQ_MAX)
		p->Frequency = PWM_FREQ_MAX;
	NT_PWM0->TBPRD = _IQ10div(_IQ10(CORE_CLK/1000.0), p->Frequency << 1) >> 10; //период

	p->k_pwm = NT_PWM0->TBPRD;
	p->FreqPrev = p->Frequency;                 //предыдущая частота
	NT_PWM0->TBPHS_bit.TBPHS = 0x0000;            // Phase is 0
	NT_PWM0->TBCTR = 0x0000;                       // Clear counter

	// Setup counter mode
	NT_PWM0->TBCTL_bit.PRDLD = TB_SHADOW;        // загрузка TBPRD при TBCTR = 0
	NT_PWM0->TBCTL_bit.CTRMODE = TB_COUNT_UPDOWN;  // Count up-down
	NT_PWM0->TBCTL_bit.PHSEN = TB_DISABLE;         // Disable phase loading
	NT_PWM0->TBCTL_bit.PHSDIR = TB_UP;      // Считать вверх после загрузки фазы
	NT_PWM0->TBCTL_bit.HSPCLKDIV = 0;     // High Speed Time-base Clock Prescale
	NT_PWM0->TBCTL_bit.CLKDIV = 0;                 // Time-base Clock Prescale
	NT_PWM0->TBCTL_bit.SYNCOSEL = TB_CTR_ZERO; // выдаём синхро-сигнал при TBCTR = 0

	// Setup shadowing
	NT_PWM0->CMPCTL_bit.SHDWAMODE = CC_SHADOW;   //включить SHADOW для сравнения
	NT_PWM0->CMPCTL_bit.LOADAMODE = CC_CTR_ZERO;   // Load on period and zero

	NT_PWM0->CMPCTL_bit.SHDWBMODE = CC_SHADOW;   //включить SHADOW для сравнения
	NT_PWM0->CMPCTL_bit.LOADBMODE = CC_CTR_ZERO;   // Load on period and zero

	// Set Compare values
	NT_PWM0->CMPA_bit.CMPA = 0;                   // Set compare A value

	// Set actions
	NT_PWM0->AQCTLA = AQ_EPWM_DISABLE; // для начала события для PWM1A запрещены
	NT_PWM0->AQCTLA_bit.ZRO = 1; //обнуляем при нуле счетчика
	NT_PWM0->AQCTLA_bit.CAU = 2; //включаем при сравнении и инкрементиовании
	NT_PWM0->AQCTLA_bit.CAD = 1; //обнуляем при сравнении и декрементровании

	//Для PWMB тоже самое, что для PWMА. Без инверсии. Инверсия далее в модуле МВ
	NT_PWM0->AQCTLB = NT_PWM0->AQCTLA; // для начала события для PWM1B запрещены
	NT_PWM0->AQCTLB_bit.ZRO = NT_PWM0->AQCTLA_bit.ZRO; //обнуляем при нуле счетчика
	NT_PWM0->AQCTLB_bit.CAU = NT_PWM0->AQCTLA_bit.CAU; //включаем при сравнении и инкрементиовании
	NT_PWM0->AQCTLB_bit.CAD = NT_PWM0->AQCTLA_bit.CAD; //обнуляем при сравнении и декрементровании

	NT_PWM0->AQSFRC_bit.RLDCSF = 3; //реагировать на софтвенную привязку ног без теневого регистра

	// Setup Deadband
	// DBRED = DBFED = 150 * Tм_мкс / 4
	NT_PWM0->DBRED = _IQ4mpy(_IQ4(150 / 4), p->DeadBand >> 20) >> 4;
	NT_PWM0->DBFED = NT_PWM0->DBRED;
	NT_PWM0->DBCTL_bit.IN_MODE = DBA_RED_DBB_FED;    //s4=0, s5=1 на картинке DT
	NT_PWM0->DBCTL_bit.OUT_MODE = DB_FULL_ENABLE;    //S1=1, S2=2 на картинке DT
	NT_PWM0->DBCTL_bit.POLSEL = DB_ACTV_HIC;       // PWM1B = !PWM1A; S2=0, S3=1

	NT_PWM0->ETSEL_bit.INTSEL = ET_DISABLE;        // Disable INT (шимовское)
	NT_PWM0->ETSEL_bit.INTEN = 0;                  // Disable INT

	NT_PWM0->TBCTL_bit.FREE_SOFT = 0;

	//разрешаем TZ быть источником аппаратной аварии (one-shot)
	//   NT_PWM0->TZSEL_bit.OSHT1 = TZ_ENABLE;
//    NT_PWM0->TZSEL_bit.OSHT2 = TZ_ENABLE;
//    NT_PWM0->TZSEL_bit.OSHT3 = TZ_ENABLE;

	// Trip-Zone
	NT_PWM0->TZCTL_bit.TZA = TZ_STATE;   // по событию "One-Shot Trip" переводим
	NT_PWM0->TZCTL_bit.TZB = TZ_STATE;          // ШИМ выходы в нужное состояние

	//Для VectorCARD от ШИМа запускается ADC
	//NT_PWM0->ETSEL_bit.SOCAEN = 1;		// Разрешить запуск ацп
	//NT_PWM0->ETSEL_bit.SOCASEL = 1;		// Запускать при CTR == 0 (Underflow)

	// ------------------------------------------------------------------------
	// Настраиваем модуль ePWM2
	// ------------------------------------------------------------------------
	// Setup TBCLK
	NT_PWM1->TBPRD = NT_PWM0->TBPRD;              //период такой же
	NT_PWM1->TBPHS_bit.TBPHS = 0x0001;            // Фаза равна 1 из-за баги в проце (0 не работает)
	NT_PWM1->TBCTR = 0x0000;                       // Clear counter

	// Setup counter mode
	NT_PWM1->TBCTL_bit.PRDLD = TB_SHADOW;        // загрузка TBPRD при TBCTR = 0
	NT_PWM1->TBCTL_bit.CTRMODE = TB_COUNT_UPDOWN;  // Count up-down
	NT_PWM1->TBCTL_bit.PHSEN = TB_ENABLE;         // Enable phase loading
	NT_PWM1->TBCTL_bit.PHSDIR = TB_UP;      // Считать вверх после загрузки фазы
	NT_PWM1->TBCTL_bit.HSPCLKDIV = 0;     // High Speed Time-base Clock Prescale
	NT_PWM1->TBCTL_bit.CLKDIV = 0;           // Time-base Clock Prescale
	NT_PWM1->TBCTL_bit.SYNCOSEL = TB_SYNC_IN; // пропускаем синхро-сигнал "насквозь"

	// Setup shadowing
	NT_PWM1->CMPCTL_bit.SHDWAMODE = CC_SHADOW;   //включить SHADOW для сравнения
	NT_PWM1->CMPCTL_bit.LOADAMODE = CC_CTR_ZERO;   // Load on period and zero

	NT_PWM1->CMPCTL_bit.SHDWBMODE = CC_SHADOW;   //включить SHADOW для сравнения
	NT_PWM1->CMPCTL_bit.LOADBMODE = CC_CTR_ZERO;   // Load on period and zero

	// Set Compare values
	NT_PWM1->CMPA_bit.CMPA = 0;                   // Set compare A value

	// Set actions
	NT_PWM1->AQCTLA = AQ_EPWM_DISABLE; // для начала события запрещены
	NT_PWM1->AQCTLA_bit.ZRO = 1; //обнуляем при нуле счетчика
	NT_PWM1->AQCTLA_bit.CAU = 2; //включаем при сравнении и инкрементиовании
	NT_PWM1->AQCTLA_bit.CAD = 1; //обнуляем при сравнении и декрементровании

	//Для PWMB тоже самое, что для PWMА. Без инверсии. Инверсия далее в модуле МВ
	NT_PWM1->AQCTLB = NT_PWM0->AQCTLA; // для начала события для PWM1B запрещены
	NT_PWM1->AQCTLB_bit.ZRO = NT_PWM0->AQCTLA_bit.ZRO; //обнуляем при нуле счетчика
	NT_PWM1->AQCTLB_bit.CAU = NT_PWM0->AQCTLA_bit.CAU; //включаем при сравнении и инкрементиовании
	NT_PWM1->AQCTLB_bit.CAD = NT_PWM0->AQCTLA_bit.CAD; //обнуляем при сравнении и декрементровании

	NT_PWM1->AQSFRC_bit.RLDCSF = 3; //реагировать на софтвенную привязку ног без теневого регистра

	// Active high complementary PWMs - Setup Deadband
	NT_PWM1->DBRED = NT_PWM0->DBRED;
	NT_PWM1->DBFED = NT_PWM1->DBRED;
	NT_PWM1->DBCTL_bit.IN_MODE = NT_PWM0->DBCTL_bit.IN_MODE;
	NT_PWM1->DBCTL_bit.OUT_MODE = NT_PWM0->DBCTL_bit.OUT_MODE;
	NT_PWM1->DBCTL_bit.POLSEL = NT_PWM0->DBCTL_bit.POLSEL;

	// Interrupt where we will change the Compare Values
	NT_PWM1->ETSEL_bit.INTSEL = ET_DISABLE;        // Disable INT
	NT_PWM1->ETSEL_bit.INTEN = 0;                  // Disable INT

	NT_PWM1->TBCTL_bit.FREE_SOFT = 0;

	//разрешаем TZ быть источником аппаратной аварии (one-shot)
	//   NT_PWM1->TZSEL_bit.OSHT1 = TZ_ENABLE;
	//   NT_PWM1->TZSEL_bit.OSHT2 = TZ_ENABLE;
	//   NT_PWM1->TZSEL_bit.OSHT3 = TZ_ENABLE;

	// Trip-Zone
	NT_PWM1->TZCTL_bit.TZA = TZ_STATE;   // по событию "One-Shot Trip" переводим
	NT_PWM1->TZCTL_bit.TZB = TZ_STATE;          // ШИМ выходы в нужное состояние

	// ------------------------------------------------------------------------
	// Настраиваем модуль ePWM3
	// ------------------------------------------------------------------------
	// Setup TBCLK
	NT_PWM2->TBPRD = NT_PWM0->TBPRD;
	NT_PWM2->TBPHS_bit.TBPHS = 0x0001;            // Фаза равна 1 из-за баги в проце (0 не работает)
	NT_PWM2->TBCTR = 0x0000;                       // Clear counter

	// Setup counter mode
	NT_PWM2->TBCTL_bit.PRDLD = TB_SHADOW;        // загрузка TBPRD при TBCTR = 0
	NT_PWM2->TBCTL_bit.CTRMODE = TB_COUNT_UPDOWN;  // Count up-down
	NT_PWM2->TBCTL_bit.PHSEN = TB_ENABLE;         // Enable phase loading
	NT_PWM2->TBCTL_bit.PHSDIR = TB_UP;      // Считать вверх после загрузки фазы
	NT_PWM2->TBCTL_bit.HSPCLKDIV = 0;     // High Speed Time-base Clock Prescale
	NT_PWM2->TBCTL_bit.CLKDIV = 0;           // Time-base Clock Prescale
	NT_PWM2->TBCTL_bit.SYNCOSEL = TB_SYNC_IN; // разрешаем выдачу синхро-сигнала

	// Setup shadowing
	NT_PWM2->CMPCTL_bit.SHDWAMODE = CC_SHADOW;   //включить SHADOW для сравнения
	NT_PWM2->CMPCTL_bit.LOADAMODE = CC_CTR_ZERO;   // Load on period and zero

	NT_PWM2->CMPCTL_bit.SHDWBMODE = CC_SHADOW;   //включить SHADOW для сравнения
	NT_PWM2->CMPCTL_bit.LOADBMODE = CC_CTR_ZERO;   // Load on period and zero

	// Set Compare values
	NT_PWM2->CMPA_bit.CMPA = 0;                   // Set compare A value

	// Set actions
	NT_PWM2->AQCTLA = AQ_EPWM_DISABLE; // для начала события запрещены
	NT_PWM2->AQCTLA_bit.ZRO = 1; //обнуляем при нуле счетчика
	NT_PWM2->AQCTLA_bit.CAU = 2; //включаем при сравнении и инкрементиовании
	NT_PWM2->AQCTLA_bit.CAD = 1; //обнуляем при сравнении и декрементровании

	//Для PWMB тоже самое, что для PWMА. Без инверсии. Инверсия далее в модуле МВ
	NT_PWM2->AQCTLB = NT_PWM0->AQCTLA; // для начала события для PWM1B запрещены
	NT_PWM2->AQCTLB_bit.ZRO = NT_PWM0->AQCTLA_bit.ZRO; //обнуляем при нуле счетчика
	NT_PWM2->AQCTLB_bit.CAU = NT_PWM0->AQCTLA_bit.CAU; //включаем при сравнении и инкрементиовании
	NT_PWM2->AQCTLB_bit.CAD = NT_PWM0->AQCTLA_bit.CAD; //обнуляем при сравнении и декрементровании

	NT_PWM2->AQSFRC_bit.RLDCSF = 3; //реагировать на софтвенную привязку ног без теневого регистра

	// Active high complementary PWMs - Setup Deadband
	NT_PWM2->DBRED = NT_PWM0->DBRED;
	NT_PWM2->DBFED = NT_PWM2->DBRED;
	NT_PWM2->DBCTL_bit.IN_MODE = NT_PWM0->DBCTL_bit.IN_MODE;
	NT_PWM2->DBCTL_bit.OUT_MODE = NT_PWM0->DBCTL_bit.OUT_MODE;
	NT_PWM2->DBCTL_bit.POLSEL = NT_PWM0->DBCTL_bit.POLSEL;

	// Interrupt where we will change the Compare Values
	NT_PWM2->ETSEL_bit.INTSEL = ET_DISABLE;        // Disable INT
	NT_PWM2->ETSEL_bit.INTEN = 0;                  // Disable INT

	//разрешаем TZ быть источником аппаратной аварии (one-shot)
	//  NT_PWM2->TZSEL_bit.OSHT1 = TZ_ENABLE;
	//  NT_PWM2->TZSEL_bit.OSHT2 = TZ_ENABLE;
	//  NT_PWM2->TZSEL_bit.OSHT3 = TZ_ENABLE;

	NT_PWM2->TBCTL_bit.FREE_SOFT = 0;

	// Trip-Zone
	NT_PWM2->TZCTL_bit.TZA = TZ_STATE;   // по событию "One-Shot Trip" переводим
	NT_PWM2->TZCTL_bit.TZB = TZ_STATE;          // ШИМ выходы в нужное состояние

	// ------------------------------------------------------------------------
	// Настраиваем модуль ePWM3 под АЦП
	// ------------------------------------------------------------------------
	// Setup TBCLK
	NT_PWM3->TBPRD = NT_PWM0->TBPRD;
	NT_PWM3->TBPHS_bit.TBPHS = 0x0001;       // Фаза равна 1 из-за баги в проце (0 не работает)
	NT_PWM3->TBCTR = 0x0000;                       // Clear counter

	// Setup counter mode
	NT_PWM3->TBCTL_bit.PRDLD = TB_SHADOW;        // загрузка TBPRD при TBCTR = 0
	NT_PWM3->TBCTL_bit.CTRMODE = TB_COUNT_UPDOWN;  // Count up-down
	NT_PWM3->TBCTL_bit.PHSEN = TB_ENABLE;         // Enable phase loading
	NT_PWM3->TBCTL_bit.PHSDIR = TB_UP;      // Считать вверх после загрузки фазы
	NT_PWM3->TBCTL_bit.HSPCLKDIV = 0;     // High Speed Time-base Clock Prescale
	NT_PWM3->TBCTL_bit.CLKDIV = 0;           // Time-base Clock Prescale
	NT_PWM3->TBCTL_bit.SYNCOSEL = TB_SYNC_IN; // разрешаем выдачу синхро-сигнала

	// Interrupt where we will change the Compare Values
	NT_PWM3->ETSEL_bit.INTSEL = ET_DISABLE;        // Disable INT
	NT_PWM3->ETSEL_bit.INTEN = 0;                  // Disable INT

	NT_PWM3->TBCTL_bit.FREE_SOFT = 0;

	NT_PWM3->ETSEL_bit.SOCAEN = 1;		// Разрешить запуск ацп
	NT_PWM3->ETSEL_bit.SOCASEL = 1;		// Запускать при CTR == 0 (Underflow)

	//сбрасываем все флаги аварий
	NT_PWM0->TZCLR = 0x7;
	NT_PWM1->TZCLR = 0x7;
	NT_PWM2->TZCLR = 0x7;



	//настройка ножек
	NT_GPIOG->ALTFUNCSET = (1 << 2) + (1 << 3) + (1 << 4);		//A[0],A[1],A[2]

	// Периферийная функция - PWM
	NT_COMMON_REG->GPIOPCTLA_bit.PIN10 = 2;

	NT_COMMON_REG->GPIOPCTLF_bit.PIN2 = 0;
	NT_COMMON_REG->GPIOPCTLF_bit.PIN4 = 0;
	NT_COMMON_REG->GPIOPCTLG_bit.PIN2 = 0;
	NT_COMMON_REG->GPIOPCTLG_bit.PIN3 = 0;
	NT_COMMON_REG->GPIOPCTLG_bit.PIN4 = 0;



//A[10], F[2], F[4]  ножки резета
	NT_GPIOA->ALTFUNCCLR = (1 << 10);		//B[0]

	NT_GPIOA->OUTENSET = (1 << 10);
	NT_GPIOF->OUTENSET = (1 << 2);
	NT_GPIOF->OUTENSET = (1 << 4);

	//A[10], F[2], F[4]
	//Синхронный запуск ШИМ
	NT_COMMON_REG->PWM_SYNC_bit.TBCLKSYNC = 0x1FF;

}

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

Re: Руководство по настройке и использованию открытого ПО

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

Насколько я помню, при нулевой фазе таймеры ШИМ оказываются в противофазе, если настроен счёт вверх-вниз. Там направление счета как-то сбивается и они едут из нуля, но в разные стороны. Но документ, это описывающий, не помню. В еррате на проц нету? Которая официальная на сайте нииэт?
С уважением,
Лашкевич Максим.
Инженер-программист ООО "НПФ Вектор", Москва.
http://motorcontrol.ru/
Аватара пользователя
Лашкевич
Сообщения: 372
Зарегистрирован: 13 май 2015, 13:10
Предприятие: ООО "НПФ Вектор"
Откуда: Москва
Контактная информация:

Re: Руководство по настройке и использованию открытого ПО

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

Нашел, это не в еррате описано, а в основном даташите:
особенность схемы – генерация и
распространение сигнала синхронизации от блока ШИМ занимает один такт TBCLK.
К примеру, если по событию синхронизации блока 0 в счетчик блока 1 должен быть
записан ноль, то этот ноль запишется только на следующий такт после события
(см. рисунок 14.3б). Таким образом, при синхронизации от другого блока ШИМ нужно
всегда учитывать этот такт и записывать значение фазы, следующее по порядку, в
соответствии с режимом счета (см. рисунок 14.3в)
С уважением,
Лашкевич Максим.
Инженер-программист ООО "НПФ Вектор", Москва.
http://motorcontrol.ru/
Илья
Сообщения: 18
Зарегистрирован: 28 ноя 2018, 00:10
Предприятие: ЛЭМЗ

Re: Руководство по настройке и использованию открытого ПО

Сообщение Илья »

нет, в ерате про фазовый сдвиг ничего не сказано.
Но у меня другой вопрос изначально. Вопрос по работе АЦП. Чтоб не нарушить иерархию форума, я его задам в теме по АЦП
Ответить

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