C#计算模数转换器(ADC)的参数DNL、INL、SNR等

1、ADC参数计算类

/// <summary>
        /// ADC参数(SNR、THD、SFDR、ENOB)计算
        /// </summary>
        /// <param name="source"></param>
        /// <param name="snr"></param>
        /// <param name="thd"></param>
        /// <param name="sfdr"></param>
        /// <param name="enob"></param>
        public static void AdcParameterCalculate(double[] source,out double snr,out double thd,out double sfdr,out double enob)
        {
            double P0 = 0;
            double P1 = 0;
            double PD = 0;
            double PN = 0;
            double PS = 0;
            for(int i=0; i<source.Length; i++)
            {
                if (i == 0)
                {
                    P0 = source[i];
                }else if (i == 1)
                {
                    P1 = source[i];
                }else if(i>1 && i<11)
                {
                    PD += source[i];
                    if (source[i] > PS)
                    {
                        PS = source[i];
                    }
                }
                else
                {
                    PN += source[i];
                    if (source[i] > PS)
                    {
                        PS = source[i];
                    }
                }
            }
            snr = 10 * Math.Log10(P1 / PN);
            thd = 10 * Math.Log10(PD / P1);
            sfdr = 10 * Math.Log10(P1 / PS);
            double sinad = 10 * Math.Log10(P1 / (PN + PD));
            enob = (sinad - 1.76) / 6.02;
        }

        /// <summary>
        /// ADC参数(DNL、INL)计算
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="bits"></param>
        /// <param name="scope"></param>
        /// <param name="dnl"></param>
        /// <param name="inl"></param>
        public static void AdcDnlAndInlCalculate(List<double> x,List<double> y, int bits,double scope,out double dnl,out double inl)
        {
            List<double> data = LinearRegression(x, y);
            double vlsb = GetVlsb(bits, scope);
            dnl = AdcDnl(x, y, vlsb);
            inl = AdcInl(data, y, vlsb);
            

        }
        /// <summary>
        /// 求和
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static double Sum(List<double> source)
        {
            double sum = 0;
            foreach(double d in source)
            {
                sum+= d;
            }
            return sum;
        }
        /// <summary>
        /// 平方和
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static double SumOfSquare(List<double> source)
        {
            double sum = 0;
            foreach (double d in source)
            {
                sum+= d*d;
            }
            return sum;
        }
        /// <summary>
        /// 交叉积和
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public static double SumOfCross(List<double> x, List<double> y)
        {
            double sum = 0;
            for(int i=0; i<x.Count; i++)
            {
                double d = x[i] * y[i];
                sum+= d;
            }
            return sum;
        }
        /// <summary>
        /// 用最小二乘法计算一元一次函数的参数
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public static void LeastSquareMethod(List<double> x, List<double> y,out  double a,out double b)
        {
            a = (SumOfSquare(x) * Sum(y) - Sum(x) * SumOfCross(x, y)) / (x.Count * SumOfSquare(x) - Sum(x) * Sum(x));
            b = (x.Count * SumOfCross(x, y) - Sum(x) * Sum(y)) / (x.Count * SumOfSquare(x) - Sum(x) * Sum(x));
        }
        /// <summary>
        /// 线性回归
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public static List<double> LinearRegression(List<double> x, List<double> y)
        {
            LeastSquareMethod(x, y, out double a, out double b);
            List<double> data = new List<double>();
            foreach (double d in x)
            {
                double z = a + b * d;
                data.Add(z);
            }
            return data;
        }
        /// <summary>
        /// 计算VLSB
        /// </summary>
        /// <param name="bits"></param>
        /// <param name="scope"></param>
        /// <returns></returns>
        public static double GetVlsb(int bits, double scope)
        {
            int count = (int)Math.Pow(2, bits);
            double d = (scope - 0) / (count - 1);
            //Console.WriteLine($"VLSB:{d}");
            return d;
        }
        /// <summary>
        /// 计算INL
        /// </summary>
        /// <param name="y1"></param>
        /// <param name="y"></param>
        /// <param name="vlsb"></param>
        /// <returns></returns>
        public static double AdcInl(List<double> y1, List<double> y, double vlsb)
        {
            double max = 0;
            for (int i = 0; i < y1.Count; i++)
            {
                double x = Math.Abs(y1[i] - y[i]);
                if (x > max) max = x;
            }
            double inl = max / vlsb;
            //Console.WriteLine($"INL:{inl}");
            return inl;
        }

        /// <summary>
        /// 计算DNL
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="vlsb"></param>
        /// <returns></returns>
        public static double AdcDnl(List<double> x, List<double> y, double vlsb)
        {
            double max = 0;
            for (int i = 1; i < x.Count; i++)
            {
                double d = Math.Abs(y[i] - y[i - 1]) / Math.Abs(x[i] - x[i - 1]);
                if (d > max) max = d;
            }
            double dnl = (max - vlsb) / vlsb;
            //Console.WriteLine($"DNL:{dnl}");
            return dnl;
        }

2、应用

private void AdcInitialize()
        {
            List<List<double>> idealData = IdealAdcData(4, 100);
            AdcDnlAndInlCalculate(idealData[0], idealData[1], 4, 100, out double dnl, out double inl);
            Console.WriteLine($"DNL:{dnl}");
            Console.WriteLine($"INL:{inl}");
            easyChartX2.Plot(idealData[1], 0, 1);
        }
double[] res = FFT.ButterflyFFT(data);
                        FFT.AdcParameterCalculate(res, out SNR, out THD, out SFDR, out ENOB);

其中data为数据

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大浪淘沙胡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值