⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 limingqi_fir.c

📁 为dsp编写的fir滤波器程序
💻 C
字号:

///////////////* FIR Filter  *///////////////

#include "DSP281x_Device.h" 
#include "stdio.h"
#include "math.h"

void FIR_deal();
void FIR_initial();
void InitSystem(void);
void Configure_GPIO(void);
void delay_us(unsigned int x);
void delay_ms(unsigned int x);
void Send_DAC_data(unsigned char command,unsigned int data);
interrupt void cpu_timer0_isr(void);


#define  SET_SCLK  	GpioDataRegs.GPFSET.bit.GPIOF0 = 1
#define  CLC_SCLK   GpioDataRegs.GPFCLEAR.bit.GPIOF0 = 1

#define  SET_DOUT  	GpioDataRegs.GPFSET.bit.GPIOF1 = 1
#define  CLC_DOUT   GpioDataRegs.GPFCLEAR.bit.GPIOF1 = 1

#define  SET_SYNC  	GpioDataRegs.GPFSET.bit.GPIOF2 = 1
#define  CLC_SYNC   GpioDataRegs.GPFCLEAR.bit.GPIOF2 = 1

#define PI 3.14159265
#define T1  1000    // 周期为 1000 us 
#define T2  1000    // 周期为 1000 us 
#define sample_rate 50 // 设定采样周期 us
unsigned long DAC_data = 0;
unsigned int t=0;


#define  FIR_ORDER   136
unsigned long  FIR_INPUT[FIR_ORDER];
unsigned long  ADC_result=0;
unsigned long  FIR_OUT=0;
unsigned int   FIR_new_point = 0;
unsigned int   FIR_old_point = 0;

/////////////*  采样率为 20 kHz  *////////////////
/*   通带 800 - 1200 Hz  */

int FIR_COEFF[FIR_ORDER/2] = {
        0,      0,      0,     11,     35,     60,     83,    101,    111,
      109,     94,     65,     24,      0,      0,      0,      0,      0,
        0,      0,      0,      0,      0,     47,    144,    236,    311,
      360,    376,    354,    292,    195,     70,      0,      0,      0,
        0,      0,      0,      0,      0,      0,      0,     97,    287,
      458,    589,    666,    679,    623,    503,    328,    115,      0,
        0,      0,      0,      0,      0,      0,      0,      0,      0,
      127,    370,    578,    729,    809,
};

void main(void)
{
	delay_ms(10);
	
	InitSystem();
	
	Configure_GPIO();
	
	InitPieCtrl();
		
	InitPieVectTable();
		
	EALLOW;
   	PieVectTable.TINT0 = &cpu_timer0_isr;
   	EDIS;
	
	InitCpuTimers();
	
    ConfigCpuTimer(&CpuTimer0,150,sample_rate);
    
    // Enable TINT0 in the PIE: Group 1 interrupt 7
   	PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

	// Enable CPU INT1 which is connected to CPU-Timer 0:
    IER = 1;
    
	// Enable global Interrupts and higher priority real-time debug events:
   	EINT;   // Enable Global interrupt INTM
   	ERTM;   // Enable Global realtime interrupt DBGM
   	
   	// 启动定时器
   	CpuTimer0Regs.TCR.bit.TSS = 0;
   	
	while(1);
}

interrupt void cpu_timer0_isr(void)
{
	DAC_data = ( unsigned long ) 512*(1+sin(2*PI*t/T1));
	ADC_result = DAC_data;
	FIR_deal();
	DAC_data = FIR_OUT>>9;
	t = t + sample_rate;
	if(t>T1) t=0;

	Send_DAC_data(0x24,DAC_data);
	
	//允许 CPU 响应中断  	
	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

void FIR_initial()
{
	unsigned char n;
	for(n=0;n<FIR_ORDER;n++) FIR_INPUT[n] = 0;
}

void FIR_deal()
{
	unsigned int  n,point0,point1,Order0;
	
	Order0 = FIR_ORDER/2;
	FIR_new_point++;
	FIR_old_point = FIR_new_point + 1;
	if(FIR_new_point>=FIR_ORDER) FIR_new_point = 0;
	if(FIR_old_point>=FIR_ORDER) FIR_old_point = 0;
	FIR_INPUT[FIR_new_point] = ADC_result;
	
	FIR_OUT = 0;
	point0 = FIR_new_point;
	point1 = FIR_old_point;
	
	if(FIR_new_point<FIR_ORDER/2)
	{
		for(n=0;n<Order0;n++)
		{
			FIR_OUT = FIR_COEFF[n]*(FIR_INPUT[point0]+FIR_INPUT[point1]) + FIR_OUT;
			point1++;
			if(point0>0) point0--;
			else point0 = FIR_ORDER - 1;			
		}
	}
	else
	{
		for(n=0;n<Order0;n++)
		{	
			FIR_OUT = FIR_COEFF[n]*(FIR_INPUT[point0]+FIR_INPUT[point1]) + FIR_OUT;
			point0--;
			point1++;
			if(point1>=FIR_ORDER) point1 =0;
		}
	}
}


void InitSystem(void)
{
	EALLOW ; // 在向EALLOW保护型寄存器中写数据前, 需要执行该指令来解除保护
	
	SysCtrlRegs.WDCR = 0x00E8;   // 设置看门狗模块(目前已禁用)
			// 赋值0x00E8 则禁止看门狗模块, 时钟预定标系数 = 1 ;
			// 赋值0x00AF 则不禁止看门狗模块, 时钟预定标系数 = 64 ;
				
//	SysCtrlRegs.SCSR = 0;

	SysCtrlRegs.PLLCR.bit.DIV = 10; // 将 CPU 的 PLL 倍频系数设为5
									// 当 PLL 未被旁路时 CLKIN = (OSCCLK * DIV)/2
									
	// HSPCLK = SYSCLKOUT/(HISPCP * 2)
	// LSPCLK = SYSCLKOUT/(LOSPCP * 2)
	SysCtrlRegs.HISPCP.all = 0x1;   // 将高速时钟的预定标器设置成 SYSCLKOUT/2 模式
	SysCtrlRegs.LOSPCP.all = 0x2;   // 将低速时钟的预定标器设置成 SYSCLKOUT/4 模式
	
	// 根据需要使能各外设模块的时钟输入 
	SysCtrlRegs.PCLKCR.bit.EVAENCLK   = 0;
	SysCtrlRegs.PCLKCR.bit.EVBENCLK   = 0;
	SysCtrlRegs.PCLKCR.bit.SCIAENCLK  = 0;
	SysCtrlRegs.PCLKCR.bit.SCIBENCLK  = 0;
	SysCtrlRegs.PCLKCR.bit.MCBSPENCLK = 0;
	SysCtrlRegs.PCLKCR.bit.SPIENCLK   = 0;
	SysCtrlRegs.PCLKCR.bit.ECANENCLK  = 0;
	SysCtrlRegs.PCLKCR.bit.ADCENCLK   = 0;
	
	EDIS ; // 执行该指令后,任何对 EALLOW 保护型寄存器的写操作都将被禁止
}

void Configure_GPIO(void)
{
	EALLOW;
	
	GpioMuxRegs.GPAMUX.all = 0x00;   // 将所有的 GPIO 引脚配置成通用 I/O 口
	GpioMuxRegs.GPBMUX.all = 0x00;
	GpioMuxRegs.GPDMUX.all = 0x00;
	GpioMuxRegs.GPEMUX.all = 0x00;
	GpioMuxRegs.GPFMUX.all = 0x00;
	GpioMuxRegs.GPGMUX.all = 0x00;
	
	// 复位后默认状态为输入, 0为输入,1为输出
	GpioMuxRegs.GPADIR.all = 0x00ff; //将 GPIO 口 A7-A0   配置成输出
									 //将 GPIO 口 A15 -A8 配置成输入
	GpioMuxRegs.GPBDIR.all = 0xffff; //将 GPIO 口 B15 -B0 配置成输出
	
	GpioMuxRegs.GPFDIR.all = 0xffff;
									 
	GpioMuxRegs.GPAQUAL.all = 0xff;  // 设置 GPIO 量化输入设定
		// 输入信号的采样时间长度 = 510 个 SYSCLKOUT 周期,只有在上述规定时间内
		// 采样输入得到的高低电平状态一直保持不变,才被作为有效输入
	GpioMuxRegs.GPBQUAL.all = 0x0;   // 设置 GPIO 输入量化器的值为 0 
	GpioMuxRegs.GPDQUAL.all = 0x0;
	GpioMuxRegs.GPEQUAL.all = 0x0;
	
	EDIS;
}

// 150 MHz 执行时间约为 5 us
void Send_DAC_data(unsigned char command,unsigned int data) // send data to DAC8532 ( TI free simple )
{
	unsigned char n=0;
	SET_SYNC;
	CLC_SCLK;
	asm(" NOP ");
	CLC_SYNC;
	for(n=8;n>0;n--)
	{
		SET_SCLK;
		if(command & 0x80) SET_DOUT;
		else CLC_DOUT;
		CLC_SCLK;
		command = command << 1;
	}
	for(n=16;n>0;n--)
	{
		SET_SCLK;
		if(data & 0x8000) SET_DOUT;
		else CLC_DOUT;
		CLC_SCLK;
		data = data << 1;
	}
	SET_SYNC;
}

void delay_ms(unsigned int x)
{
	unsigned int a=0;
	for(;x>0;x--)
	for(a=30000;a>0;a--);
}

void delay_us(unsigned int x)
{
	unsigned int a=0;
	for(;x>0;x--)
	for(a=28;a>0;a--);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -