Если вы хотите генерировать синусоидальный сигнал с помощью микроконтроллера Xmega, самый простой способ сделать это - использовать фиксированную таблицу синусов, хранящуюся в памяти контроллера, таймер и PWM контроллера.
Принцип:
Таблица синусов содержит полное синусоидальный период. Для этой цели индивидуальные значения напряжения были рассчитаны с горизонтальным фиксированным размером шага с вертикальным разрешением 256 значений. Если эти значения последовательно выводятся с фиксированной частотой через модуль ШИМ с разрешающей способностью 8 бит, то есть 256 шагов, этот рабочий цикл будет меняться в зависимости от этой синусоиды. Так как Xmega работает при напряжении 3,3 В, амплитуда синусоидальной волны составляет +/- 1,65 В, при этом 1,65 В (значение таблицы 127) является виртуальным нулем. Скорость вывода задается частотой, установленной в таймере. Чем выше эта частота, тем выше частота синусоидальной волны.
Синусоидальная волна в таблице начинается с 127, что равно 0 (1.65 В). Затем градиент поднимается вверх, имеет максимум при 255 (3.3 В), снова идет вниз, проходит через 127 (1.65 В), затем достигает минимума 0 (0.0 В), а затем снова поднимается до начальной точки на 128 (1,65 В). После этого запуска весь процесс начинается снова с нового колебания.
Сгенерированный синусоидальный ШИМ-сигнал затем сглаживается с помощью фильтра нижних частот, то есть RC-элемента, с помощью которого получается аналоговое синусоидальное напряжение.
Принцип:
Таблица синусов содержит полное синусоидальный период. Для этой цели индивидуальные значения напряжения были рассчитаны с горизонтальным фиксированным размером шага с вертикальным разрешением 256 значений. Если эти значения последовательно выводятся с фиксированной частотой через модуль ШИМ с разрешающей способностью 8 бит, то есть 256 шагов, этот рабочий цикл будет меняться в зависимости от этой синусоиды. Так как Xmega работает при напряжении 3,3 В, амплитуда синусоидальной волны составляет +/- 1,65 В, при этом 1,65 В (значение таблицы 127) является виртуальным нулем. Скорость вывода задается частотой, установленной в таймере. Чем выше эта частота, тем выше частота синусоидальной волны.
Синусоидальная волна в таблице начинается с 127, что равно 0 (1.65 В). Затем градиент поднимается вверх, имеет максимум при 255 (3.3 В), снова идет вниз, проходит через 127 (1.65 В), затем достигает минимума 0 (0.0 В), а затем снова поднимается до начальной точки на 128 (1,65 В). После этого запуска весь процесс начинается снова с нового колебания.
Сгенерированный синусоидальный ШИМ-сигнал затем сглаживается с помощью фильтра нижних частот, то есть RC-элемента, с помощью которого получается аналоговое синусоидальное напряжение.
3-фазный синусоидальный генератор
Если вы хотите генерировать 3 синусоидальных сигнала, сдвинутых по фазе, все это следует тому же основному принципу, что и при использовании простого синусоидального сигнала. Дополнительные сигналы также генерируются с помощью двух дополнительных блоков ШИМ. Преимущество Xmega заключается в том, что с модулем PWM вы можете создавать до 4 PWM с разными рабочими циклами. Однако все эти ШИМ имеют один и тот же источник синхронизации, который заставляет их работать синхронно. Все, что вам нужно сделать, это обеспечить одновременное обновление всех трех PWM, а не только одной PWM. Сдвиг получается пуском всех трех сигналов ШИМ с другим значением в таблице синусов, см. Исходный код в качестве примера:
Если вы хотите генерировать 3 синусоидальных сигнала, сдвинутых по фазе, все это следует тому же основному принципу, что и при использовании простого синусоидального сигнала. Дополнительные сигналы также генерируются с помощью двух дополнительных блоков ШИМ. Преимущество Xmega заключается в том, что с модулем PWM вы можете создавать до 4 PWM с разными рабочими циклами. Однако все эти ШИМ имеют один и тот же источник синхронизации, который заставляет их работать синхронно. Все, что вам нужно сделать, это обеспечить одновременное обновление всех трех PWM, а не только одной PWM. Сдвиг получается пуском всех трех сигналов ШИМ с другим значением в таблице синусов, см. Исходный код в качестве примера:
#define TIMERRELOAD 256 #define AUFLOESUNG 65536 // 16-Bit Counter 65535 const uint8_t sinustabelle[512] PROGMEM = {127,130,133,136,139,143,146, 149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200, 203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239, 240,242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254, 254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242, 240,239,238,236,234,233,231,229,227,225,223,221,219,217,215,212,210,208,205, 203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152, 149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90, 87,84,81,78,76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27, 25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1, 1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,33,35,37,39,42, 44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108, 111,115,118,121,124,130,133,136,139,143,146,149,152,155,158,161,164,167,170, 173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219, 221,223,225,227,229,231,233,234,236,238,239,240,242,243,244,245,247,248,249, 249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252, 252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229, 227,225,223,221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184, 181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127, 124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,76,73,70,67,64,62,59, 56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9, 7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15, 16,18,20,21,23,25,27,29,31,33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70, 73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124}; volatile union {uint16_t u16; uint8_t u8[2];} counterA; volatile uint16_t offset; //######################################################### void sinus_setFreq(int Ausgabefrequenz) { offset=((F_CPU/2+Ausgabefrequenz*TIMERRELOAD*AUFLOESUNG)/F_CPU); /* F_CPU/2 fürs Runden */ } //######################################################### void sinus_init(void) { sbi(PORTF.DIR,0); sbi(PORTF.DIR,1); sbi(PORTF.DIR,2); /* Modus BIT0/1=Single Slope PWM BIT4=OCA, BIT5=OCB Enable */ TCF0.CTRLA = TC_CLKSEL_DIV1_gc; // Prescaler 1 TCF0.CTRLB = 0b11110011; TCF0.PER = 0x00ff; TCF0.CNT = 0x00; TCF0.INTCTRLA = 0b00000011; TCF0.CCA = 100; TCF0.CCB = 100; TCF0.CCC = 100; counterA.u16=0; } //######################################################### Int Timer F0 ISR(TCF0_OVF_vect) { TCF0.CCA = pgm_read_byte(&sinustabelle[counterA.u8[1]+ 0]); TCF0.CCB = pgm_read_byte(&sinustabelle[counterA.u8[1]+ 85]); TCF0.CCC = pgm_read_byte(&sinustabelle[counterA.u8[1]+171]); counterA.u16 += offset; } //######################################################### Main int main (void) { cli(); sinus_init(); PMIC.CTRL |= PMIC_HILVLEN_bm |PMIC_MEDLVLEN_bm|PMIC_LOLVLEN_bm; sei(); sinus_setFreq(150); while(1) { } }
0 коммент.:
Отправить комментарий