国二【A题-安徽大学】一博学队—信号失真度测量装置
本题采用TI的TMS320F28035作为主控芯片,采用OPA695构成信号调理电路,将输入信号放大、偏移到主控芯片可接受的电压范围0-3.3V;对输入信号进行傅里叶分解,获得各次谐波分量幅值,得到总谐波失真率。
标签
嵌入式系统
DJZ___aaaa
更新2021-12-08
安徽大学
3459

视频补充中,后续上传

1、方案的选择与设计原理

1.1方案的选择与比较

由于输入信号为谐波信号,其峰峰值范围为30mV-600mV,基频频率为1kHz-100kHz,而TMS320F28335可处理的信号范围是0-3V,考虑到测量精度问题,输入信号必须经放大和偏移之后再送入TMS320F28335的ADC。我们通过理论分析确定了下述两个方案。

方案一:选择可调增益的一个放大电路,对不同的输入电压采用不同的放大倍数,让小信号的放大倍数尽可能大且满足要求。此方案可以根据信号的大小来合理的调整放大倍数,提高测量精度,但调试起来困难。

方案二:选择可调增益的两个放大电路,一个调为4倍,一个调为10倍,将信号同时输入两个放大电路中,两个输出放大信号给电压偏置1.5V,将两个输出与TMS320F28335相连,让TMS320F28335自行判断两端口输入信号峰峰值是否满足0-3.3V的范围,并选择合适的信号进行后续操作,此方案实时性好,测量精度高,操作简便。

综上所述,最终选择了方案二。

主体流程框架见图1

Fq3-k1X8cZkqw-0B-Lu7M6UzE_eX

图1 主体流程框架

2.硬件电路设计及仿真实验

2.1放大电路设计

考虑到信号谐波频率最大值为500kHz(5次谐波频率),所以设计的放大电路带宽应至少大于600kHZ,采用两个OPA695分别构成增益为4和10的放大电路,可以满足带宽要求。

10倍放大电路原理图如图2,幅频特性如图3所示:

4倍放大电路原理图如图4,幅频特性如图5所示:

Fs-XErbICihcKWTOJIM2qBhrzGAE

现以4倍放大电路为例,实验如下:

(1)输入信号,取不同值,频率取1kHZ,实验结果如表1所示:

FluvvE1BAaBNmDi2rcRk6J1RExem

(2)输入信号,取相同值,频率取不同值,实验结果如表2所示:

FlvZnmrGv2GT3wwjJzMxTuhSfSc8

可见,放大电路完全满足设计要求。

2.2偏移电路的设计

为了使被测信号的峰-峰值为TMS320F28335可接受的范围,设计偏移电路及仿真结果如图6和图7所示,该电路将放大后的信号偏移1.5V,为了使送给单片机的信号为正,本级采用单电源供电: 

FiwP-TbChHdlEZcp562Ajr6Y9LCH

与4倍放大电路经大电容级联后,输入信号,取不同值,频率取1kHZ,实验结果表3所示:

FnH8Bjf5kDkr5-1ZhVUTBxsz3uK5

2.3谐波信号放大实验

采用任意信号发生器产生的自编辑的谐波信号,见图8和图9,给设计的电路进行测试,改变信号基频频率和幅值,信号均可以得到正常放大,为了保护单片机输入端,在放大+偏移电路末端增加了二极管限幅电路,使输出的电压最大值都在单片机可处理范围。

Fi5zzEI7QCxyEBjcLBbJD5ht3hQm

3、THD检测原理

通过TMS320F28335的定时器控制DMA+ADC12采集模拟信号为数字信号于数组中,通过雷德算法和蝶形运算实现FFT,得到输出频域值。通过频域复数值的模计算和幅角计算得到频率相角数组。通过公式(3-9)进行THD计算,还需进行傅里叶反变换和归一化幅值计算,并在OLED屏幕上显示。程序框图如图10:

FlF3miKbCC8XrdNoWB3yKNtE6ODV

图10 程序框图

3.1 FFT算法原理:

FqaIFXFtzGcA2rLmr5OgUsQcABkX

3.2THD说明及计算公式:

FmQFoQ4jidJ40z5wgxCpEn4K9yrT

4.测量与显示结果

(1)输入信号Vipp取200mV,基频为1kHz-100kHZ的三角波,测量结果见表4。

FmZmLHqM50FBWVKERp-VmyB-UlEH

(2)输入信号Vipp取350mV,基频为1kHz-100kHZ的方波,测量结果见表5。

FgkuF8POSc-sq0MMb0yRnu3TS5bM

(3)输入信号Vipp取300mV,基频为1kHz-100kHZ的自编辑谐波(波形如图9所示),测量结果见表6。

Fh4N8AHXZv7UGGZZtntxILlnIgYq

实验结果表明,以上失真度测量与显示均不超过10秒。

(4)显示屏上显示方波失真度测量值THDx,见图13。

Fvroup7B9J9QtFcfISaA3n6nmnTy

图13  显示屏显示方波失真度测量值

(5)显示屏上显示输入一个信号的一个周期波形,见图14。

FjBbrAyO5B2XbY9us1SK1Gus7qI4

(6)显示输入信号基波与谐波的归一化幅值,只显示到 5 次谐波,见图15.

(7)手机显示测量装置测得并显示的输入信号THDx值、 基波与谐波的归一化幅值见图16. 

FsP4XualpQPJaWkd6lJvhnER_c6M

图16  手机显示

5.误差分析

(1)ADC采样有频率限制,当输入信号频率过大时,可能会有误差。

(2)FFT算法有频谱泄露现象,会造成各频点幅值下降。

(3)输入端有杂波的干扰,当输入为小信号时,容易受杂波的干扰。

(4)可能是芯片以及运放的引脚特性导致的,焊接不好也会导致有误差。

6.附录(代码)

FFT函数:
#include "fft.h"

void InitBufInArray()
{
    unsigned short i;
    float fx;
    for(i=0; i<NPT; i++)
    {
        fx = 1500 * sin(PI2 * i * 350.0 / Fs) + 2700 * sin(PI2 * i * 8400.0 / Fs) + 4000 * sin(PI2 * i * 18725.0 / Fs);

        lBufInArray[i].real = fx ;
        lBufInArray[i].imag = 0.0;
    }
}

void GetPowerMag(void)
{
    unsigned int i;
    for(i = 0;i < NPT/2;i++) //求变换后结果的模值,存入复数的实部部分
    {
        if(i==0)
            Mag[0]=sqrt(lBufInArray[i].real*lBufInArray[i].real+lBufInArray[i].imag*lBufInArray[i].imag)/NPT;
        else
            Mag[i]=sqrt(lBufInArray[i].real*lBufInArray[i].real+lBufInArray[i].imag*lBufInArray[i].imag)*2/NPT;
    }
}

struct compx EE(struct compx a,struct compx b)
{
    struct compx c;

    c.real=a.real*b.real-a.imag*b.imag;
    c.imag=a.real*b.imag+a.imag*b.real;

    return(c);
}

