Hello Friends J
The purpose of this
share is to help someone who's trying to utilize Arduino due’s greater performance +
lack of reference + non-helpful datasheet.
This
project is able to generate up to 3 phase sine wave @ 256 samples / cycle at
low freq (<1KHz) and 16 samples/cycle @ high freq (up to 20kHz), which is
good enough to be smoothed by simple LPFs and the output is almost perfect.
The
attached file was not my final version for I added some additional feature but
the core is same to that. Note the samples/cycle was set lower than above
statement.
Since
the CPU capacity is maximized through the approach shown in the attached file,
I used an Arduino Uno as control unit, who utilize Arduino Due's external
interrupt to pass frequency value to Arduino Due. In addition to frequency
control, the Arduino Uno also controls amplitude (through digital potential-meter + OpAmp) as well as I/O---there will be a lot of room to play
with.
Step 1: Generate sine data
array
Since real-time
calculation is CPU demanding, a sine data array is required for better
performance
uint32_t sin768 [] PROGMEM=....
while x= [0:5375]; y = 127+127*(sin (2*pi/5376/*or some # you prefer depends on requirement*/))
while x= [0:5375]; y = 127+127*(sin (2*pi/5376/*or some # you prefer depends on requirement*/))
Step 2: Enabling parallel
output
Unlike Arduino Uno, Due has
limited reference. However in order to generate 3 phase sine wave based on
Arduino Uno, 1st of all, performance is not applausable due to its low MCLK
(16MHz while Due is 84MHz), 2nd, it's limited GPIO can produce max 2 phase
output and you need additional analogue circuit to produce the 3rd phase
(C=-A-B).
Following GPIO enabling was mostly
based on try and trial+not helpful datasheet of SAM3X
PIOC->PIO_PER = 0xFFFFFFFE; //PIO
controller PIO Enable register (refer to p656 of ATMEL SAM3X datasheet) and Arduino
Due pin 33-41 and 44-51 were enabled
PIOC->PIO_OER = 0xFFFFFFFE; //PIO controller
output enable register, refer to p657 of ATMEL SAM3X datasheet PIOC->PIO_OSR
= 0xFFFFFFFE; //PIO controller output status register, refer to p658 of ATMEL
SAM3X datasheet
PIOC->PIO_OWER = 0xFFFFFFFE; //PIO
output write enable register, refer to p670 of ATMEL SAM3X datasheet
//PIOA->PIO_PDR = 0x30000000;
//optional as insurance, does not seem to affect performance, digital pin 10
connect to both PC29 and PA28, digital pin 4 connect to both PC29 and PA28,
here to disable PIOA #28 & 29
Step 3: Enabling interrupt
To maximize its
performance, CPU load should be as low as possible. However due to the non-1to1
correspondence between the CPU pin and the Due pin, bit operation is necessary.
You can further optimize the algorithm
but the room is very limited.
void TC7_Handler(void)
{ TC_Get Status(TC2,1);
{ TC_Get Status(TC2,1);
t = t%samples; //use t%samples instead
of 'if' to avoid overflow of t
PhaseAInc = (preset*t)%5376; //use
%5376 to avoid array index overflow
PhaseBInc = (phaseAInc+1792)%5376;
PhaseCInc = (phaseAInc+3584)%5376;
p_A = sin768 [phaseAInc]<<1;
//refer to PIOC: PC1 to PC8, corresponding Arduino Due pin: pin 33-40, hence
shift left for 1 digit
p_B = sin768 [phaseBInc]<<12;
//refer to PIOC: PC12 to PC19, corresponding Arduino Due pin: pin 51-44, hence
shift left 12 digit
p_C = sin768 [phaseCInc]; //phase C
output employee PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 and PC29,
corresponding Arduino Due pin: digital pin: 9, 8, 7,6,5,4,3,10, respectively.
p_C2 = (p_C&B11000000)<<22;
//this generates PC28 and PC29
p_C3 = (p_C&B00111111)<<21;
//this generates PC21-PC26
p_C = p_C2|p_C3; //this generates
parallel output of phase C
p_A = p_A|p_B|p_C; //32 bit output =
phase A (8bit) |phase B|phase C
PIOC->PIO_ODSR = p_A; //output
register =p_A
t++; }
Thanks and References
Hope you enjoyed this. If you have any
suggestion, than I am here to listen you.
For any other help you can visit this
site... https://www.robomart.com
No comments:
Post a Comment