Мазмуну:
- 1 -кадам: Sine маалыматтар массивин түзүү
- 2 -кадам: Параллелдүү чыгарууну иштетүү
- 3 -кадам: Үзгүлтүктү иштетүү
- 4 -кадам: R/2R DAC
- 5 -кадам: Толук код
Video: 3 фазалуу синус толкун генератору Arduino Due негизделген: 5 кадам
2024 Автор: John Day | [email protected]. Акыркы өзгөртүү: 2024-01-30 10:40
Бул үлүштүн максаты Due'дин көбүрөөк иштөөсүн + маалымдаманын жоктугун + пайдалуу эмес маалымат баракчасын колдонууга аракет кылып жаткан бирөөгө жардам берүү.
Бул проект 3 фазалуу синус толкуну @ 256 үлгүлөрдү / циклди төмөнкү жыштыкта (<1kHz) жана 16 үлгүлөрдү / циклде @ жогорку жыштыкта (20 кГцке чейин) түзө алат, бул жөнөкөй LPFлер жана тегиздөө үчүн жетиштүү. чыгаруу дээрлик идеалдуу.
тиркелген файл менин акыркы версиям эмес болчу, анткени мен кээ бир кошумча функцияларды коштум, бирок өзөгү буга окшош. Үлгү/цикл жогорудагы билдирүүдөн төмөн коюлганына көңүл буруңуз.
CPU кубаттуулугу тиркелген файлда көрсөтүлгөн ыкма аркылуу максималдаштырылгандыктан, мен Arduino Uno башкаруу бирдиги катары колдондум, ал Arduino Due жыштыгынын маанисин өткөрүп берүү үчүн Arduino Due тышкы үзгүлтүгүн колдонот. Жыштыкты контролдоодон тышкары, Arduino Uno амплитудасын да башкарат (санарип потенциал-метр + OpAmp аркылуу), ошондой эле I/O --- менен ойной турган көп орун болот.
1 -кадам: Sine маалыматтар массивин түзүү
Реалдуу убакытта эсептөө CPU талап кылгандыктан, жакшыраак иштөө үчүн синустук маалымат массиви талап кылынат
uint32_t sin768 PROGMEM =…. while x = [0: 5375]; y = 127+127*(күнөө (2*pi/5376/*же сиз каалаган # # талапка жараша болот//))
2 -кадам: Параллелдүү чыгарууну иштетүү
Unoдон айырмаланып, Due чектелген маалыматка ээ. Бирок, Arduino Uno негизинде 3 фазалуу синус толкунду жаратуу үчүн, биринчиден, MCLKнин төмөндүгүнөн (16 МГц, 84 МГц болгондо) аткаруу кол чабууга болбойт, экинчиден, чектелген GPIO 2 фазалуу өндүрүштү өндүрө алат жана сизге кошумча керек 3-фазаны өндүрүү үчүн аналогдук схема (C = -AB).
GPIO иштетүүдөн кийин, негизинен, SAM3X боюнча пайдалуу эмес, текшерүү жана сыноо негизделген
PIOC-> PIO_PER = 0xFFFFFFFE; // PIO контроллери PIO Enable register (ATMEL SAM3X маалымат барагынын p656-на кайрылыңыз) жана https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 жана 44-51 иштетилген
PIOC-> PIO_OER = 0xFFFFFFFE; // PIO контроллеринин өндүрүмүн иштетүү реестри, ATMEL SAM3X маалымат барагынын p657 караңыз PIOC-> PIO_OSR = 0xFFFFFFFE; // PIO контроллеринин чыгуу статусунун реестри, ATMEL SAM3X маалымат барагынын p658ине кайрылыңыз
PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO чыгаруу жазууну иштетүү реестри, ATMEL SAM3X маалымат барагынын p670ине кайрылыңыз
// PIOA-> PIO_PDR = 0x30000000; // камсыздандыруу катары милдеттүү эмес, өндүрүмдүүлүккө таасир этпейт окшойт, санарип пин 10 PC29 менен PA28ге туташат, санарип пин 4 PC29 менен PA28ге туташат, бул жерде PIOA #28 & 29 өчүрүү үчүн
3 -кадам: Үзгүлтүктү иштетүү
Анын аткарылышын максималдаштыруу үчүн, CPU жүктөмү мүмкүн болушунча аз болушу керек. Бирок CPU пини менен Due пиндин ортосундагы 1to1 эмес жазышуулардан улам, бит операциясы зарыл.
Алгоритмди андан ары оптималдаштырсаңыз болот, бирок бөлмө өтө чектелген.
жараксыз TC7_Handler (боштук) {TC_GetStatus (TC2, 1);
t = t%үлгүлөрү; // t ашпаш үчүн 'if' ордуна t%үлгүлөрүн колдонуңуз
PhaseAInc = (алдын ала коюлган*t)%5376; // массивдин индексинин толуп кетпеши үчүн %5376 колдонуңуз
PhaseBInc = (PhaseAInc+1792)%5376;
PhaseCInc = (PhaseAInc+3584)%5376;
p_A = sin768 [PhaseAInc] << 1; // PIOCко кайрылыңыз: PC1ден PC8ге, тиешелүү Arduino байланыштуу пин: пин 33-40, демек солго 1 цифрага солго
p_B = sin768 [PhaseBInc] << 12; // PIOCко кайрылыңыз: PC12ден PC19га, тиешелүү Arduino байланыштуу пин: пин 51-44, демек солго 12 сан
p_C = sin768 [PhaseCInc]; // этап C чыгаруу PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 жана PC29, тиешелүү Arduino байланыштуу пин: санарип пин: 9, 8, 7, 6, 5, 4, 3, 10, тиешелүүлүгүнө жараша
p_C2 = (p_C & B11000000) << 22; // бул PC28 жана PC29 түзөт
p_C3 = (p_C & B00111111) << 21; // бул PC21-PC26 түзөт
p_C = p_C2 | p_C3; // бул С фазасынын параллелдүү чыгарылышын жаратат
p_A = p_A | p_B | p_C; // 32 бит чыгаруу = фаза А (8бит) | фаза В | фаза
PIOC-> PIO_ODSR = p_A; // чыгаруу реестри = p_A
t ++; }
4 -кадам: R/2R DAC
3x8bit R/2R DAC түзүңүз, Google'да көптөгөн реф.
5 -кадам: Толук код
#define _BV (x) (1 << (x)); uint32_t sin768 PROGMEM = /* x = [0: 5375]; y = 127+127*(күнөө (2*pi/5376))*/
uint32_t p_A, p_B, p_C, p_C2, p_C3; // фаза А фазасы В фазасы С мааниси-чыгаруу 8 бит гана болсо да, p_A жана p_B мааниси 32 биттик PIOC чыгаруу менен күрөшүү үчүн жаңы 32 биттик маанини түзүү үчүн иштетилет.
uint16_t PhaseAInc, PhaseBInc, PhaseCInc, Freq, FreqNew; uint32_t интервал; uint16_t үлгүлөрү, алдын ала коюлган; uint32_t t = 0;
жараксыз орнотуу () {
// параллелдүү чыгаруу PIOC орнотуусу: Arduino Due pin33-40 фаза А чыгаруу катары колдонулат, ал эми pin 44-51 B фазасы үчүн иштейт
PIOC-> PIO_PER = 0xFFFFFFFE; // PIO контроллери PIO иштетүү реестри (ATMEL SAM3X маалымат барагынын p656-на кайрылыңыз) жана https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due пин 33-41 жана 44-51 иштетилген
PIOC-> PIO_OER = 0xFFFFFFFE; // PIO контроллеринин чыгуусу регистрди иштетет, ATMEL SAM3X маалымат барагынын p657 -ге кайрылыңыз
PIOC-> PIO_OSR = 0xFFFFFFFE; // PIO контроллеринин чыгуу статусунун реестри, ATMEL SAM3X маалымат барагынын p658ине кайрылыңыз
PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO чыгаруу жазууну иштетүү реестри, ATMEL SAM3X маалымат барагынын p670ине кайрылыңыз
// PIOA-> PIO_PDR = 0x30000000; // камсыздандыруу катары милдеттүү эмес, өндүрүмдүүлүккө таасир этпейт окшойт, санарип пин 10 PC29 менен PA28ге туташат, санариптик пин 4 PC29 менен PA28ге туташат, бул жерде PIOA #28 & 29ду өчүрүү үчүн таймерди орнотуу үчүн, httpге кайрылыңыз.: //arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (жалган); // Power Management Control регистрлеринин жазууну коргоону өчүрүү
pmc_enable_periph_clk (ID_TC7); // четки сааттык убакытты эсептегичти иштетүү 7
TC_Configure (/ * саат */TC2,/ * канал */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // TC сааты 42МГц (саат, канал, режимди салыштыруу) TC_SetRC (TC2, 1, интервал); TC_Start (TC2, 1);
// таймердеги тыныгууларды иштетүү TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = үзгүлтүктү иштетүү реестри TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = реестрди үзгүлтүккө учуратуу
NVIC_EnableIRQ (TC7_IRQn); // Киргизилген вектордук үзгүлтүк контроллериндеги үзүүнү иштетүү freq = 60; // жыштыгы 60 Гц алдын ала коюлган = 21 катары инициализациялоо; // массивдин индекси 21 үлгүгө көбөйөт = 256; // чыгаруу үлгүлөрү 256/цикл аралыгы = 42000000/(freq*үлгүлөрү); // үзгүлтүк санап TC_SetRC (TC2, 1, интервал); // баштоо TC Serial.begin (9600); // сыноо максатында}
void checkFreq ()
{freqNew = 20000;
if (freq == freqNew) {} башка
{freq = freqNew;
if (freq> 20000) {freq = 20000; /*максималдуу жыштыгы 20 кГц*/};
if (freq <1) {freq = 1; /*мүн жыштыгы 1Гц*/};
if (freq> 999) {алдын ала коюлган = 384; үлгүлөр = 14;} // жыштык үчүн> = 1кГц, ар бир цикл үчүн 14 үлгү
else if (freq> 499) {preset = 84; үлгүлөр = 64;} // 500 үчүн <= жыштык99) {алдын ала коюлган = 42; үлгүлөр = 128;} // 100Гц үчүн <= жыштыгы <500Гц, 128 үлгү/цикл
else {preset = 21; үлгүлөр = 256;}; // жыштык үчүн <100Гц, ар бир цикл үчүн 256 үлгү
интервал = 42000000/(freq*үлгүлөрү); t = 0; TC_SetRC (TC2, 1, интервал); }}
void loop () {
checkFreq (); кечиктирүү (100); }
жараксыз TC7_Handler (жараксыз)
{TC_GetStatus (TC2, 1);
t = t%үлгүлөрү; // t fazAInc = (алдын ала орнотулган*t)%5376 алдын алуу үчүн t%үлгүлөрүн колдонуңуз; // массивдин индексинин толуп кетпеши үчүн %5376 колдонуңуз
PhaseBInc = (PhaseAInc+1792)%5376;
PhaseCInc = (PhaseAInc+3584)%5376;
p_A = sin768 [PhaseAInc] << 1; // PIOCко кайрылыңыз: PC1ден PC8ге, тиешелүү Arduino байланыштуу пин: пин 33-40, демек солго 1 цифрага солго
p_B = sin768 [PhaseBInc] << 12; // PIOCко кайрылыңыз: PC12ден PC19га, тиешелүү Arduino байланыштуу пин: пин 51-44, демек солго 12 сан
p_C = sin768 [PhaseCInc]; // фаза С чыгаруу PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 жана PC29, тиешелүү Arduino байланыштуу пин: санариптик пин: 9, 8, 7, 6, 5, 4, 3, 10, тиешелүүлүгүнө жараша
p_C2 = (p_C & B11000000) << 22; // бул PC28 жана PC29 түзөт
p_C3 = (p_C & B00111111) << 21; // бул PC21-PC26 //Serial.println(p_C3, BIN) жаратат; p_C = p_C2 | p_C3; // бул С фазасынын параллелдүү чыгарылышын жаратат
p_A = p_A | p_B | p_C; // 32 бит чыгаруу = фаза А (8бит) | фаза В | фаза C //Serial.println(p_A>>21, БИН); // PIOC-> PIO_ODSR = 0x37E00000;
PIOC-> PIO_ODSR = p_A; // чыгаруу реестри = p_A t ++; }
Сунушталууда:
Таза синус толкун инвертору: 8 кадам
Таза синус толкун инвертору: Менин изилдөөм
Arduino толкун формасынын генератору: 5 кадам (сүрөттөр менен)
Arduino Waveform Генератору: 2021 -жылдын февраль жаңыртуусу: Raspberry Pi Pico негизделген 300x үлгү алуу ылдамдыгы менен жаңы версиясын карап көрүңүз. Бул күчөткүчтү сыноо, чынжырын текшерүү болушу мүмкүн
Аба ырайына негизделген музыка генератору (ESP8266 негизделген Midi генератору): 4 кадам (сүрөттөр менен)
Аба ырайына негизделген музыка генератору (ESP8266 негизделген Midi генератору): Саламатсызбы, мен бүгүн өзүңүздүн кичинекей аба ырайына негизделген музыкалык генераторду кантип жасоону түшүндүрүп берем. жана жарыктын интенсивдүүлүгү. Бул бүтүндөй ырларды же аккорд программасын түзөт деп күтпөңүз
Төмөн наркы толкун формасынын генератору (0 - 20МГц): 20 кадам (сүрөттөр менен)
Төмөн наркы толкун формасынын генератору (0 - 20МГц): КЫСКАЧА Бул долбоор өткөрүү ылдамдыгы 10 МГцтен ашкан толкун генераторун жана 1%га чейинки гармоникалык бурмалоону алуу зарылчылыгынан келип чыгат, мунун баары арзан баада. Бул документ толкун генераторунун конструкциясын сүрөттөйт
Fast Edge Square толкун генератору: 4 кадам
Fast Edge Square Wave Generator: Эгерде сиз кандайдыр бир компоненттин индуктивдүүлүгүн, сыйымдуулугун өлчөөнү кааласаңыз, анда бул макалада тез кырдуу толкун керек, биз бул жөнүндө билебиз