Заключение
В результате выполнения данного проекта был разработан цифровой полосовой фильтр, позволяющий осуществлять фильтрацию сигнала, дискретизированного по времени с частотой 48000 Гц, и задавать две частоты среза. Ширина перехода частотной характеристики спроектированного фильтра составляет всего 0.78% от заданной частоты дискретизации, что равняется примерно 344 Гц.
Разработка цифрового фильтра включала выбор необходимых современных микросхем (сигнальный процессор типа TMS, АЦП и ЦАП), их согласование между собой (построение принципиальной схемы), разработку алгоритмов фильтрации и их программную реализацию с учетом особенностей выбранных микросхем, а также анализ временных характеристик.
При разработке алгоритмов фильтрации и их программной реализации было создано тестовое приложение, моделирующее работу спроектированного фильтра, результаты обработки анализировались путем построения частотной характеристики ядра фильтра и спектров моделируемого сигнала в среде MathCad. Такое моделирование позволило прийти к выводу, что алгоритм фильтрации разработан правильно и работоспособен.
В ходе выполнения проекта были закреплены знания по основам цифровой обработки сигналов и в частности по фильтрации. Изучены особенности применения современных сигнальных процессоров, АЦП и ЦАП на примере микросхем фирмы Texas Instruments. На протяжении всего времени выполнения проекта постоянно изучалась техническая документация по использованным микросхемам, написанная преимущественно на английском языке фирмой-производителем.
Список использованной литературы
-
Стивен Смит. Научно-техническое руководство по цифровой обработке сигналов [Электронный ресурс] / Пер. с англ. фирмы «Автэкс». – С-Пб, 2001.
-
Хемминг Р.В. Цифровые фильтры. Пер. с англ. В.И. Ермишина./ Под ред. А.М. Трахтмана. – М.: «Советское радио», 1980. – 224 с.
-
Введение в цифровую фильтрацию. /Под. ред. Р. Богнера и А. Константинидиса. Пер. с англ. Л.И. Филиппова. – М.: «Мир», 1976. – 218 с.
-
Блейхут Р. Быстрые алгоритмы цифровой обработки сигналов. Пер. с англ. И.И. Грушко. – М.: «Мир», 1989. – 220 с.
-
TMS320VC5402 Fixed-point digital signal processor. [Электронный ресурс]. – Houston: Texas Instruments Inc., 2000.
-
TMS320C54x, TMS320LC54x, TMS320VC54x Fixed-point digital signal processors. [Электронный ресурс]. – Houston: Texas Instruments Inc., 1999.
-
16-Bit, High-Speed, microPower Sampling Analog-To-Digital Converter ADS8320. [Электронный ресурс]. – Houston: Texas Instruments Inc., 2000.
-
Low-Power, 16-Bit Serial Input Digital-To-Analog Converter DAC8531. [Электронный ресурс]. – Houston: Texas Instruments Inc., 2000.
1.Interfacing the ADS8320 to the TMS320C5402 DSP. [Электронный ресурс]. – Houston: Texas Instruments Inc., 2001.
ПРИЛОЖЕНИЕ
Листинг программного обеспечения
//--------------------Memory-Mapped Registers---------------------
#define IMR 0x0000 // Interrupt Mask register
#define IFR 0x0001 // Interrupt flag register
//--------------------- McBSP0 Registers -------------------------
#define McBSP0_DRR2x 0x0020 // McBSP0 Data Rx Reg2
#define McBSP0_DRR1 0x0021 // McBSP0 Data Rx Reg1
#define McBSP0_DXR2 0x0022 // McBSP0 Data Tx Reg2
#define McBSP0_DXR1 0x0023 // McBSP0 Data Tx Reg1
#define McBSP0_SPSA 0x0038 // McBSP0 Sub Bank Addr Reg
#define McBSP0_SPSD 0x0039 // McBSP0 Sub Bank Data Reg
//--------------------- McBSP1 Registers --------------------------
#define McBSP1_DRR2 0x0040 ; //McBSP1 Data Rx Reg2
#define McBSP1_DRR1 0x0041 ; //McBSP1 Data Rx Reg1
#define McBSP1_DXR2 0x0042 ; //McBSP1 Data Tx Reg2
#define McBSP1_DXR1 0x0043 ; //McBSP1 Data Tx Reg1
#define McBSP1_SPSA 0x0048 ; //McBSP1 Sub Bank Addr Reg
#define McBSP1_SPSD 0x0049 ; //McBSP1 Sub Bank Data Reg
//------- McBSP0 & McBSP1 Sub-Bank Addressed Registers -------------
#define SPCR1 0x0000 ; //McBSP Ser Port Ctrl Reg1
#define SPCR2 0x0001 ; //McBSP Ser Port Ctrl Reg2
#define RCR1 0x0002 ; //McBSP Rx Ctrl Reg1
#define RCR2 0x0003 ; //McBSP Rx Ctrl Reg2
#define XCR1 0x0004 ; //McBSP Tx Ctrl Reg1
#define XCR2 0x0005 ; //McBSP Tx Ctrl Reg2
#define SRGR1 0x0006 ; //McBSP Sample Rate Gen Reg1
#define SRGR2 0x0007 ; //McBSP Sample Rate Gen Reg2
#define MCR1 0x0008 ; //McBSP Multichan Reg1
#define MCR2 0x0009 ; //McBSP Multichan Reg2
#define RCERA 0x000A ; //McBSP Rx Chan Enable Reg Partition A
#define RCERB 0x000B ; //McBSP Rx Chan Enable Reg Partition B
#define XCERA 0x000C ; //McBSP Tx Chan Enable Reg Partition A
#define XCERB 0x000D ; //McBSP Tx Chan Enable Reg Partition B
#define PCR 0x000E ; //McBSP Pin Ctrl Reg
//------------------ General Purpose I/0 Registers -------------------------
#define GPIOCR 0x003C ; //GP I/O Pins Control Reg
#define GPIOSR 0x003D ; //GP I/O Pins Status Reg
//----------------- Timer0 Memory-mapped registers--------------------
#define TIM0 0x0024 ; //Timer0 register
#define PRD0 0x0025 ; //Timer0 period counter register
#define TCR0 0x0026 ; //Timer0 control register
#define M 511
#define M1 512
#define 2M2 1024
#define Fd 48000
#define halfM 255
short kernel_re [2M2];
short kernel_im [2M2];
short frame1_re [2M2];
short frame1_im [2M2];
short frame2_re [2M2];
short frame2_im [2M2];
short filt_signal1 [M1];
short filt_signal2 [M1];
short overlap [M1];
short in_index=0;
short out_index=0;
bool frame1_fl=false;
bool frame2_fl=false;
bool frame1out_fl=false;
bool frame2out_fl=false;
bool frame1in_fl=false;
bool frame2in_fl=false;
double Fl = 1000.0,
Fh = 10000.0;
double fl = Fl/Fd,
fh = Fh/Fd;
void main()
{
short tmp;
short Fc1,Fc,i,j;
//Initialize DSP
//установить адрес страницы памяти в регистр DP,
//установить указатель стека (регистр SP),
*(INTM)=1 ; //Запрет прерываний
//установить адрес таблицы векторов прерываний (в регистр PMST)
*(IMR)=0x0408; //разреш прерывания от таймера0,получения данных порта mcBSP1
*(IFR)=0xFFFF;
//(multichannel buffered serial port) SPSA–как указатель, SPSD-как данные
//Initialize McBSP1
*(McBSP1_SPSA)=SPCR1;
tmp=*(McBSP1_SPSD);
tmp&=0xFFFE;//сброс приемника – бит RRST=0 в регистре SPCR1
*(McBSP1_SPSD)=tmp;
*(McBSP1_SPSA)=SPCR2;
tmp=*(McBSP1_SPSD);
tmp&=0xFF2E;// биты GRST=0,FRST=0,XRST=0 – сброс генераторов
*(McBSP1_SPSD)=tmp;
*(McBSP1_SPSA)=RCR1;
*(McBSP1_SPSD)=0x0040;//получение данных по 16 бит
*(McBSP1_SPSA)=RCR2;
*(McBSP1_SPSD)=0x0000;
*(McBSP1_SPSA)=SRGR1;
*(McBSP1_SPSD)=0x0031;//делитель частоты CLKGDV=31h – частота синхронизации
//порта тогда CLKX=(CPU_CLK/1+CLKGDV)=2 МГц
*(McBSP1_SPSA)=SRGR2;
*(McBSP1_SPSD)=0x2016;// паузы между передачами – 22 такта (16h)
*(McBSP1_SPSA)=PCR;
*(McBSP1_SPSD)=0x0A0D; //прием по переднему фронту синхроимпульса, FSX
//активный на низком уровне
*(McBSP1_SPSA)=SPCR1;
*(McBSP1_SPSD)=0x1800;//синхроимпульс начинается с переднего фронта
tmp=*(McBSP1_SPSD);
tmp|=0x0001;//разрешение работы приемника McBSP1
*(McBSP1_SPSD)=tmp;
*(McBSP1_SPSA)=SPCR2;
tmp=*(McBSP1_SPSD);
tmp=0x02C0;// биты GRST=1,FRST=1,XRST=1 – разрешение генераторов
*(McBSP1_SPSD)=tmp;
tmp|=0x0001;// бит XRST=1, разрешение работы порта
*(McBSP1_SPSD)=tmp;
//Initialize McBSP0
*(McBSP0_SPSA)=SPCR1;
tmp=*(McBSP0_SPSD);
tmp&=0xFFFE;//сброс приемника – бит RRST=0 в регистре SPCR1
*(McBSP0_SPSD)=tmp;
*(McBSP0_SPSA)=SPCR2;
tmp=*(McBSP0_SPSD);
tmp&=0xFF2E;// биты GRST=0,FRST=0,XRST=0 – сброс генераторов и передатчика
*(McBSP0_SPSD)=tmp;
*(McBSP0_SPSA)=XCR1;
*(McBSP0_SPSD)=0x0040;//передача данных по 16 бит
*(McBSP0_SPSA)=XCR2;
*(McBSP0_SPSD)=0x0000;
*(McBSP0_SPSA)=SRGR1;
*(McBSP0_SPSD)=0x0031;//делитель частоты CLKGDV=31h – частота синхронизации
//порта тогда CLKX=(CPU_CLK/1+CLKGDV)=2 МГц
*(McBSP0_SPSA)=SRGR2;
*(McBSP0_SPSD)=0x2000;
*(McBSP0_SPSA)=PCR;
*(McBSP0_SPSD)=0x0A0D; //передача по переднему фронту синхроимпульса, FSX
//активный на низком уровне
*(McBSP0_SPSA)=SPCR1;
*(McBSP0_SPSD)=0x1800;//синхроимпульс начинается с переднего фронта
tmp=*(McBSP0_SPSD);
tmp|=0x0001;//разрешение работы передатчика McBSP0
*(McBSP0_SPSD)=tmp;
*(McBSP0_SPSA)=SPCR2;
tmp=*(McBSP0_SPSD);
tmp=0x02C0;// биты GRST=1,FRST=1,XRST=1 – разреш. генераторы и передатчик
*(McBSP0_SPSD)=tmp;
tmp|=0x0001;// бит XRST=1, разрешение работы порта
*(McBSP0_SPSD)=tmp;
//Initialize Timer0
tmp=*(TCR0);// читаем регистр состояния таймера
tmp|=0x0010;//устанавливаем 1 в бит TSS регистра TCR0 – останавливаем таймер
*(TCR0)=tmp;
*(PRD0)=0x008D;// (PRD0+1)*(TDDR0+1)=CPUclk/48000=100000000/48000=2083
*(TCR0)=0x081F;//TDDR0=0xF=15 -> PRD0=2268/(15+1)-1=141=0x8D
//это установка периода срабатывания прерывания от таймера
tmp=*(TCR0);
tmp&=0xFFEF;// запуск таймера – бит TSS=0
*(TCR0)=tmp;
tmp|=0x0020;// перезагрузка таймера – установка бита TRB=1
*(TCR0)=tmp;
//Настройка выводов HD0-HD7 на прием данных от внешнего компьютера для
//частоты среза – 8 бит, рассматривается как старший байт 16 битного значения
//т.е. частота среза задается только с шагом через 256 Гц
*(GPIOCR)=0x0000;
*(INTM)=0;//разрешение прерываний
Fc1=*(GPIOSR);
Fc=Fc1<<8;
for(i=0;i
Filter(Fd,Fc,kernel_re);//Получаем ядро фильтра (511 точек)
for(i=M1;i<2M2;i++){kernel_re[i]=0;kernel_im[i]=0;}
BPF(kernel_re,kernel_im,2M2,1);//нашли спектр ядра фильтра
frame1in_fl=true;
//основной цикл
while(1)
{
if(frame1_fl)
{
tmp=*(GPIOSR);
if(Fc1!=tmp)//пересчет фильтра
{
Fc1=tmp;
Fc=Fc1<<8;
for(i=0;i
Filter(Fd,Fc,kernel_re);//Получаем ядро фильтра (511 точек)
for(i=M1;i<2M2;i++){kernel_re[i]=0;kernel_im[i]=0;}
BPF(kernel_re,kernel_im,2M2,1);//нашли спектр ядра фильтра
}
for(i=0;i
for(i=M1;i<2M2;i++)
{
frame1_re[i]=0;
frame1_im[i]=0;
}
BPF(frame1_re,frame1_im,2M2,1);
for(i=0;i<2M2;i++)//свертка
{
tmp=frame1_re[i]*kernel_re[i]-frame1_im[i]*kernel_im[i];
frame1_im[i]=frame1_re[i]*kernel_im[i]+frame1_im[i]*kernel_re[i];
frame1_re[i]=tmp;
}
//находим обратное БПФ - восстанавливаем сигнал
BPF(frame1_re,frame1_im,2M2,-1);
//формируем кадр выходного сигнала и перекрывающуюся часть
for(i=0;i
{
filtered_signal1[i]=overlap[i]+frame1_re[i];
overlap[i]=frame1_re[i+M1];
}
frame1_fl=false;
frame1out_fl=true;
}
else if(frame2_fl)
{
tmp=*(GPIOSR);
if(Fc1!=tmp)//пересчет фильтра
{
Fc1=tmp;
Fc=Fc1<<8;
for(i=0;i
Filter(Fd,Fc,kernel_re);//Получаем ядро фильтра (511 точек)
for(i=M1;i<2M2;i++){kernel_re[i]=0;kernel_im[i]=0;}
BPF(kernel_re,kernel_im,2M2,1);//нашли спектр ядра фильтра
}
for(i=0;i
for(i=M1;i<2M2;i++)
{
frame2_re[i]=0;
frame2_im[i]=0;
}
BPF(frame2_re,frame2_im,2M2,1);
for(i=0;i<2M2;i++)//свертка
{
tmp=frame2_re[i]*kernel_re[i]-frame2_im[i]*kernel_im[i];
frame2_im[i]=frame2_re[i]*kernel_im[i]+frame2_im[i]*kernel_re[i];
frame2_re[i]=tmp;
}
//находим обратное БПФ - восстанавливаем сигнал
BPF(frame2_re,frame2_im,2M2,-1);
//формируем кадр выходного сигнала и перекрывающуюся часть
for(i=0;i
{
filtered2_signal[i]=overlap[i]+frame2_re[i];
overlap[i]=frame2_re[i+M1];
}
frame2_fl=false;
frame2out_fl=true;
}
}
}
void timer_interrupt()
{
*(McBSP1_DXR1)=0x0000;//для генерации импульса BFSX1 и начала работы АЦП
if(frame1out_fl)
{*(McBSP0_DXR1)=filtered1_signal[out_index];
if(out_index==M)
{
out_index=0;
frame1out_fl=false;
return;
}
else {out_index++;return;}
}
else if(frame2out_fl)
{*(McBSP0_DXR1)=filtered2_signal[out_index];
if(out_index==M)
{
out_index=0;
frame2out_fl=false;
return;
}
else {out_index++;return;}
}
return;
}
void MCBSP1_Rinterrupt()
{
if(frame1in_fl)//запись в первый буфер
{
frame1_re[in_index]=*(McBSP1_DRR1);//чтение из порта
if(in_index==M)
{
in_index=0;
frame1_fl=true;//установка флага, свидетельствующего о том,
//что первый буфер заполнен
frame2in_fl=true;
frame1in_fl=false;
return;
}
else in_index++;
}
else if(frame2in_fl)//запись во второй буфер
{
frame2_re[in_index]=*(McBSP1_DRR1);//чтение из порта
if(in_index==M)
{
in_index=0;
frame2_fl=true;//установка флага, свидетельствующего о том,
//что второй буфер заполнен
frame1in_fl=true;
frame2in_fl=false;//флаги показывают, что нужно писать в первый буфер
return;
}
else in_index++;
}
}
void Filter(short Fd,short Fc,short* h)
{
int i,j;
double tmp, tempH, tempL;
double Hh[M],Hl[M];
double suml=0, sumh=0;
for (i=- halfM;i< halfM;i++)
{
j=i+ halfM; // i=- halfM.. halfM j=0..M
if (i==0)
{
Hh[halfM]=1;
Hl[halfM]=1;
}
else
{
tmp= PiFFC2*i;
tempH=tmp*2*fh;
tempH=sin(tempH);
tempL=tmp*2*fl;
tempL=sin(tempL);
Hh[j]=tempH/tmp;
Hl[j]=tempL/tmp;
}
//окно
Hl[j]=Hl[j]* Blackman [j];
Hh[j]=Hh[j]* Blackman [j];
//сумма для нормализации
suml+=Hl[j];
sumh+=Hh[j];
}
//нормализация
for (i=0;i
{
Hl[i]/=suml;
Hh[i]/=sumh;
H[i]=Hh[i]-Hl[i];
}
return;
}
|