步驟1:生成正弦數(shù)據(jù)數(shù)組
由于實(shí)時(shí)計(jì)算對(duì)CPU的要求很高,因此需要一個(gè)正弦數(shù)據(jù)數(shù)組以獲得更好的性能
uint32_t sin768 [] PROGMEM = 。..。
而x = [0:5375]; y = 127 + 127 *(sin(2 * pi/5376/*或您希望根據(jù)要求使用一些#*))
步驟2:?jiǎn)⒂貌⑿休敵?/p>
與Uno不同,Due具有有限的參考。但是,要基于Arduino Uno生成三相正弦波,首先,由于其MCLK低(16MHz,而Due是84MHz),因此性能不佳,第二,它的GPIO有限,可以產(chǎn)生最大2相輸出,您需要額外的模擬電路產(chǎn)生第三相(C = -AB)。
啟用GPIO的步驟主要是基于SAM3X的try and trial +無(wú)用數(shù)據(jù)表
PIOC-》 PIO_PER = 0xFFFFFFFE ;//PIO控制器PIO使能寄存器(請(qǐng)參閱ATMEL SAM3X數(shù)據(jù)表的p656)和http://arduino.cc/zh-CN/Hacking/PinMappingSAM3X、Arduino Due引腳33-41和44-51已啟用
PIOC-》 PIO_OER = 0xFFFFFFFE;//PIO控制器輸出使能寄存器,請(qǐng)參見ATMEL SAM3X數(shù)據(jù)手冊(cè)p657-》 PIO_OSR = 0xFFFFFFFE;//PIO控制器輸出狀態(tài)寄存器,請(qǐng)參閱ATMEL SAM3X數(shù)據(jù)表的p658
PIOC-》 PIO_OWER = 0xFFFFFFFE;//PIO輸出寫使能寄存器,請(qǐng)參閱ATMEL SAM3X數(shù)據(jù)表的p670
//PIOA-》 PIO_PDR = 0x30000000;//作為保險(xiǎn)是可選的,似乎并不影響性能,數(shù)字引腳10連接到PC29和PA28,數(shù)字引腳4連接到PC29和PA28,此處禁用禁用PIOA#28&29
步驟3:?jiǎn)⒂弥袛?/p>
為最大程度地發(fā)揮其性能,CPU負(fù)載應(yīng)盡可能低。但是,由于CPU引腳和Due引腳之間的非1to1對(duì)應(yīng)關(guān)系,需要進(jìn)行位操作。
您可以進(jìn)一步優(yōu)化算法,但空間非常有限。
void TC7_Handler(void)
{TC_GetStatus(TC2,1);
t = t%樣本;//使用t%samples而不是‘if’來(lái)避免t的溢出
phaseAInc =(preset * t)%5376;//使用%5376避免數(shù)組索引溢出
phaseBInc =(phaseAInc + 1792)%5376;
phaseCInc =(phaseAInc + 3584)%5376;
p_A = sin768 [phaseAInc] 《《1;//參考PIOC:PC1至PC8,對(duì)應(yīng)的Arduino Due引腳:引腳33-40,因此向左移1位
p_B = sin768 [phaseBInc] 《《12;//參考PIOC:PC12至PC19,對(duì)應(yīng)的Arduino Due引腳:引腳51-44,因此左移12位
p_C = sin768 [phaseCInc];//C相輸出使用PIOC:PC21,PC22,PC23,PC24,PC25,PC26,PC28和PC29,對(duì)應(yīng)的Arduino Due引腳:數(shù)字引腳:分別為9,8,7,6,5,4,3,10
p_C2 =(p_C&B11000000)《《22;//這會(huì)生成PC28和PC29
p_C3 =(p_C&B00111111)《《21;//這會(huì)生成PC21-PC26
p_C = p_C2 | p_C3;//這會(huì)產(chǎn)生C相的并行輸出
p_A = p_A | p_B | p_C;//32位輸出= A相(8位)| B相| C相
PIOC-》 PIO_ODSR = p_A;//輸出寄存器= p_A
t ++; }
第4步:R/2R DAC
構(gòu)建3x8bit R/2R DAC,在Google上加載參考。
步驟5:完整代碼
#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;//A相B相C值-盡管輸出僅8位,但p_A和p_B值將被操作以生成新的32位值,以應(yīng)對(duì)32位PIOC輸出
uint16_t phaseAInc,phaseBInc ,phaseCInc,freq,freqNew; uint32_t間隔; uint16_t個(gè)樣本,預(yù)設(shè); uint32_t t = 0;
void setup(){
//并行輸出PIOC設(shè)置:Arduino Due引腳33-40被用作A相輸出,而44-51引腳則用于A相B輸出
PIOC-》 PIO_PER = 0xFFFFFFFE;//PIO控制器PIO使能寄存器(請(qǐng)參閱ATMEL SAM3X數(shù)據(jù)表的p656)和http://arduino.cc/zh-CN/Hacking/PinMappingSAM3X、Arduino Due引腳33-41和44-51已啟用
PIOC-》 PIO_OER = 0xFFFFFFFE;//PIO控制器輸出使能寄存器,請(qǐng)參閱ATMEL SAM3X數(shù)據(jù)表的p657
PIOC-》 PIO_OSR = 0xFFFFFFFE;//PIO控制器輸出狀態(tài)寄存器,請(qǐng)參閱ATMEL SAM3X數(shù)據(jù)表的p658
PIOC-》 PIO_OWER = 0xFFFFFFFE;//PIO輸出寫使能寄存器,請(qǐng)參閱ATMEL SAM3X數(shù)據(jù)表的p670
//PIOA-》 PIO_PDR = 0x30000000;//作為保險(xiǎn),是可選的,似乎不影響性能,數(shù)字引腳10連接到PC29和PA28,數(shù)字引腳4連接到PC29和PA28,此處禁用禁用PIOA#28和29//定時(shí)器設(shè)置,請(qǐng)參閱http ://arduino.cc/en/Hacking/PinMappingSAM3X,
pmc_set_writeprotect(false);//禁用電源管理控制寄存器的寫保護(hù)
pmc_enable_periph_clk(ID_TC7);//啟用外設(shè)時(shí)鐘時(shí)間計(jì)數(shù)器7
TC_Configure(/*時(shí)鐘*/TC2,/*通道*/1,TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);//TC時(shí)鐘42MHz(時(shí)鐘,通道,比較模式設(shè)置)TC_SetRC(TC2,1,interval); TC_Start(TC2,1);
//在計(jì)時(shí)器TC2-》 TC_CHANNEL [1]上啟用計(jì)時(shí)器中斷。TC_IER= TC_IER_CPCS;//IER =中斷允許寄存器TC2-》 TC_CHANNEL [1] .TC_IDR =?TC_IER_CPCS;//IDR =中斷禁止寄存器
NVIC_EnableIRQ(TC7_IRQn);//在嵌套向量中斷控制器freq = 60中啟用中斷;//將頻率初始化為60Hz預(yù)設(shè)= 21;//數(shù)組索引增加21個(gè)樣本= 256;//輸出樣本256/周期間隔= 42000000/(頻率*樣本);//中斷計(jì)數(shù)TC_SetRC(TC2,1,interval);//啟動(dòng)TC Serial.begin(9600);//出于測(cè)試目的}
void checkFreq()
{freqNew = 20000;
if(freq == freqNew){}其他
{freq = freqNew;
if(freq》 20000){freq = 20000;/*最大頻率20kHz */};
,如果(freq 《1){freq = 1;/*最低頻率1Hz */};
如果(freq》 999){preset = 384;樣本= 14;}//對(duì)于頻率》 = 1kHz,每個(gè)周期14樣本
否則(freq》 499){preset = 84;樣本= 64;}//對(duì)于500 《=頻率《1000Hz,每個(gè)周期64個(gè)樣本,否則(freq》 99){preset = 42; samples = 128;}//對(duì)于100Hz 《= frequency 《500Hz,128個(gè)采樣/周期
else {preset = 21;樣本= 256;};//對(duì)于頻率《100hz,每個(gè)周期256個(gè)采樣
間隔= 42000000/(freq * samples); t = 0; TC_SetRC(TC2,1,間隔); }}
void loop(){
checkFreq();延遲(100); }
void TC7_Handler(void)
{TC_GetStatus(TC2,1);
t = t%樣本;//使用t%samples引起t phase的溢出AInc =(preset * t)%5376;//使用%5376避免數(shù)組索引溢出
phaseBInc =(phaseAInc + 1792)%5376;
phaseCInc =(phaseAInc + 3584)%5376;
p_A = sin768 [phaseAInc] 《《1;//參考PIOC:PC1至PC8,對(duì)應(yīng)的Arduino Due引腳:引腳33-40,因此向左移1位
p_B = sin768 [phaseBInc] 《《12;//參考PIOC:PC12至PC19,對(duì)應(yīng)的Arduino Due引腳:引腳51-44,因此左移12位
p_C = sin768 [phaseCInc];//C相輸出使用PIOC:PC21,PC22,PC23,PC24,PC25,PC26,PC28和PC29,對(duì)應(yīng)的Arduino Due引腳:數(shù)字引腳:分別為9,8,7,6,5,4,3,10
p_C2 =(p_C&B11000000)《《22;//這會(huì)生成PC28和PC29
p_C3 =(p_C&B00111111)《《21;//這將生成PC21-PC26//Serial.println(p_C3,BIN); p_C = p_C2 | p_C3;//這會(huì)產(chǎn)生C相的并行輸出
p_A = p_A | p_B | p_C;//32位輸出= A相(8位)| B相| C相////Serial.println(p_A》》21,BIN);//PIOC-》 PIO_ODSR = 0x37E00000;
PIOC-》 PIO_ODSR = p_A;//輸出寄存器= p_A t ++; }
責(zé)任編輯:wv
-
發(fā)生器
+關(guān)注
關(guān)注
4文章
1372瀏覽量
62061 -
Arduino
+關(guān)注
關(guān)注
188文章
6479瀏覽量
188725
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
在AFE5851外接一個(gè)正弦波發(fā)生器遇到的問(wèn)題求解
用DSP28335后接DAC7724產(chǎn)生三相正弦波信號(hào),隨負(fù)載加重DAC7724的輸出受到干擾怎么解決?
AN-2199003:ADSP-21990:生成三相正弦波PWM模式

ADS1254信號(hào)發(fā)生器輸出100Hz正弦波,顯示的波形中存在有規(guī)律的問(wèn)題,怎么處理?
MS37549/MS37545——三相無(wú)感正弦波 BLDC 驅(qū)動(dòng)

正弦波控制器速度怎么解碼
用LM324做了一個(gè)RC震蕩正弦波發(fā)生器,使用單電源供電時(shí)波形完全是雜亂的 ,怎么解決?
用tina-ti仿真文氏正弦波發(fā)生器沒(méi)有成功是哪里出了問(wèn)題?
數(shù)字信號(hào)發(fā)生器能夠提供哪些波形信號(hào)
信號(hào)發(fā)生器頻率怎么調(diào)
信號(hào)發(fā)生器的使用方法 信號(hào)發(fā)生器的幅值是有效值嗎
函數(shù)波形發(fā)生器的特點(diǎn)和應(yīng)用場(chǎng)景
為什么我這個(gè)濾波器濾不出來(lái)正弦波 而是三角波?
信號(hào)發(fā)生器有哪些用途
Spectrum儀器高速任意波形發(fā)生器DDS功能可生成20個(gè)正弦波

評(píng)論