📄 filter.c
字号:
/*********************************************************************************
* FILTER.C v1.00 SEED-DTK APD的数字滤波实验主程序 *
* 版权(c) 2004- 北京合众达电子技术有限责任公司 *
* 设计者: 耿升辉 *
**********************************************************************************/
#include "string.h"
#include "UART_func.h"
#include "SEED-DEC2407.h"
#include "comm.h"
#include "firfilt.h"
#include "iirfilt.h"
#include "iircoeff.h"
/*帧长度的设定*/
#define FRAMLONGTH 0x104
#define DataLongth 0x100
#define NX 0x400
#define NH 0x010
#define NBIQ 0x04
unsigned int Ad_data[2048]={0};
int filter_data[1024];
int filter_result[1024];
typedef struct _UartForDec5416{
unsigned int Length;
unsigned int Type;
unsigned int Mutul;
unsigned int Data[DataLongth];
unsigned int Check;
}UartForDec5416, *PuartForDec5416;
PuartForDec5416 precieve =0;
unsigned long i= 0;
unsigned int k= 0;
int uart_s=0,uart_err=0,fifostatus=0;
unsigned long flashbaddr=0;
unsigned long flashaddr = 0;
PuartForDec5416 psend=0;
unsigned int errorsend = 0;
volatile unsigned int uart[0x104] ={0};
volatile unsigned int uarts[0x104] = {0};
unsigned int filterset[5] = {1024,0,0,0,0};
PFilterConfig pfilterset = 0;
volatile unsigned int datasendlong = 0;
volatile unsigned int datasendlength = 0;
volatile unsigned int sendcount = 0;
unsigned int convcount = 0;
volatile unsigned int adconvover =0;
volatile unsigned int convtimes=60;
volatile unsigned int convtimesback=60;
void sys_reset(void);
void SystemInit(void);
void PHANTOM(void);
void init_UART(void);
void AdInit(void);
void Ad8kInit(void);
void Ad44kInit(void);
void Ad96kInit(void);
int uart_recive(void);
unsigned int uart_send(void);
unsigned int temp;
#pragma DATA_SECTION(lpf, "firfilt")
FIRFILT_ORD20 lpf = FIRFILT_ORD20_LPF;
#pragma DATA_SECTION(iir, "iirfilt");
IIR5BIQ16 iir=IIR5BIQ16_DEFAULTS;
/* Instance the Filter Object and Initialize */
#pragma DATA_SECTION(dbuffer,"iirfilt");
int dbuffer[2*IIR_LPF_NBIQ]; /* Create Delay Buffer */
#pragma DATA_SECTION(coeff, "iirfilt");
int coeff[5*IIR_LPF_NBIQ]=IIR_LPF_COEFF;
/* Create Coefficient Buffer and initialize */
void main(void)
{
ONLED;
DINT;
SystemInit();
init_UART();
*IFR = 0x3f;
*IMR = 0x21;
EINT;
/*实验主控程序*/
psend = (PuartForDec5416)(&uarts[0]);
precieve = (PuartForDec5416)(&uart[0]);
pfilterset = (PFilterConfig)(&filterset[0]);
/*通知主机,系统准备好*/
psend->Length = FRAMLONGTH;
psend->Type = UARTCOMMAND;
psend->Data[0] = INITOVER;
psend->Mutul = UARTCONT;
uart_send();
for(;;)
{
uart_s =uart_recive();
/* 返回值 0:接受完成 */
/* 1:数据未准备好 */
/* -1:串口接受错误 */
/* 2:中断超时错误 */
/* 3: 较验出错 */
if(uart_s ==0)
{
/*不是命令帧*/
if(precieve->Type != UARTCOMMAND)
{
/*无效命令*/
psend->Length = FRAMLONGTH;
psend->Type = UARTCOMMAND;
psend->Data[0] = COMMANDNODO;
psend->Mutul = UARTCONT;
uart_send();
precieve->Type = UARTCOMMAND;
continue;
}
}
/*接收从主机的数据*/
precieve = (PuartForDec5416)(&uart[0]);
switch(precieve->Data[0])
{
/*AD设置*/
case FILTERSET:
for(i=0;i<5;i++)
{
filterset[i] = precieve->Data[i+1];
}
/*设置数据发送长度*/
datasendlong = pfilterset->SampleLong;
datasendlength= 2 * datasendlong;
precieve->Data[0] = 0;
break;
/*启动AD采样*/
case FILTERSTART:
convcount=0;
adconvover=0;
sendcount=0;
datasendlength= 2 * datasendlong;
/*AD采样率*/
switch( pfilterset->SampleRate)
{
case ADSAMPL8K: //0xd //采样率为8k
convtimes=24;
convtimesback=24;
break;
case ADSAMPL44K: // 0x23 //采样率为44k
convtimes=4;
convtimesback=4;
break;
case ADSAMPL96K://0x1d //采样率为96k
convtimes=2;
convtimesback=2;
break;
default:
break;
}
AdInit();
for(;;)
{
if (adconvover==1)
{
break;
}
}
/*AD采样结束*/
for(i=0;i<datasendlong;i++)
{
Ad_data[i]=(Ad_data[i]>>6)-0x136;
filter_data[i]=Ad_data[i]*32;
//除以1024,变成小数,再转换成q15。
}
/*fir滤波处理*/
if(pfilterset->FilterType == FIRFILTER)
{
lpf.dbuffer_ptr=&lpf.dbuffer[0];
lpf.coeff_ptr=&lpf.coeff[0];
lpf.init(&lpf);
for(i=0;i<datasendlong;i++)
{
lpf.input=filter_data[i];
lpf.calc(&lpf);
filter_result[i]=lpf.output;
}
for(i=0;i<datasendlong;i++)
{
filter_result[i]=filter_result[i]/32;
//转换成浮点数,再乘以1024。
//lpf.output/32768*1024
Ad_data[datasendlong+i]=filter_result[i];
}
}
else
{
iir.dbuffer_ptr= dbuffer;
/* Object Initialization */
iir.coeff_ptr=coeff;
iir.qfmat=IIR_LPF_QFMAT;
iir.nbiq=IIR_LPF_NBIQ;
//iir.nbiq=8;
iir.isf=IIR_LPF_ISF;
iir.init(&iir);
for(i=0;i<datasendlong;i++)
{
iir.input=filter_data[i];
iir.calc(&iir);
/* Invoke the Computation routine */
filter_result[i]=iir.output;
}
for(i=0;i<datasendlong;i++)
{
filter_result[i]=filter_result[i]/16;
//直接输出为Q14格式,所以除以16。
Ad_data[datasendlong+i]=filter_result[i];
}
}
//AD采样滤波结束。发送命令。
psend->Length = 1;
psend->Type = UARTCOMMAND;
psend->Data[0] = FILTEROVER;
psend->Mutul = UARTCONT;
uart_send();
precieve->Data[0] = 0;
break;
/*AD数据传送*/
case FILTERDATASEND:
/*不满buffer的数据*/
if(datasendlength <= 256)
{
for(i = 0;i<datasendlength;i++)
{
psend->Data[i] = Ad_data[i+sendcount*256];
}
psend->Length = datasendlength;
psend->Type = UARTDATA;
psend->Mutul = UARTCONT;
uart_send();
precieve->Data[0] = 0;
break;
}
/*满buffer数据*/
for(k = 0; k<256;k++)
{
psend->Data[k] = Ad_data[k+sendcount*256];
}
psend->Length = 256;
psend->Type = UARTDATA;
psend->Mutul = UARTMUTL;
uart_send();
datasendlength= datasendlength - 256;
sendcount++;
precieve->Data[0] = 0;
break;
case RECIEVEERROR:
datasendlength = datasendlength + 256;
sendcount--;
precieve->Data[0] = ADDATASEND;
break;
/*系统复位*/
case SYSRESET:
precieve->Data[0] = 0;
/* reset adc */
*ADCTRL1 = 0x4000; //RESET ADC
*ADCTRL2 = 0x4000;// reset sequencer to state CONV00
*MAXCONV = 0;// Number of conversions =1
sys_reset();
NOP;
break;
default:
break;
}
}
}
void SystemInit(void)
{
WSGR = 0x80;
*WDCR = 0x68;
*SCSR1 = 0x080; //40MHZ
*MCRA = 0x04;
*XINT1CR = 0x01;
}
void AdInit(void)
{
/* reset adc */
*ADCTRL1 = 0x4000; //RESET ADC
*ADCTRL2 = 0x4000;// reset sequencer to state CONV00
*MAXCONV = 0;// Number of conversions =1
NOP;
/* run,seq casc operation */
*ADCTRL1 = 0x3030;
*MAXCONV = 0x00;//
*CHSELSEQ1 = 0x3210;
*CHSELSEQ2 = 0x7654;
*CHSELSEQ3 = 0xBA98;
*CHSELSEQ4 = 0xFEDC;
*ADCTRL2 = 0x2600;
}
void PHANTOM(void)
{
}
void init_UART(void)
{
UARTA_LCR = (data_w8+data_s1+LC_1_DLAB); /*8位数据 1停止位 不校验 开启除数转换*/
UARTA_DLL = buad_19k2_l; /*9.6K波特率*/
UARTA_DLH = buad_19k2_h;
UARTA_LCR = (data_w8+data_s1+LC_0_DLAB); /*8位数据 1停止位 不校验 关闭其余寄存器转换*/
UARTA_MCR = UartLoop;
UARTA_FCR = fifo_reset;
UARTA_FCR = fifo_enable+fifo_txdip8+fifo_rxdip8;//TRIGLE level =8
UARTA_IER = uartint_rhr;
for(i= 0; i<0x104;i++)
{
uart[i] = 0;
uarts[i] = 0;
}
for(i=0;i<32;i++)
{
sys_statbuff[i]=0;//系统标志buff清0
}
}
interrupt void c_int1(void)//串口接收中断
{
int i;
DINT;
if((*PIVR & 0x01) == 0x01)//xint1中断
{
if((INT1_RD & 0x02) == 0x02)//uarta中断
{
temp=UARTA_LSR;//读一次lsr,第一次读有可能有误。
temp=UARTA_LSR;
for(i=0;i<8;i++)//fifo有8个字节等待读。
{
if (((temp&0x1e)==0)&&((temp&0x01)==1))//无串口接收错误
{
uarta_recbuff[sys_statbuff[RECAADDR]]=UARTA_RHR&0xff;//接收数据
sys_statbuff[RECAADDR]++;
}
else
{
sys_statbuff[UARTAERR]=1;//错误标志为1
sys_statbuff[RECAADDR]=0;//缓冲区接收位置清0
break;//中止循环
}
}//for(i=0;i<8;i++)//fifo有8个字节等待读
UARTA_FCR = fifo_rreset;//3rest r fifo,enable fifo
if(sys_statbuff[RECAADDR]==FRAMLONGTH*2)//满帧
{
if (sys_statbuff[RECANEW]==1)//上一帧新帧标志仍未清除
{
sys_statbuff[UARTIMEA]=1;//超时错误置一
}
sys_statbuff[RECANEW]=1;//新帧标志置一
sys_statbuff[RECAADDR]=0;//缓冲区接收位置清0
//转移到uart[]。
for(i=0;i<FRAMLONGTH;i++)
{
uart[i]=(uarta_recbuff[i*2]<<8)+uarta_recbuff[i*2+1];
}
}
if(sys_statbuff[RECAADDR]>FRAMLONGTH*2)//超帧
{
// sys_statbuff[UARTAERR]=1;//错误标志为1
sys_statbuff[RECAADDR]=0;//缓冲区接收位置清0
}
}//if((INT1_RD & 0x02) == 0x02)//uarta中断
*XINT1CR = *XINT1CR | 0x8000;
} //if((*PIVR & 0x01) == 0x01)//xint1中断
// *IFR = *IFR & 0x01;
// EINT;
}
interrupt void c_int6(void)
{
NOP;
DINT;
if(*PIVR == 0x4)
{
convtimes--;
if(convtimes==0)
{
convtimes=convtimesback;
Ad_data[convcount] = *RESULT0;
convcount++;
if (convcount==pfilterset->SampleLong)
{
convcount=0;
adconvover=1;//接满标志
}
else
{
//reset sequencer to state CONV00
//清除中断状态位
*ADCTRL2 = *ADCTRL2 | 0x4000;
NOP;
NOP;
*ADCTRL2 = *ADCTRL2 | 0x2000;
}
}
else
{
//reset sequencer to state CONV00
//清除中断状态位
*ADCTRL2 = *ADCTRL2 | 0x4000;
NOP;
NOP;
*ADCTRL2 = *ADCTRL2 | 0x2000;
}
}
// *IFR = *IFR & 0x20;
// EINT;
}
/* 返回值 0:接受完成 */
/* 1:数据未准备好 */
/* -1:串口接受错误 */
/* 2:中断超时错误 */
/* 3: 较验出错 */
int uart_recive(void)
{
int check;
/*判断串口是否故障*/
if(sys_statbuff[UARTAERR] != 0)
{
sys_statbuff[UARTAERR]=0;
return -1;
}
/*判断超时是否故障*/
// if(sys_statbuff[UARTIMEA] != 0)
// {
// return 2;
// }
/*数据未准备好*/
if(sys_statbuff[RECANEW] != 1)
{
return 1;
}
sys_statbuff[RECANEW]=0;//新帧标志位清零
check=0;
for(i=0;i<FRAMLONGTH-1;i++)
{
check=check ^ uart[i];
}
if(check!=uart[FRAMLONGTH-1])//校验不正确
{
return 3;
}
return 0;
}
unsigned int uart_send(void)
{
unsigned int i;
unsigned int send_datah;
unsigned int timeout = 0x4000;
unsigned int check = 0;
for(i = 0; i<FRAMLONGTH-1; i++)
{
for(;;)
{
timeout--;
temp=UARTA_LSR;
/*上一次发送是否完成*/
if(UARTA_LSR & 0x40)
{
/*发送数据的高8位*/
send_datah = uarts[i];
check = check ^ (send_datah);
UARTA_THR = send_datah>>8;
break;
}
/*检查是否超时*/
if(!(timeout))
{
return 0xFFFF;
}
}
timeout = 0x4000;
for(;;)
{
timeout--;
/*上一次发送是否完成*/
if(UARTA_LSR & 0x40)
{
/*发送数据的低8位*/
UARTA_THR = uarts[i];
break;
}
/*检查是否超时*/
if(!(timeout))
{
return 0xFFFF;
}
}
}
/*发送校验结果*/
for(;;)
{
timeout--;
/*上一次发送是否完成*/
if(UARTA_LSR & 0x40)
{
/*发送数据的高8位*/
send_datah = (check>>8);
UARTA_THR = send_datah;
break;
}
/*检查是否超时*/
if(!(timeout))
{
return 0xFFFF;
}
}
timeout = 0x4000;
for(;;)
{
timeout--;
/*上一次发送是否完成*/
if(UARTA_LSR & 0x40)
{
/*发送数据的低8位*/
UARTA_THR = check;
break;
}
/*检查是否超时*/
if(!(timeout))
{
return 0xFFFF;
}
}
uarts[FRAMLONGTH-1]=check;
return 0;
}
void sys_reset(void)
{
WSGR = 0;
*WDCR = 0x08;
for(;;){};
/*
asm(" B 768H "); */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -