利用双通道示波器展示传输线行为的方法
2 直接数字合成
本文引用地址:https://www.eepw.com.cn/article/248900.htm为获得稳定的显示,就必须产生准确的频率。这里的“稳定”表示节点的水平位置或者驻波图案的最大或最小位置在屏幕上不移动。一种实现办法,采用具有数控振荡器(NCO)2的DDS。NCO采用一个16位计数器,称之为相位累加器,来实现。FCLOCK(图5)为一个固定的时钟频率递增量,Fcw为调制量或频率控制量。FCLOCK远远高于波形频率。
将相位累加器的高8位的值和正弦查找表(LUT)对应,然后将查找值发送至DAC。相位累加器中的值可认为对应的是一个圆上的某一个点;调制量定义为绕圆周的“步长”。调制量越大,绕圆周旋转的越快,因此输出的频率也越高。产生的频率由下式给出:
FOUT = FCW × FCLOCK/216
输出频率与FCW成正比。本例中,FCLOCK为31.25kHz。FCW值采用841、839和837,计算得到三个频率为:
F1=841×31250/65536= 401.02Hz
F2=839×31250/65536= 400.06Hz
F3=837×31250/65536= 399.11Hz
这里的频率表示采用保留两位小数,但实际上(F1 – F2和(F2 – F3)是完全相等的。频率差精确到9位小数时为0.953674316Hz。
3 实现
本演示使用Maxim® MAX5715 4通道12位数/模转换器(DAC)的三个通道来实现,由Arduino® Uno板上的Atmel® AVR处理器驱动。Arduino是一个开放的软硬件平台,对于基于AVR系统开发环境,非常方便。Maxim DAC通过SPI(串行外设接口)很容易和Arduino相连,AVR硬件支持SPI接口,Arduino软件库自带SPI驱动。运行Arduino 库中的SPI程序初始化AVR SPI硬件。也提供现存的SPI数据传输的程序,但速度太慢,未使用。
三个相位累加器采用16的位计数器,计数器递增是通过一个中断程序来实现,中断程序由处理器中的一个定时器来触发。每32µs (1/31.25kHz)中断一次。利用LUT将两个相位累加器值(生成F1和F3)转换为正弦值并然后送给DAC的两个通道。将第三个相位累加器(生成F2)的两个最高有效位发送至第三个DAC通道,产生一个4节拍的示波器触发信号。通过改变触发电平,可选择想要驻波的相位去进行开路或短路端接仿真。
Arduino SPI库中的数据传输程序太慢,导致中断程序的运行时间超过了中断周期。因此,改用直接写至AVR SPI硬件的代码。
中断程序代码:
//******************************************************************
// Timer2 Interrupt Service at 31372.550 Hz = 32uSec
// this is the timebase REFCLOCK for the DDS generator
// FOUT = (M (REFCLK)) / (2 exp 32)
ISR(TIMER2_OVF_vect) {
// set the SS line low
PORTB &= (0xFF ^ 4);
// send in the address and value via SPI:
SPDR = CODEA;
// update phase accumulators while waiting
phaccu_a += tword_a;
phaccu_b += tword_b;
phaccu_c += tword_c;
while (!(SPSR & _BV(SPIF)))
;
// do the table lookup based on accum 'a' high-order byte
SPDR = pgm_read_byte_near(sine256 + highByte(phaccu_a));
while (!(SPSR & _BV(SPIF)))
;
SPDR = 0;
while (!(SPSR & _BV(SPIF)))
;
// set the SS line high
PORTB |= 4;
// set the sS line low for the second SPI transfer
PORTB &= (0xFF ^ 4);
// do the second SPI transfer
//SPDR = CODEB_LOADALL;
SPDR = CODEB;
while (!(SPSR & _BV(SPIF)))
;
// do table lookup based on accum 'b'
SPDR = pgm_read_byte_near(sine256 + highByte(phaccu_b));
while (!(SPSR & _BV(SPIF)))
;
SPDR = 0;
while (!(SPSR & _BV(SPIF)))
;
评论