Mục lục:

Bộ tạo sóng hình sin 3 pha dựa trên Arduino Do: 5 bước
Bộ tạo sóng hình sin 3 pha dựa trên Arduino Do: 5 bước

Video: Bộ tạo sóng hình sin 3 pha dựa trên Arduino Do: 5 bước

Video: Bộ tạo sóng hình sin 3 pha dựa trên Arduino Do: 5 bước
Video: Tạo Xung PWM Với Arduino UNO R3 | Điện tử DAT 2024, Tháng bảy
Anonim
Bộ tạo sóng sin 3 pha dựa trên Arduino Do
Bộ tạo sóng sin 3 pha dựa trên Arduino Do

mục đích của chia sẻ này là để giúp một người nào đó đang cố gắng tận dụng hiệu suất cao hơn của Due + thiếu tài liệu tham khảo + biểu dữ liệu không hữu ích.

dự án này có thể tạo ra tối đa sóng sin 3 pha @ 256 mẫu / chu kỳ ở tần số thấp (<1kHz) và 16 mẫu / chu kỳ ở tần số cao (lên đến 20kHz), đủ tốt để được làm mượt bằng các LPF đơn giản và đầu ra gần như hoàn hảo.

tệp đính kèm không phải là phiên bản cuối cùng của tôi vì tôi đã thêm một số tính năng bổ sung nhưng cốt lõi vẫn giống như vậy. Lưu ý rằng các mẫu / chu kỳ được đặt thấp hơn tuyên bố trên.

vì dung lượng CPU được tối đa hóa thông qua cách tiếp cận được hiển thị trong tệp đính kèm, tôi đã sử dụng Arduino Uno làm đơn vị điều khiển, đơn vị này sử dụng ngắt bên ngoài của Arduino Due để chuyển giá trị tần số cho Arduino Due. Ngoài điều khiển tần số, Arduino Uno cũng điều khiển biên độ (thông qua máy đo điện thế kỹ thuật số + OpAmp) cũng như I / O --- sẽ có rất nhiều chỗ để chơi.

Bước 1: Tạo Mảng Dữ liệu Sine

Vì tính toán thời gian thực đòi hỏi CPU nên cần có mảng dữ liệu sin để có hiệu suất tốt hơn

uint32_t sin768 PROGMEM =…. trong khi x = [0: 5375]; y = 127 + 127 * (sin (2 * pi / 5376 / * hoặc một số # bạn thích tùy thuộc vào yêu cầu * /))

Bước 2: Bật đầu ra song song

Không giống như Uno, Due có giới hạn tham chiếu. Tuy nhiên, để tạo ra sóng sin 3 pha dựa trên Arduino Uno, trước hết, hiệu suất không được hoan nghênh do MCLK thấp (16MHz trong khi Do là 84MHz), thứ hai, GPIO giới hạn của nó có thể tạo ra đầu ra 2 pha tối đa và bạn cần bổ sung mạch tương tự để tạo ra pha thứ 3 (C = -AB).

Sau khi bật GPIO chủ yếu dựa trên thử và dùng thử + biểu dữ liệu không hữu ích của SAM3X

PIOC-> PIO_PER = 0xFFFFFFFE; // Bộ điều khiển PIO Kích hoạt thanh ghi PIO (tham khảo p656 của biểu dữ liệu ATMEL SAM3X) và https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Do chân 33-41 và 44-51 đã được bật

PIOC-> PIO_OER = 0xFFFFFFFE; // Thanh ghi cho phép đầu ra bộ điều khiển PIO, tham khảo p657 của biểu dữ liệu ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Thanh ghi trạng thái đầu ra của bộ điều khiển PIO, tham khảo p658 của biểu dữ liệu ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Thanh ghi cho phép ghi đầu ra PIO, tham khảo p670 của biểu dữ liệu ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // tùy chọn như bảo hiểm, dường như không ảnh hưởng đến hiệu suất, chân kỹ thuật số 10 kết nối với cả PC29 và PA28, chân kỹ thuật số 4 kết nối với cả PC29 và PA28, tại đây để vô hiệu hóa PIOA # 28 & 29

Bước 3: Bật ngắt

Để tối đa hóa hiệu suất của nó, tải CPU phải càng thấp càng tốt. Tuy nhiên do sự không tương ứng 1to1 giữa chân CPU và chân Do, hoạt động bit là cần thiết.

Bạn có thể tối ưu hóa thuật toán hơn nữa nhưng phòng rất hạn chế.

void TC7_Handler (void) {TC_GetStatus (TC2, 1);

t = t% mẫu; // sử dụng t% mẫu thay vì 'if' để tránh tràn t

phaseAInc = (đặt trước * t)% 5376; // sử dụng% 5376 để tránh tràn chỉ mục mảng

phaseBInc = (phaseAInc + 1792)% 5376;

phaseCInc = (phaseAInc + 3584)% 5376;

p_A = sin768 [phaseAInc] << 1; // tham chiếu đến PIOC: PC1 đến PC8, pin Do Arduino tương ứng: chân 33-40, do đó dịch chuyển sang trái cho 1 chữ số

p_B = sin768 [phaseBInc] << 12; // tham chiếu đến PIOC: PC12 đến PC19, tương ứng với Arduino Do pin: pin 51-44, do đó dịch chuyển sang trái 12 chữ số

p_C = sin768 [phaseCInc]; // đầu ra pha C sử dụng PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 và PC29, chân tương ứng Arduino Do: chân số: 9, 8, 7, 6, 5, 4, 3, 10, tương ứng

p_C2 = (p_C & B11000000) << 22; // điều này tạo ra PC28 và PC29

p_C3 = (p_C & B00111111) << 21; // điều này tạo ra PC21-PC26

p_C = p_C2 | p_C3; // điều này tạo ra đầu ra song song của pha C

p_A = p_A | p_B | p_C; // Đầu ra 32 bit = pha A (8bit) | pha B | pha C

PIOC-> PIO_ODSR = p_A; // thanh ghi đầu ra = p_A

t ++; }

Bước 4: R / 2R DAC

build 3x8bit R / 2R DAC, vô số ref trên google.

Bước 5: Mã đầy đủ

#define _BV (x) (1 << (x)); uint32_t sin768 PROGMEM = / * x = [0: 5375]; y = 127 + 127 * (sin (2 * pi / 5376)) * /

uint32_t p_A, p_B, p_C, p_C2, p_C3; // giá trị pha A pha B pha C - mặc dù đầu ra chỉ là 8 bit, giá trị p_A và p_B sẽ được vận hành để tạo ra giá trị 32 bit mới để đối phó với đầu ra PIOC 32 bit

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; khoảng thời gian uint32_t; uint16_t mẫu, cài đặt trước; uint32_t t = 0;

void setup () {

// Thiết lập PIOC đầu ra song song: Arduino Do chân 33-40 được sử dụng làm đầu ra pha A trong khi chân 44-51 hoạt động cho đầu ra pha B

PIOC-> PIO_PER = 0xFFFFFFFE; // Bộ điều khiển PIO Kích hoạt thanh ghi PIO (tham khảo p656 của biểu dữ liệu ATMEL SAM3X) và https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Do chân 33-41 và 44-51 đã được bật

PIOC-> PIO_OER = 0xFFFFFFFE; // Thanh ghi cho phép đầu ra bộ điều khiển PIO, tham khảo p657 của biểu dữ liệu ATMEL SAM3X

PIOC-> PIO_OSR = 0xFFFFFFFE; // Thanh ghi trạng thái đầu ra của bộ điều khiển PIO, tham khảo p658 của biểu dữ liệu ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Thanh ghi cho phép ghi đầu ra PIO, tham khảo p670 của biểu dữ liệu ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // tùy chọn như bảo hiểm, dường như không ảnh hưởng đến hiệu suất, chân kỹ thuật số 10 kết nối với cả PC29 và PA28, chân kỹ thuật số 4 kết nối với cả PC29 và PA28, tại đây để vô hiệu hóa PIOA # 28 & 29 // thiết lập bộ hẹn giờ, tham khảo https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (sai); // vô hiệu hóa tính năng bảo vệ ghi của các thanh ghi Điều khiển Quản lý Nguồn

pmc_enable_periph_clk (ID_TC7); // bật bộ đếm thời gian đồng hồ ngoại vi 7

TC_Configure (/ * clock * / TC2, / * channel * / 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // Đồng hồ TC 42MHz (đồng hồ, kênh, cài đặt chế độ so sánh) TC_SetRC (TC2, 1, khoảng thời gian); TC_Start (TC2, 1);

// bật ngắt bộ định thời trên bộ định thời TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = thanh ghi cho phép ngắt TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = ngắt thanh ghi vô hiệu hóa

NVIC_EnableIRQ (TC7_IRQn); // Kích hoạt ngắt trong bộ điều khiển ngắt vector lồng nhau freq = 60; // khởi tạo tần số là 60Hz đặt trước = 21; // chỉ số mảng tăng 21 mẫu = 256; // xuất mẫu 256 / khoảng chu kỳ = 42000000 / (freq * mẫu); // đếm ngắt TC_SetRC (TC2, 1, khoảng thời gian); // khởi động TC Serial.begin (9600); // cho mục đích thử nghiệm}

void checkFreq ()

{freqNew = 20000;

if (freq == freqNew) {} else

{freq = freqNew;

if (freq> 20000) {freq = 20000; / * tần số tối đa 20kHz * /};

if (freq <1) {freq = 1; / * tần số tối thiểu 1Hz * /};

if (freq> 999) {preset = 384; mẫu = 14;} // cho tần số> = 1kHz, 14 mẫu cho mỗi chu kỳ

else if (freq> 499) {preset = 84; sample = 64;} // for 500 <= frequency99) {preset = 42; mẫu = 128;} // cho 100Hz <= tần số <500Hz, 128 mẫu / chu kỳ

else {đặt trước = 21; mẫu = 256;}; // cho tần số <100hz, 256 mẫu cho mỗi chu kỳ

khoảng = 42000000 / (freq * mẫu); t = 0; TC_SetRC (TC2, 1, khoảng thời gian); }}

void loop () {

checkFreq (); chậm trễ (100); }

void TC7_Handler (vô hiệu)

{TC_GetStatus (TC2, 1);

t = t% mẫu; // sử dụng t% mẫu để tránh tràn t phaseAInc = (preset * t)% 5376; // sử dụng% 5376 để tránh tràn chỉ mục mảng

phaseBInc = (phaseAInc + 1792)% 5376;

phaseCInc = (phaseAInc + 3584)% 5376;

p_A = sin768 [phaseAInc] << 1; // tham chiếu đến PIOC: PC1 đến PC8, pin Do Arduino tương ứng: chân 33-40, do đó dịch chuyển sang trái cho 1 chữ số

p_B = sin768 [phaseBInc] << 12; // tham chiếu đến PIOC: PC12 đến PC19, tương ứng với Arduino Do pin: pin 51-44, do đó dịch chuyển sang trái 12 chữ số

p_C = sin768 [phaseCInc]; // đầu ra pha C sử dụng PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 và PC29, tương ứng chân Arduino Do: chân số: 9, 8, 7, 6, 5, 4, 3, 10, tương ứng

p_C2 = (p_C & B11000000) << 22; // điều này tạo ra PC28 và PC29

p_C3 = (p_C & B00111111) << 21; // điều này tạo ra PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // điều này tạo ra đầu ra song song của pha C

p_A = p_A | p_B | p_C; // Ngõ ra 32 bit = phase A (8bit) | phase B | phase C //Serial.println(p_A>>21, BIN); // PIOC-> PIO_ODSR = 0x37E00000;

PIOC-> PIO_ODSR = p_A; // xuất thanh ghi = p_A t ++; }

Đề xuất: