基于Arduino Due的三相正弦波发生器的解析

步骤1:生成正弦数据数组
由于实时计算对cpu的要求很高,因此需要一个正弦数据数组以获得更好的性能
uint32_t sin768 [] progmem = 。..。
而x = [0:5375]; y = 127 + 127 *(sin(2 * pi/5376/*或您希望根据要求使用一些#*))
步骤2:启用并行输出
与uno不同,due具有有限的参考。但是,要基于arduino uno生成三相正弦波,首先,由于其mclk低(16mhz,而due是84mhz),因此性能不佳,第二,它的gpio有限,可以产生最大2相输出,您需要额外的模拟电路产生第三相(c = -ab)。
启用gpio的步骤主要是基于sam3x的try and trial +无用数据表
pioc-》 pio_per = 0xfffffffe ;//pio控制器pio使能寄存器(请参阅atmel sam3x数据表的p656)和http://arduino.cc/zh-cn/hacking/pinmappingsam3x、arduino due引脚33-41和44-51已启用
pioc-》 pio_oer = 0xfffffffe;//pio控制器输出使能寄存器,请参见atmel sam3x数据手册p657-》 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对应关系,需要进行位操作。
您可以进一步优化算法,但空间非常有限。
void tc7_handler(void)
{tc_getstatus(tc2,1);
t = t%样本;//使用t%samples而不是‘if’来避免t的溢出
phaseainc =(preset * t)%5376;//使用%5376避免数组索引溢出
phasebinc =(phaseainc + 1792)%5376;
phasecinc =(phaseainc + 3584)%5376;
p_a = sin768 [phaseainc] 《《1;//参考pioc:pc1至pc8,对应的arduino due引脚:引脚33-40,因此向左移1位
p_b = sin768 [phasebinc] 《《12;//参考pioc:pc12至pc19,对应的arduino due引脚:引脚51-44,因此左移12位
p_c = sin768 [phasecinc];//c相输出使用pioc:pc21,pc22,pc23,pc24,pc25,pc26,pc28和pc29,对应的arduino due引脚:数字引脚:分别为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;//这会产生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
构建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位值,以应对32位pioc输出
uint16_t phaseainc,phasebinc ,phasecinc,freq,freqnew; uint32_t间隔; uint16_t个样本,预设; uint32_t t = 0;
void setup(){
//并行输出pioc设置:arduino due引脚33-40被用作a相输出,而44-51引脚则用于a相b输出
pioc-》 pio_per = 0xfffffffe;//pio控制器pio使能寄存器(请参阅atmel sam3x数据表的p656)和http://arduino.cc/zh-cn/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(false);//禁用电源管理控制寄存器的写保护
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时钟42mhz(时钟,通道,比较模式设置)tc_setrc(tc2,1,interval); 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中启用中断;//将频率初始化为60hz预设= 21;//数组索引增加21个样本= 256;//输出样本256/周期间隔= 42000000/(频率*样本);//中断计数tc_setrc(tc2,1,interval);//启动tc serial.begin(9600);//出于测试目的}
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;}//对于频率》 = 1khz,每个周期14样本
否则(freq》 499){preset = 84;样本= 64;}//对于500 《=频率《1000hz,每个周期64个样本,否则(freq》 99){preset = 42; samples = 128;}//对于100hz 《= frequency 《500hz,128个采样/周期
else {preset = 21;样本= 256;};//对于频率《100hz,每个周期256个采样
间隔= 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避免数组索引溢出
phasebinc =(phaseainc + 1792)%5376;
phasecinc =(phaseainc + 3584)%5376;
p_a = sin768 [phaseainc] 《《1;//参考pioc:pc1至pc8,对应的arduino due引脚:引脚33-40,因此向左移1位
p_b = sin768 [phasebinc] 《《12;//参考pioc:pc12至pc19,对应的arduino due引脚:引脚51-44,因此左移12位
p_c = sin768 [phasecinc];//c相输出使用pioc:pc21,pc22,pc23,pc24,pc25,pc26,pc28和pc29,对应的arduino due引脚:数字引脚:分别为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;//这会产生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 ++; }


昌平哪个店能买到康德莱一次性无菌注射器带针
越南竹航到今年年底将会拥有50架飞机
干货 | PCB电路板短路了!试试这六种检查方法
中台战略的提出是出于怎样的目的
日本芯片制造商铠侠试图重启与西部数据合并谈判
基于Arduino Due的三相正弦波发生器的解析
人工智能的发展关键在“人”
韩国三大电池公司全年投资翻倍,突破16万亿韩元
电磁波与X光有什么不同?
基于仿真的自动驾驶可靠性估计(二)
工信部对促进移动通信转售行业高质量发展提出了四点意见
中移动加盟FDD 欲逼死联通电信?
腾达别墅路由nova荣获2017中国好WiFi“年度产品奖”
利普思SiC功率模块产品通过欧洲航空设备厂家验证
固态电容和钽电容二者之间的区别是什么
alanpoi import有何优势 怎么使用alanpoi实现导入
苹果公司宣布,将斥资10亿美元在美国德克萨斯州奥斯汀兴建第二个园区
多彩节能的夏日平板挑选法则
这么萌还不买?红米Note4X初音专属配色图赏
高、低端两头受敌,2013年高通面临大挑战