void FFT(struct compx *xin)
{
    int f,m,nv2,nm1,i,k,l,j=0;
    struct compx u,w,t;
    nv2=NPT/2;
    //变址运算,即把自然顺序变成倒位序,采用雷德算法
    nm1=NPT-1;
    for(i=0;i<nm1;i++)
    {
        if(i<j) //如果i<j,即进行变址
        {
            t=xin[j];
            xin[j]=xin[i];
            xin[i]=t;
        }
        k=nv2;
        //求j的下一个倒位序
        while(k<=j) //如果k<=j,表示j的最高位为1
        {
            j=j-k; //把最高位变成0
            k=k/2; //k/2,比较次高位,依次类推,逐个比较,直到某个位为0
        }
        j=j+k; //把0改为1
    }
    {
        int le,lei,ip;//FFT运算核,使用蝶形运算完成FFT运算
        f=NPT;
        for(l=1;(f=f/2)!=1;l++) ;//计算l的值,即计算蝶形级数////////
            for(m=1;m<=l;m++) // 控制蝶形结级数
            {
                                    //m表示第m级蝶形,l为蝶形级总数l=log(2)N
                le=2<<(m-1);         //le蝶形结距离,即第m级蝶形的蝶形结相距le点
                lei=le/2; //同一蝶形结中参加运算的两点的距离
                u.real=1.0; //u为蝶形结运算系数,初始值为1
                u.imag=0.0;
                w.real=cos(PI/lei); //w为系数商,即当前系数与前一个系数的商
                w.imag=-sin(PI/lei);
                for(j=0;j<=lei-1;j++) //控制计算不同种蝶形结,即计算系数不同的蝶形结
                {
                    for(i=j;i<=NPT-1;i=i+le) //控制同一蝶形结运算,即计算系数相同蝶形结
                    {
                        ip=i+lei; //i,ip分别表示参加蝶形运算的两个节点
                        t=EE(xin[ip],u); //蝶形运算,详见公式
                        xin[ip].real=xin[i].real-t.real;
                        xin[ip].imag=xin[i].imag-t.imag;
                        xin[i].real=xin[i].real+t.real;
                        xin[i].imag=xin[i].imag+t.imag;
                    }
                    u=EE(u,w); //改变系数,进行下一个蝶形运算
                }
            }
    }
}
、


THD函数
float THDcount(float *result)
{
    unsigned int i = 0, n = 2, m, t = 0, sum = 0;
    float THD = 0;
    max = result[1];
    for (i = 2; i < 128; i++)                              //gaile
    {
        if (result[i] > max)
        {
            max = result[i];
            t = i;
        }
    }
    sf = t;
    for (i = 1; i < 5; i++)
    {
        Noramp[i] = 0;
    }
    phase[0] = -atan2f(lBufInArray[t].imag, lBufInArray[t].real);
    m = t * n;
    while (m < 128 && n < 6)
    {
        Noramp[n - 1] = result[m] / max;
        phase[n - 1] = -atan2f(lBufInArray[m].imag, lBufInArray[m].real);
        sum = result[m] * result[m] + sum;
        n++;
        m = t * n;
    }
    THD = 100 * sqrt(sum) / max;
    //sum=sum/(max*max);
    // THD=100*sqrt(sum);
    return THD;
}



波形显示
void zhouqi(void)
{
    unsigned char i = 0;
    wave[i] =
            max
                    * (sin(2 * 3.141592653589793 * i / 60 + phase[0])
                            + Noramp[1]
                                    * sin(2 * 2 * 3.141592653589793 * i / 60
                                            + phase[1])
                            + Noramp[2]
                                    * sin(3 * 2 * 3.141592653589793 * i / 60
                                            + phase[2])
                            + Noramp[3]
                                    * sin(4 * 2 * 3.141592653589793 * i / 60
                                            + phase[3])
                            + Noramp[4]
                                    * sin(5 * 2 * 3.141592653589793 * i / 60
                                            + phase[4]));

    OLED_Clear();
    for (i = 1; i < 60; i++)
    {
        wave[i] = max
                * (sin(2 * 3.141592653589793 * i / 60 + phase[0])
                        + Noramp[1]
                                * sin(2 * 2 * 3.141592653589793 * i / 60
                                        + phase[1])
                        + Noramp[2]
                                * sin(3 * 2 * 3.141592653589793 * i / 60
                                        + phase[2])
                        + Noramp[3]
                                * sin(4 * 2 * 3.141592653589793 * i / 60
                                        + phase[3])
                        + Noramp[4] * sin(5 * 2 * 3.141592653589793 * i / 60

                        + phase[4]));
        OLED_DrawLine(i * 4 - 4, 60 - wave[i - 1] * 60 / 4096, 4 * i,
                      60 - wave[i] * 60 / 4096);
    }
}

 

 

 

 

附件下载
FFT算法原理以及THD说明及计算公式.docx
补充3.1及3.2:FFT算法原理以及3.2THD说明及计算公式
团队介绍
安徽大学,我们团队由一个大四和两个大三的组成
团队成员
居易乐天
Hkcul
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号