Найти в Дзене
Groul

Преобразование аналогового сигнала в цифровой вид. Дискретное преобразование Фурье.

Данная статья основана на лабораторной работе, сделанной мною. В ней я разберу выполнение преобразований с прикреплением программного кода. Техническое задание: задан аналоговый сигнал со своими параметрами. Необходимо разработать программное обеспечение, которое производит преобразования аналогового сигнала в цифровой вид. Параметры аналогового сигнала: a = 1 (1/с); T = 0.8 мкс Функционал программы: 1. Построение графика аналогового сигнала. 2. Определение граничной частоты (верхней частоты) аналогового сигнала. 3. Определение частоты дискретизации аналогового сигнала. 4. Генерирование дискретного сигнала и построение его графика. 5. Выполнение квантование дискретного сигнала с шагом, соответствующим представлению отсчетов 4-битным числом. 6. Построение графика квантованного сигнала. 7. Вычисление погрешности квантования. Построение графика погрешности. 8. Определение коэффициентов ДПФ. 9. Восстановление аналогового сигнала по значениям цифрового сигнала. 10. Построение и сравнение гр
Оглавление

Данная статья основана на лабораторной работе, сделанной мною. В ней я разберу выполнение преобразований с прикреплением программного кода.

Техническое задание: задан аналоговый сигнал со своими параметрами. Необходимо разработать программное обеспечение, которое производит преобразования аналогового сигнала в цифровой вид.

Параметры аналогового сигнала:

Функция, описывающая сигнал
Функция, описывающая сигнал

a = 1 (1/с);

T = 0.8 мкс

Функционал программы:

1. Построение графика аналогового сигнала.

2. Определение граничной частоты (верхней частоты) аналогового сигнала.

3. Определение частоты дискретизации аналогового сигнала.

4. Генерирование дискретного сигнала и построение его графика.

5. Выполнение квантование дискретного сигнала с шагом, соответствующим представлению отсчетов 4-битным числом.

6. Построение графика квантованного сигнала.

7. Вычисление погрешности квантования. Построение графика погрешности.

8. Определение коэффициентов ДПФ.

9. Восстановление аналогового сигнала по значениям цифрового сигнала.

10. Построение и сравнение графиков исходного аналогового сигнала с восстановленным.

Процесс создания программы:

Программа будет создаваться на языке c# в Microsoft Visual Studio, в Windows Forms.

Начнем создание с интерфейса программы. Мы создадим 4 chart`а, в которых будем строить необходимые графики. Также создадим кнопку, при помощи которой будем запускать вычисления.

Интерфейс программы
Интерфейс программы

Написание программного кода

1. Построение графика аналогового сигнала.

Для этого нам нужно реализовать метод, описывающий сигнал

double FunctionSt(double arg)

{

return (Math.Pow(arg, 4));

}

Далее используя его, мы можем отрисовать исходный аналоговый сигнал. Его нам надо отрисовать в двух chart`ах.

void PrintGrafAnalogSignal(double T)

{

for (double i=0; i<T; i+=0.1)

{

chart1.Series[0].Points.AddXY(i, FunctionSt(i));

chart4.Series[1].Points.AddXY(i, FunctionSt(i));

}

}

Полученный аналоговый сигнал
Полученный аналоговый сигнал

2. Определение граничной частоты (верхней частоты) аналогового сигнала.

Энергия, сосредоточенная в полосе частот [0¸wk], определяется следующим соотношением:

-5
Потеря энергии не должна быть более 2%
Потеря энергии не должна быть более 2%

А энергия сигнала равна:

-7

Для того чтобы посчитать энергию сигнала мы создадим следующие методы:

  • Квадрат нашей функции сигнала.

double FunctionSqrSt(double arg)

{

return (FunctionSt(arg) * FunctionSt(arg));

}

  • Метод для интегрирования (будем использовать метод прямоугольников).

private double Rectangle(double a, double b, double n, Func func)

{

double h = (b - a) / n;

double res = 0;

for (double i = a; i <= b; i += h)

{

res += h * func(i + (h / 2));

}

return res;

}

  • Метод, подсчитывающий энергию сигнала.

double TakeEc(double a, double b)

{

return Rectangle(a, b, 100, FunctionSqrSt);

}

  • И последнее – нам необходимо рассчитывать |S(jw)^2|. Для создадим следующие методы:

double FunctionModSjw(double arg)

{

return Math.Sqrt(Math.Pow(Re(arg), 2) + Math.Pow(Im(arg), 2));

}

double Re(double arg)

{

return (24 * Sin(arg * T) - 24 * arg * T * Cos(arg * T) - 12 * Math.Pow(arg, 2) * Math.Pow(T, 2) * Sin(arg * T)+ 4 * Math.Pow(arg, 3) * Math.Pow(T, 3) * Cos(arg * T) + Math.Pow(arg, 4)* Math.Pow(T, 4)* Sin(arg*T))/ Math.Pow(arg, 5);

}

double Im(double arg)

{

return (24 * Cos(arg * T) + 24 * arg * T * Sin(arg * T) - 12 * Math.Pow(arg, 2) * Math.Pow(T, 2) * Cos(arg * T) - 4 * Math.Pow(arg, 3) * Math.Pow(T, 3) * Sin(arg * T) + Math.Pow(arg, 4) * Math.Pow(T, 4) * Cos(arg * T) - 24) / Math.Pow(arg, 5);

}

Что это и откуда это взялось?

Одиночный импульс может быть представлен как во временной области, так и в частотной. Переход из временной в частотную область осуществляется с помощью прямого преобразования Фурье:

-8

S(jw) – спектральная плотность сигнала, является комплексной величиной. Чтобы ее посчитать нам необходимо провести интегрирования. Так как мы рассматриваем определенный сигнал и не пишем универсальную программу, то мы можем просто посчитать ее с помощью MathCad.

Спектральную плотность можно выразить через модуль (амплитудный спектр |S(jw)|) и аргумент (фазовый спектр ф(t)), в данный момент нам необходим модуль:

-9

Re(S(jw)), Im(S(jw)) – вещественная и мнимая части спектральной плотности S(jw).

Теперь мы может написать метод рассчитывающий граничную частоту:

double TakeWk(double Ec)

{

double Wk = 0.01;

double Ew;

do

{

Ew = (1 / Math.PI) * Rectangle(0, Wk, q, FunctionModSqrSjw);

Wk += 0.0001;

} while ((Ec- Ew) / Ec < 0.98);

return Wk;

}

3. Определение частоты дискретизации аналогового сигнала.

Формула частоты дискретизации:

-10

Но перед ее подсчетом нам необходимо перевести граничную частоту в герцы, разделив ее на 2 pi.

4. Генерирование дискретного сигнала и построение его графика.

Для этого мы находим количество отсчетных значений используя частоту дискретизации. Оно равно (T / fd) + 1. Получившееся значение округляется в большую сторону, а также если оно получилось нечетным, то добавляем еще единицу.

int TakeN(double fd)

{

int N = int.Parse(Math.Ceiling((T / fd) + 1).ToString());

if (N % 2 == 1) N++;

return N;

}

Потом находим шаг дискретизации

double TakeDeltaDis(int N)

{

return (T / (N - 1));

}

И теперь мы можем построить график дискретного сигнала

void PrintGrafDiscreteSignal(int N, double deltaDis)

{

for (int i=1; i<N; i++)

{

chart2.Series[0].Points.AddXY(i, FunctionSt(deltaDis*i));

}

}

Полученный график
Полученный график

5. Выполнение квантование дискретного сигнала с шагом, соответствующим представлению отсчетов 4-битным числом.

Количество уровней квантования для 4-битного числа – M=2^4=16.

Формула шага квантования:

-12

В нашем случае он равен (из-за того что минимальное значение – 0 и график непрерывно растет):

deltaQuant = FunctionSt(deltaDis * (N-1)) / 15;

6. Построение графика квантованного сигнала.

Для построения графика создадим следующий метод.

double[] PrintGrafDigitalSignal(int N, double deltaDis, double deltaQuant)

{

double[] Skv = new double[N];

int k;

for (int i = 0; i < N; i++)

{

k = int.Parse(Math.Round(FunctionSt(deltaDis * i)/ deltaQuant).ToString());

Skv[i] = deltaQuant * k;

chart2.Series[1].Points.AddXY(i, Skv[i]);

chart3.Series[0].Points.AddXY(i, (FunctionSt(deltaDis * i) - Skv[i]));

}

return Skv;

}

Он принимает рассчитанные нами ранее параметры и с их помощь строит график квантованного сигнала, записывает полученные значения и строит график погрешностей для следующего пункта.

Полученный сигнал
Полученный сигнал

7. Вычисление погрешности квантования. Построение графика погрешности.

Полученный график погрешности
Полученный график погрешности

8. Определение коэффициентов ДПФ.

Коэффициенты высчитываются по формуле:

-15

Сами коэффициенты не пригодятся, нам нужны их мнимая и действительная части для подсчета модулей и фазовых углов:

-16

Вот метод, высчитывающий необходимые нам значения:

double [,] TakeModeCn(double deltaQuant, double [] Skv)

{

int N = Skv.Length;

double[,] Cn = new double[N, 2];

for (int n=0; n<N; n++)

{

double Re = 0;

double Im = 0;

for (int i=0; i<N; i++)

{

Re += Skv[i] * Math.Cos((-2 * Math.PI * n * i) / N);

Im += Skv[i] * Math.Sin((-2 * Math.PI * n * i) / N);

}

Re = Re / N;

Im = Im / N;

Cn[n, 0] = Math.Sqrt(Math.Pow(Re, 2) + Math.Pow(Im, 2));

Cn[n, 1] = -Math.Atan(Im / Re);

}

return Cn;

}

9. Восстановление аналогового сигнала по значениям цифрового сигнала.

Восстановление аналогового сигнала S(t) по значениям коэффициентов ДПФ:

-17

А сам метод, реализующий данную функцию, выглядит так:

double Svt(double [,] Cn, double arg, int N)

{

double Svt = Cn[0, 0];

for (int i=1; i<=N/2; i++)

{

Svt += 2 * Cn[i, 0] * Cos((2*i * Math.PI * arg)/T + Cn[i, 1]);

}

return Svt;

}

10. Построение и сравнение графиков исходного аналогового сигнала с восстановленным.

Посторенние происходит, используя метод, написанный ранее:

void PrintGrafRestoreSignal(double [,] Cn, int N)

{

double i = 0;

while(i<T)

{

chart4.Series[0].Points.AddXY(T-i, Svt(Cn, i, N));

i+=0.01;

}

}

График восстановленного сигнала
График восстановленного сигнала