Исходные тексты модулей проекта DspLab_fir




ОТЧЕТ ПО ВЫПОЛНЕНИЮ ЛАБОРАТОРНЫХ РАБОТ

По дисциплине «Сигнальные процессоры»

Лабораторная работа № 3

Синтез цифровых фильтров на процессорах
с ядром ARM Cortex-M4

 

Выполнил студент: Мамаев С.С. Дата выполнения: 23.12.15

 

 

1. Тестовый КИХ-фильтр с непрерывной обработкой.

 

Примерный вид АЧХ (указать тип, порядок, обозначить названия параметров, единиц измерения)

Тип фильтра: режекторный Порядок фильтра:70

 

Времена обработки при использовании различных форматов данных

 

  C фиксированной точкой C плавающей точкой и FPU C плавающей точкой без FPU
Время ввода отсчета 0,84 0,84 0,84
Время обработки отсчета 5,6 6,11 34,39
Время вывода отсчета 0,55 0,58 0,58
Приведенное время одной итерации умножения-суммирования 0,16 0,17 0,96

 

 

2. Тестовый КИХ-/БИХ-фильтр с блочной обработкой

FIR (КИХ) - фильтр

Время ввода-вывода одного отсчета: 1,85 мкс

Время обработки блока отсчетов: 3502,85 мкс

Время обработки одного отсчета: 3,42 мкс

Полное время, затрачиваемое на ввод-вывод-обработку отсчета: 5,27 мкс

Порядок фильтра: 151

Приведенное время одной итерации умножения-суммирования: 0,02 мкс

Период дискретизации: 167 мкс

Коэффициент загрузки процессора: 3,2 %

3. Синтез КИХ- и БИХ-фильтров

 

Discrete-Time IIR Filter (real)

% -------------------------------

% Filter Structure: Direct-Form II, Second-Order Sections

% Number of Sections: 3

% Stable: Yes

% Linear Phase: No

 

 

SOS matrix:

1 0 -1 1 -1.579725723787528 0.95295196905777169

1 0 -1 1 -1.6697431729913097 0.95809295838494668

1 0 -1 1 -1.5916986838748972 0.9128438590431841

 

Scale Values:

0.044515627477252032

0.044515627477252032

0.043578070478407893

Filter Structure: Direct-Form FIR

% Filter Length: 51

% Stable: Yes

% Linear Phase: Yes (Type 1)

 

 

Numerator:

-0.020610195446912189

0.0075288479873491104

0.013069144503431579

0.018814073859032294

0.020992268830162544

0.016859796985477845

0.0060945966941012373

-0.0087354059513403918

-0.022715777792557221

-0.0302498975800761

-0.027447470094929698

-0.013806436248764807

0.0069612327766380277

0.027843292603074072

0.041005135762151382

0.040692075260921355

0.02573329841180937

0.00035212663167955981

-0.026989722948053966

-0.046506242056566567

-0.050701818741585601

-0.037363861348875121

-0.010557855347337802

0.020582019039452594

0.045167163393082285

0.054466057834360163

0.045167163393082285

0.020582019039452594

-0.010557855347337802

-0.037363861348875121

-0.050701818741585601

-0.046506242056566567

-0.026989722948053966

0.00035212663167955981

0.02573329841180937

0.040692075260921355

0.041005135762151382

0.027843292603074072

0.0069612327766380277

-0.013806436248764807

-0.027447470094929698

-0.0302498975800761

-0.022715777792557221

-0.0087354059513403918

0.0060945966941012373

0.016859796985477845

0.020992268830162544

0.018814073859032294

0.013069144503431579

0.0075288479873491104

-0.020610195446912189

 

 

Текст задания

Вариант 2. Полоса частот входного сигнала 0…6 кГц. Полоса пропускания 1500±100 Гц при неравномерности 4 дБ. Ослабление на частотах за пределами 1500±400 Гц не менее 30 дБ

КИХ-фильтр

 

Response Type (тип АЧХ) полосовой
Design Method (метод синтеза): FIR Equiripple
Частота дискретизации Fs  
Границы полосы пропускания Fpass  
Границы полосы ослабления Fstop  
Неравномерность в полосе пропускания Apass  
Уровень ослабления Astop  
Порядок фильтра (Order)  

 

Разностное уравнение:

 

Рекурсивный цифровой фильтр второго порядка описывается разностным уравнением f 2[ n ] = a 0 f 1[ n ] + a 1 f 1[ n – 1] + a 2 f 1[ n – 2] + b 1 f 2[ n – 1] + b 2 f 2[ n – 2]

нерекурсивный цифровой фильтр второго порядка описывается разностным уравнением f 2[ n ] = a 0 f 1[ n ] + a 1 f 1[ n – 1] + a 2 f 1[ n – 2]

БИХ-фильтр

 

 

Response Type (тип АЧХ) Bandpass
Design Method (метод синтеза): IIR Least Pth-norm
Частота дискретизации Fs  
Границы полосы пропускания Fpass  
Границы полосы ослабления Fstop  
Неравномерность в полосе пропускания Apass  
Уровень ослабления Astop  
Порядок фильтра (Order)  
Число биквадратных звеньев (Sections)  
Признак стабильности фильтра (Stable) Yes

 

Разностные уравнения для первого и последнего звеньев:

yk =

yk =

4. Практическая реализация КИХ- и БИХ-фильтра

 

Таблица АЧХ КИХ- и БИХ-фильтров

 

  Частота, Гц                          
КИХ-фильтр, коэффициент передачи, дБ -37 -31 -9,6 -2,3 -0,3 -2,5 -10 -31,2 -32 -33 -35 -37
БИХ-фильтр, коэффициент передачи, дБ -36 -31 -14 -2,3 -0,3 -2,6 -21 -33,4 -34,2 -35 -35,6 -36

 

Теоретические и экспериментальные АЧХ КИХ- и БИХ-фильтров

 

Времена блочной и непрерывной обработки для КИХ-/БИХ-фильтров и данных в форматах с фиксированной точкой (16 бит) и плавающей точкой (32 бита)

 

  Блочная обработка Непрерывная обработка
КИХ-фильтр БИХ-фильтр КИХ-фильтр
Фикс. Плав. Плав. Фикс. Плав.
Время ввода-вывода отсчета 1,66 1,85 1,83 0,84 0,84
Время обработки блока отсчетов 1595,8 1938,3 509,24    
Время обработки одного отсчета 1,56 1,89 0,5    
Приведенное время одной итерации умножения-суммирования 0,021 0,025 0,016 0,16 0,17
Коэффициент загрузки процессора 2,6% 3% 1,9%    

 

 

5. Синтез многополосного фильтра (по второму каналу)

 

Исходные данные

 

Тип фильтра: заграждающий

Центральные частоты полос: 697, 770, 852, 941, 1209, 1336, 1477, 1633 Гц

Полоса пропускания: 30 Гц

Полоса ослабления: 40 Гц

 

Исходные данные для программы Filter Design:

 

Частота дискретизации:4000 Гц

Вектор частот (Freq. vector):

Вектор амплитуд (Mag. vector):

Вектор вес. коэф. (Weight vector):

Задаваемый порядок (Specify order):600

 

 


Исходные тексты модулей проекта DspLab_fir

 

Модуль main.c

 

/******************************************************************************

*

* УЧЕБНЫЙ ПРОЕКТ

*

* Фильтр с конечной импульсной характеристикой

* Непрерывная обработка для каждого отсчета сигнала

*

* Copyright (C) 2015 МИРЭА

* Версия: 1.3

*

******************************************************************************/

/*

ОРГАНЫУПРАВЛЕНИЯ

Джойстик "вверх/вниз" - увеличение/уменьшение частоты генератора синусоидального сигнала

Джойстик "влево" - переключение между типами входного сигнала: синусоидальный / шум / нет сигнала

Джойстик "вправо" - переключение форматов входного сигнала: аналоговый (через АЦП) / цифровой код

Кнопка TAMPER - вывод меток времени обработки

*/

 

#include "stm32_p407.h" //Файл конфигурации отладочной платы STM32-P407

#include "adcdac.h" //Объявления функций для работы с периферийными устройствами

#include "gauge.h" //Процедуры управления и измерения

#include "values.h" //Числовые значения исходных операндов

 

//---------------------------------------------------------------------------

// Объявления данных

int16_t DataChannel1, DataChannel2; //Входные и выходные отсчеты в формате 1.15

int16_t DataADC; //Прямой отсчет с АЦП для системы калибровки

int32_t AmplOffset = 0; //Смещение нулевого уровня сигнала с АЦП

int32_t Modes = 0; //Режимы обработки и конфигурация системы:

// 0: аналоговый генератор -> АЦП -> обработка

// 1: цифровой генератор -> обработка

//---------------------------------------------------------------------------

// Прототипы функций в Proc.c

void DataInit(void);

void Proc(void);

 

//---------------------------------------------------------------------------

// ГЛАВНАЯ ФУНКЦИЯ

int main()

