2021年全国大学生电子设计竞赛——信号失真度测量装置(A题)——设计过程分享(2)

一、前言
       电赛的第二天一般需要去确定最终的硬件电路,因为电路板的腐蚀和焊接都需要一定的时间,之后的硬件基本就不会再进行大改,最多都是在现有的基础上更改元件参数或者割线修改,之后即使功能不够理想也就是从软件的层面去进行补救。软件方面的任务是在第一天编写好的驱动上进行业务代码的和编写。

二、电赛第二日
       软件业务代码框架当时是这么设计的,如下。

while1{
	again:
	//delay(10); //设置pwm后由于滤波器的延时特性需要等待信号稳定再开始采集,这里是后面加入的。
	BeginAdc(); //开始ADC转换
	delay(10); //等待转换完成。也可以使用转换完成中断来同步
	ifAutoAdjustSignalVpp()//计算VPP,自动调整PWM
		goto again; //没有调整到位
	fft(); //做fft
	//计算完成之后进行显示等
}

       上面的代码逻辑中BeginAdc()已经在第一天就完成了,剩下的主要就是AutoAdjustSignalVpp()和fft()计算部分。先开始编写AutoAdjustSignalVpp的部分,根据采集的数据计算得到信号的Vpp值(可以找到最大和最小的五个值求平均后再相减进行计算),根据计算得到的Vpp和设定的值进行比较来判断是否调整到位。需要注意的是:这里的调整最好是做一个迟滞的效果,比如我的直流信号是1.235V(其实使用Vcc/2最好),因此我的判断条件就是下面这样的。比如信号幅值小于直流电压的0.6时,增大放大倍数,直到信号幅值大于直流电压的0.75时停止调整,这样就留了0.15的余量,防止由于测量误差导致信号在门槛边界来回跳动造成信号的不稳定。

/* AutoAdjustSignalVpp代码的逻辑图 */

#define VDC  1.235f /* 直流电压 */
/* 判断逻辑 */
uint8_t adj_sta;  /* 调整状态标志 */
if (!adj_sta) { /* 没在进行调整 */
	if (vpp/2 < VDC*0.6f) { /* 信号幅值太小 */
		adj_sta = 1; /* 增大放大倍数 */
	} else if (vpp/2 > VDC*0.9f) { /* 信号幅值太大 */
		adj_sta = 2; /* 减小放大倍数 */
	}
} else { /* 正在进行调整 */
	if (adj_sta  == 1) {
		if (vpp/2 < VDC*0.75f)
			setpwm(pwm_duty+1); /* 为了加快信号的调整速度可以参考我的源代码,分级调整 */
		else
			adj_sta  = 0;
	} else if (adj_sta  == 2) {
		if (vpp/2 > VDC*0.75f)
			setpwm(pwm_duty-1);
		else
			adj_sta  = 0;
	}
}

       当然上面的代码并不是一蹴而就的,我第二天的动态调整代码写的很烂,当时我在调整PWM的占空比是参考的TI的例子先将PWM输出关闭,然后设置PWM占空比再打开PWM,再立刻进行一次测量(就像之前代码框架中没有添加第一个delay一样)。这里就有了刚刚提到的一个问题,低通滤波器的延时问题,我关闭PWM的时候直流电压降为0,此时就会出现问题,当我重新打开PWM时,我没有进行delay(10)的延时就进行信号测量,导致信号测量的vpp十分的不稳定,也就使得我第二天编写的AutoAdjSignalVpp在实际测试的时候经常出现莫名奇妙的问题。
       虽然当时的自动调节代码写的很烂,但是大部分时候还是可以使用的,于是我不再纠结这个问题,抓紧时间开始编写fft的代码,由于fft变化的函数是库里面现成的,我就直接调用库函数进行计算,得到了转换之后的结果,此时我是使用1Mbps的采样率采样了1024个点的数据进行计算。结果自然是很不理想,立马分析原因如下,1M采样1024个点的采样时间为1.024ms,对应的频率分辨率为1/1.024ms=0.9765625kHz,这样的话由于频率的误差,基波的分量并不是1kHz的真实信号幅值,而是1kHz的信号泄漏到0.9765625kHz上的幅值。当时我认为1k-100k的频率要求,信号的频率步进应该是1kHz,也就是说测评给的信号应该是整数值而不是小数值,即类似1k、3k、25k等整数(测评要是来个1.5k我就凉了哈哈),所以我只要把信号的分辨率弄成1k即可,但是我又没办法进行1024k的采样,于是我就试了1M采集1000个点然后补零的方法,我先用sin函数进行模拟测试计算,效果很好。但是我用实际的信号输入进行采集后得到的效果却比较烂,反而不如之前的情况,现在想来也没搞懂怎么回事,毕竟网络上都说是补零的方法。
       然后我就想了另一个方法对采集的信号进行插值,具体的操作就是采集1000个点,然后在1000个点中插入24个点,插入的点的值为前后两个点的平均值,这样可以尽量的保证信号的原始状态。当然这个方法也是有它的缺点的,现在想来应该就是这个方法导致信号频率高了之后测量不准的情况。通过这个方法进行测量谐波分量时输入一个1k的正弦波时,计算得到的THD值为0.6%,精度大大的提高了,之前1M采集1024点的时候测量1k的正弦波THD值为3%。
       就当我搞定了基础部分要求,以为会很顺利的完成发挥部分的测量时,之前的提到的VCA810的坑让我花费了不少时间,此时时间为下午晚饭前。

三、填坑VCA810
       吃过晚饭之后想着顺利的话今天可以早点回去睡觉,果然是一个flag,吃完饭之后就是满满的不顺利直接干了一个通宵。
       先是进行了1kHz的频率下30-600Vpp的正弦信号输入后看测量值,以10mV的步进调整输入信号。这里就开始出现了问题,我们发现测量值的三次谐波会偏大,在输入信号的幅值改变的时候三次谐波的测量值也会跟着改变,在测量过程中最糟糕的情况时测量THD高达6%,最好的情况THD只有0.3%。这个情况的出现让我们措手不及,最开始以为是软件问题,但是用标准的测量仪表进行测量也是这个情况,于是确定是硬件问题。通过排查定位最终确定是VCA810在搞鬼,这可真是始料未及,由于之前没有使用过这个芯片,对其的细节特性不甚了解,没想到会出这个情况。这时我们就开始研究VCA810的数据手册,最终经过一段时间的研究发现了其中的问题,数据手册中提到VCA810会对信号的二次谐波和三次谐波产生影响,其中对二次谐波的影响很弱,但是对三次谐波的影响就比较强了,手册里面的图表如下我来分析一下。
2021年全国大学生电子设计竞赛——信号失真度测量装置(A题)——设计过程分享(2)_第1张图片

       Figure7显示了信号的频率和谐波失真关系,由于我们输入信号都是小于0.1M的这里就影响不大。Figure8显示输出负载对谐波失真的影响,由于运放输出时进的加法器,负载时两个分压电阻,阻值在几k的样子这个也问题不大。Figure9显示了输出电压和谐波失真的关系,这个和我们关系比较大,前面提到过1k频率下不同幅值的正弦波测量的THD值相差很大就是这个影响了结果,此时我们的电路放大倍数都是由VCA810来提供的,最终的信号为VCA810的输出Uo+1.235V,因此VCA810的输出信号峰峰值经过调整之后在1.6V到2V之间,图表里的上限为1V,我最低都调整到1.6V直接就爆表了,所以我的三次谐波也就放飞自我了。再看Figure10显示了放大倍数和谐波失真的关系,这里也影响了我不同幅值下的谐波测量,因为幅值不同放大倍数也就不同,趋势是放大倍数越大谐波失真越小。
       发现这个问题的时候已经是晚上半夜了,这时我们的板子都已经腐蚀完成了,如果此时再去调整硬件的方案的话无疑时时间上比较紧张的,最后我们还是决定硬着头皮上填上这个VCA810的坑,主要解决方式是就是减小VCA810的输出电压峰峰值。于是就调整了后面的加法器的比例关系,让原来的1+1改为3Ui+1Udc,这样前面的VCA810只需要输出0.6V的电压即可。相当于输入信号为600mVpp时VCA810增益为0dB,30mVpp时增益为13dB。最后更改完成的效果也比较理想,1kHz不同峰峰值的正弦波测试THD都在1%以下,说明硬件上的问题已经基本填完。
       填完VCA810的坑这时已经后半夜了,接着开始进行发挥部分的测试,毕竟之前的测试都是基于1k的频率下得,频率高了之后肯定还会出现其他的问题。

四、测量与记录
       后半夜刚刚解决了VCA810的坑,大家都在兴头之上没有睡意,然后就开始测试频率高了之后数据测量是否准确,测试结果就是频率越高测量值偏离越大。结果自然是令人十分的失望,但是经过几个小时的测量记录,还是有一些规律可循的,那就是误差值是和频率相关的,既然是频率相关的那么就可以进行数据的校准。
       测试完所有的情况和数据之后已经天光大亮,时间已经来到了第三天的白天,我们还是决定休息一下再开始下面的工作。

你可能感兴趣的:(大学生电子设计竞赛,单片机)