{

//Счетчик для реализации периода изменения тестовой индикации

volatile uint32_t i = 0;

 

//Инициализация цифровой обработки сигнала

DataInit();

 

//Задание 4-х уровней групповых приоритетов и 4-х уровней приоритетов в каждой группе

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

 

//Инициализация индикаторов

STM_LEDInit(LED1);

 

//Инициализация кнопок

STM_PBInit(BUTTON_TAMPER, BUTTON_MODE_GPIO);

STM_PBInit(BUTTON_WAKEUP, BUTTON_MODE_GPIO);

 

//Инициализация кодека (ЦАП выходных отсчетов сигнала)

SoundCodecConfig(FS_FIR); //Аргумент - частота дискретизации, Гц

SoundCodecInterruptConfig(ENABLE);

 

//Инициализация АЦП

ADCConfig();

 

//Инициализация генератора входного сигнала

SignalGenConfig();

 

//Инициализация графического интерфейса, джойстика, системы измерений

GgInterfaceInit();

 

//ОСНОВНОЙ ЦИКЛ

while (1)

{

GgControl(); //Управление частотой и амплитудой генератора сигнала,

// вывод результатов измерений

if (i++ == 0x800) STM_LEDOff(LED1); //Тестовое управление индикатором

if (i == 0x50000) STM_LEDOn(LED1), i = 0;

 

if (STM_PBGetState(BUTTON_WAKEUP)) break; //Выход из основного цикла, если нажата WAKEUP

}

//ОКОНЧАНИЕ ОСНОВНОГО ЦИКЛА

 

//Сброс процессора - завершение выполнения данной программы, запуск начального загрузчика

NVIC_SystemReset();

 

while (1) {}

}

 

//---------------------------------------------------------------------------

// ОБСЛУЖИВАНИЕ ПРЕРЫВАНИЯ С ЧАСТОТОЙ ДИСКРЕТИЗАЦИИ

// Данная подпрограмма вызывается из обработчика прерывания..._IRQHandler(),

// реализованного в adcdac.c

// Частота дискретизации формируется модулем процессора SPI/I2S,

// посредством которого по интерфейсу I2S отсчеты сигнала выводятся на внешний звуковой кодек.

// Этот модуль также генерирует прерывания с частотой дискретизации. В обработчике

// прерывания, размещенном здесь, производятся следующие операции:

// - считываются отсчеты входного сигнала с АЦП или цифрового входа;

// - АЦП запускается на следующий цикл преобразования;

// - вызывается процедура обработки Proc(), возвращающая выходные отсчеты;

// - выходные отсчеты передаются кодеку.

void Sample_Handler(void)

{

extern int16_t GeneratorSamples; //Цифровой выход генератора сигналов (в доп. коде)

// параметр объявлен в adcdac.c

if (Modes == 0)

{ //Получение данных с АЦП, преобразование смещенного кода в дополнительный,

// коррекция нулевого уровня

DataADC = ADC_GetConversionValue(ADC1) ^ 0x8000;

DataChannel2 = DataChannel1 = DataADC - AmplOffset;

}

//Получение цифрового отсчета входного сигнала (минуя АЦП)

else DataChannel2 = DataChannel1 = GeneratorSamples;

 

//Перезапуск АЦП

ADC_SoftwareStartConv(ADC1);

 

//Вызов подпрограммы цифровой обработки сигнала (реализована в proc.c)

TimeMarker2(); //Временная метка № 2

Proc();

TimeMarker3(); //Временная метка № 3

 

//Обработанные значения - в DataChannel1, DataChannel2

}

 

 

Модуль proc.c

 

/******************************************************************************

*

* ПОДПРОГРАММЫЦИФРОВОЙ ОБРАБОТКИ СИГНАЛА

*

* Фильтр с конечной импульсной характеристикой

* Непрерывная обработка для каждого отсчета сигнала

*

******************************************************************************/

 

/* Подключаемые заголовочные файлы */

#include "mathfunc.h" //Прототипы математических функций

#include "coef.h" //Значения коэффициентов

 

//#define FLOAT_PROC //Определение для использования при обработке сигнала

// данных с плавающей точкой

 

/* Константы */

// numTaps //Число отсчетов/коэффициентов - задано в coef.h

// float FIR_coef[numTaps] //Массив коэффициентов в формате float - задан в coef.h

 

/* Текущие переменные */

extern int16_t DataChannel1, //Входные и выходные отсчеты в формате 1.15

DataChannel2; // (объявлены в main.c)

 

#ifndef FLOAT_PROC //В а р и а н т обработки с фиксированной точкой

int16_t Samples[numTaps]; //Буфер 16-разрядных отсчетов (циклический) в формате 1.15

int32_t Coeffs[numTaps]; //Буфер 32-разрядных коэффициентов в дробном формате 1.31

int16_t* pSamples; //Указатель на отсчеты

int16_t* pSamplesEnd; //Указатель на конец буфера отсчетов

int32_t* pCoeffs; //Указатель на коэффициенты

#else //В а р и а н т обработки с плавающей точкой

float Samples[numTaps]; //Буфер отсчетов

float* pSamples; //Указатель на отсчеты

float* pSamplesEnd; //Указатель на конец буфера отсчетов

float* pCoeffs; //Указатель на коэффициенты

#endif

 

/******************************************************************************

ПОДПРОГРАММА ИНИЦИАЛИЗАЦИИ ФИЛЬТРА

Вызывается однократно при старте программы

*/

void DataInit(void)

{

#ifndef FLOAT_PROC

int32_t i; //Для варианта обработки с фиксированной точкой:

for (i = 0; i < numTaps; i++) // преобразование формата коэффициентов из float в дробный 1.31

Coeffs[i] = float_to_q31(FIR_coef[i]);

#endif

pSamples = Samples; //Установка указателя отсчетов на начало буфера

pSamplesEnd = Samples + numTaps; //Задание указателя конца буфера отсчетов

}

 

/******************************************************************************

ПОДПРОГРАММА ОБРАБОТКИ

Вызывается с частотой дискретизации при получении новых отсчетов.

Отсчеты входного сигнала для первого и второго каналов

размещены в глобальных переменных DataChannel1, DataChannel2. В эти же

переменные записываются обработанные отсчеты по соответствующим каналам.

В исходном варианте производится обработка данных только первого канала.

*/

void Proc(void)

{

#ifndef FLOAT_PROC //------- В а р и а н т обработки с фиксированной точкой -------

 

int32_t x, b; //Текущие значения отсчета и коэффициента

int32_t i = numTaps; //Счетчик циклов умножений-накоплений

int64_t acc = 0; //Очистка 64-разрядного аккумулятора (накопителя)

 

pCoeffs = &Coeffs[numTaps-1]; //Установка указателя на последний коэффициент bN

*pSamples++ = DataChannel1; //Сохранение входного отсчета в памяти

if (pSamples >= pSamplesEnd) pSamples = Samples; //Проверка перехода на начало циклического буфера

 

do //Организация цикла с счетчиком i, изменяющимся от numTaps до 1

{

x = *pSamples++; //Выборка отсчета, продвижение указателя на следующий отсчет

b = *pCoeffs--; //Выборка коэффициента, продвижение указателя на предыдущий коэффициент

acc += (int64_t)b * x; //Умножение коэффициента и отсчета с накоплением

if (pSamples >= pSamplesEnd) pSamples = Samples; //Проверка перехода на начало циклического буфера

 

} while (--i!= 0); //Декремент счетчика i, проверка его на обнуление

 

DataChannel1 = (int16_t)(acc >> 31u); //Преобразование формата 2.62 в формат 1.31 с усечением до 1.15

 

#else //------- В а р и а н т обработки с плавающей точкой -------

 

float x, b; //Текущие значения отсчета и коэффициента

int32_t i = numTaps; //Счетчик циклов умножений-накоплений

float acc = 0; //Очистка аккумулятора (накопителя)

 

pCoeffs = &FIR_coef[numTaps-1]; //Установка указателя на последний коэффициент bN

*pSamples++ = q15_to_float(DataChannel1); //Преобразование входного отсчета в формат float,

// сохранение его в памяти

if (pSamples >= pSamplesEnd) pSamples = Samples; //Проверка перехода на начало циклического буфера

 

do //Организация цикла с счетчиком i, изменяющимся от numTaps до 1

{

x = *pSamples++; //Выборка отсчета, продвижение указателя на следующий отсчет

b = *pCoeffs--; //Выборка коэффициента, продвижение указателя на предыдущий коэффициент

acc += b * x; //Умножение коэффициента и отсчета с накоплением

if (pSamples >= pSamplesEnd) pSamples = Samples; //Проверка перехода на начало циклического буфера

 

} while (--i!= 0); //Декремент счетчика i, проверка его на обнуление

 

DataChannel1 = float_to_q15(acc); //Преобразование формата float в формат 1.15

 

#endif

 

DataChannel2 = DataChannel1;

}

 

 

Пример заголовочного модуля coef.h (fir_coef.h)

 

#define numTaps 34 //Число коэффициентов

 

float FIR_coef[numTaps] =

{

0.0214619597717033f, 0.0307411336820300f, 0.0038734707706876f, -0.0082041254073283f,

-0.0381282158344837f, -0.0378178633033697f, -0.0198560236913657f, 0.0217448788296480f,

0.0539662691353649f, 0.0594653676995162f, 0.0257788446908599f, -0.0276575170129635f,

-0.0704352004893433f, -0.0728329271355395f, -0.0310751415250206f, 0.0317280678231007f,

0.0771282967388960f, 0.0771282967388960f, 0.0317280678231007f, -0.0310751415250206f,

-0.0728329271355395f, -0.0704352004893433f, -0.0276575170129635f, 0.0257788446908599f,

0.0594653676995162f, 0.0539662691353649f, 0.0217448788296480f, -0.0198560236913657f,

-0.0378178633033697f, -0.0381282158344837f, -0.0082041254073283f, 0.0038734707706876f,

0.0307411336820300f, 0.0214619597717033f

};

 

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-04-27 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: