- #pragma DATA_SECTION (ping_buffer, "DMARAML5"); // Place ping and pong in DMA RAM L5
- #pragma DATA_SECTION (pong_buffer, "DMARAML5");
- #pragma DATA_SECTION (out1, "DMARAML6"); // Place ping and pong in DMA RAM L5
- #pragma DATA_SECTION (out2, "DMARAML6");
- Uint32 out1[1024]; //512// Note that Uint32 is used, not Uint16
- Uint32 out2[1024]; //512
- Uint32 ping_buffer[1024]; //512 // Note that Uint32 is used, not Uint16
- Uint32 pong_buffer[1024]; //512
- Uint32 * L_channel = &ping_buffer[0]; // This pointer points to the beginning of the L-C data in either of the buffers
- Uint32 * R_channel = &ping_buffer[512]; //256 // This pointer points to the beginning of the R-C data in either of the buffers
- Uint32 ping_buff_offset = (Uint32) &ping_buffer[0];
- Uint32 pong_buff_offset = (Uint32) &pong_buffer[0];
- Uint32 out1_offset = (Uint32) &out1[0];
- Uint32 out2_offset = (Uint32) &out2[0];
- Uint16 first_interrupt = 1; // 1 indicates first interrupt
- Uint32 k = 0;
- int i, j;
- //#pragma DATA_SECTION(noise, ".X");
- int noise[NUM_OF_POINT];
- //#pragma DATA_SECTION(out_error, ".X");
- int out_error[NUM_OF_POINT];
- //#pragma DATA_SECTION(out_error2, ".X");//
- //float out_error2[NUM_OF_POINT];//
- //#pragma DATA_SECTION(out_y, ".X");
- int out_y[1024];//512
- //#pragma DATA_SECTION(out_y2, ".X");//
- //float out_y2[NUM_OF_POINT];//
- void main(void)
- {
- EALLOW;
- // Step 1. Initialize System Control:
- // PLL, WatchDog, enable Peripheral Clocks
- InitSysCtrl();
- // Step 2. Initalize GPIO:
- // For this example, enable the GPIO PINS for McBSP operation.
- InitMcbspGpio();
- InitI2CGpio();
- /* Fill the buffer with dummy data */
- for(k=0; k<1024; k++) { ping_buffer[k] = 0x00000000; } //1024
- for(k=0; k<1024; k++) { pong_buffer[k] = 0x00000000; }
- for(k=0; k<1024; k++) { out1[k] = 0x00000000; }
- for(k=0; k<1024; k++) { out2[k] = 0x00000000; }
- // Step 3. Clear all interrupts and initialize PIE vector table:
- // Disable CPU interrupts
- DINT;
- // Initialize PIE control registers to their default state.
- // The default state is all PIE interrupts disabled and flags
- // are cleared.
- // This function is found in the DSP2833x_PieCtrl.c file.
- InitPieCtrl();
- EALLOW;
- DINT; // Disable interrupts again (for now)
- // Disable CPU interrupts and clear all CPU interrupt flags:
- IER = 0x0000;
- IFR = 0x0000;
- // Step 4. Initialize the Peripherals
- ping_buff_offset++; // Start at location 1 (32-bit r/w from loc. 1, then 0)
- pong_buff_offset++; // Start at location 1 (32-bit r/w from loc. 1, then 0) //init_mcbsp_spi(); // Initialize McBSP-B as SPI Control
- out1_offset++; // Start at location 1 (32-bit r/w from loc. 1, then 0)
- out2_offset++; // Start at location 1 (32-bit r/w from loc. 1, then 0)
- I2CA_Init();
- AIC23Write(0x00,0x1f);//左声道输入音量
- Delay(100);
- AIC23Write(0x02,0x1f);//右声道输入音量
- Delay(100);
- AIC23Write(0x04,0xBf);//左声道输出音量
- Delay(100);
- AIC23Write(0x06,0xBf);//右声道输出音量
- Delay(100);
- AIC23Write(0x08,0x12);//AIC23Write(0x08,0x12);//DAC选择,lin输入//AIC23Write(0x08,0x14);//DAC选择,MIC输入
- Delay(100);
- AIC23Write(0x0A,0x00);//AIC23Write(0x0A,0x00);
- Delay(100);
- AIC23Write(0x0C,0x00);
- Delay(100);
- AIC23Write(0x0E,0x43);//AIC23Write(0x0E,0x43);//数字音频接口格式控制,AIC23主模式,dsp初始化,转换比特值设定00即:16bit--》96dB//AIC23Write(0x0E,0x63);
- Delay(100);
- AIC23Write(0x10,0x0d);//AIC23Write(0x10,0x23/0c);//设置采样率为16khz;USB模式下时钟为12mhz,采样率为12/272=44.1Khz//AIC23Write(0x10,0xce);
- Delay(100);
- AIC23Write(0x12,0x01);//激活标志
- Delay(100); //AIC23Init
- // AIC23Write(0x1e,0x00);//激活标志
- //AIC23Init
- init_dma(); // Initialize the DMA before McBSP, so that DMA is ready to transfer the McBSP data
- InitMcbspa();
- //init_mcbspa(); // Initalize McBSP-A
- //init_zone7();
- //InitMcbspa(); //init_mcbspa(); // Initalize McBSP-A
- delay_loop();
- EALLOW;
- DmaRegs.CH1.CONTROL.bit.RUN = 1; // Start rx on Channel 1
- /* Reassign ISRS */
- PieVectTable.DINTCH1 = &local_D_INTCH1_ISR;
- PieVectTable.DINTCH2 = &local_D_INTCH2_ISR;
- /* Configure PIE interrupts */
- PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable vector fetching from PIE block
- PieCtrlRegs.PIEACK.all = 0xFFFF; // Enables PIE to drive a pulse into the CPU
- // The interrupt can be asserted in the following interrupt lines
- PieCtrlRegs.PIEIER7.bit.INTx1 = 1; // Enable INTx.1 of INT7 (DMA CH1)
- PieCtrlRegs.PIEIER7.bit.INTx2 = 1; // Enable INTx.2 of INT7 (DMA CH2)
- /* Configure system interrupts */
- IER |= 0x0040; // Enable INT7
- EINT; // Global enable of interrupts
- EDIS;
- /* Wait for data */
- while(1) {
- for(i=0;i<512;i++)
- {
- noise[i]=ping_buffer[i];
- noise[i+512]=pong_buffer[i];
- out_error[i]=ping_buffer[i+512];
- out_error[i+512]=pong_buffer[i+512];
- }
- for(i=0;i<1024;i++) { if(i<LMS_M) { for(j=0;j<=i;j++) { lms_x[j] =noise[i-j]; lms_error[j]=out_error[i-j]; } } else { for(j=0;j<LMS_M;j++) { lms_x[j] = noise[i-j]; lms_error[j]=out_error[i-j]; } } lms_param_in.d = noise[i];//signal_noise[i]; lms_param_in.error = &lms_error[0]; lms_param_in.x_ptr = &lms_x[0]; lms_param_in.length_x = LMS_M; LMS_Gradient_Instantaneous_Estimates(&lms_param_in, &lms_param_out); //运行瞬时梯度估计LMS算法 耗时514个时钟周期 out_y[i] =lms_param_out.y;// //Delay(10); //out_y[i] =noise[i]; }
- for(i=0;i<512;i++)
- {
- out1[i]=out_y[i]; //输出左通道
- out1[i+512]=out_y[i]; //输出右通道
- out2[i]=out_y[i+512]; //输出左通道
- out2[i+512]=out_y[i+512];//输出右通道
- }
- }//while
- }//main
- // INT7.1 -
- interrupt void local_D_INTCH1_ISR(void) // DMA Ch1 - McBSP-A Rx
- {
- EALLOW;
- if(first_interrupt==1) // No processing needs to be done (B/c interrupt occurs
- { // at beginning of DMA transfers to ping buffer - no data received yet)
- first_interrupt=0; // Turn flag off and exit interrupt
- }
- else
- {
- DmaRegs.CH2.CONTROL.bit.RUN = 1;
- }
- // When DMA first starts working on ping buffer, set the shadow registers
- // to start at pong buffer next time and vice versa
- if( DmaRegs.CH1.DST_ADDR_SHADOW == ping_buff_offset)
- {
- DmaRegs.CH1.DST_ADDR_SHADOW = pong_buff_offset;
- DmaRegs.CH1.DST_BEG_ADDR_SHADOW = pong_buff_offset;
- }
- else
- {
- DmaRegs.CH1.DST_ADDR_SHADOW = ping_buff_offset;
- DmaRegs.CH1.DST_BEG_ADDR_SHADOW = ping_buff_offset;
- }
- // To receive more interrupts from this PIE group, acknowledge this interrupt
- PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;
- EDIS;
- }
- // INT7.2
- interrupt void local_D_INTCH2_ISR(void) // DMA Ch2 - McBSP-A Tx
- {
- // When DMA first starts working on ping buffer, set the shadow registers
- // to start at pong buffer next time and vice versa
- EALLOW;
- if(DmaRegs.CH2.SRC_ADDR_SHADOW == out1_offset)//
- {
- DmaRegs.CH2.SRC_ADDR_SHADOW = out2_offset;//
- DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = out2_offset;//(Uint32)&out_y[0];
- }
- else
- {
- DmaRegs.CH2.SRC_ADDR_SHADOW =out1_offset;//pong_buff_offset;//(Uint32)&out_y[0];
- DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = out1_offset;//pong_buff_offset;//(Uint32)&out_y[0];
- }
- PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // To receive more interrupts from this PIE group, acknowledge this interrupt
- EDIS;
- }
- void init_dma()
- {
- EALLOW;
- DmaRegs.DMACTRL.bit.HARDRESET = 1;
- asm(" NOP");
- DmaRegs.PRIORITYCTRL1.bit.CH1PRIORITY = 0;
- /* DMA Channel 1 - McBSP-A Receive */
- DmaRegs.CH1.BURST_SIZE.all = 1; // 2 16-bit words/burst (1 32-bit word) - memory address bumped up by 1 internally
- DmaRegs.CH1.SRC_BURST_STEP = 1; // DRR2 must be read first & then DRR1. Increment by 1. Hence a value of +1. (This is a 2's C #)
- DmaRegs.CH1.DST_BURST_STEP = -1; // Copy DRR2 data to address N+1 and DRR1 data to N. Hence -1 (32-bit read= read addr N+1 as MSB, then N as LSB)
- DmaRegs.CH1.TRANSFER_SIZE = 1023;//511; // DMA Interrupt every 1024 (n+1) bursts (1024 32-bit words).
- DmaRegs.CH1.SRC_TRANSFER_STEP = -1; // Decrement source address by 1 (from DRR1 back to DRR2) after processing a burst of data
- DmaRegs.CH1.DST_TRANSFER_STEP = 1025;//513; // After copying 1 32-bit word of L-C data (1 burst), move down to R-C data in a given buffer
- DmaRegs.CH1.SRC_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR2.all; // First read from DRR2
- DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DRR2.all;
- DmaRegs.CH1.DST_ADDR_SHADOW = ping_buff_offset; // First write to ping_buffer[1]
- DmaRegs.CH1.DST_BEG_ADDR_SHADOW = ping_buff_offset;
- DmaRegs.CH1.DST_WRAP_SIZE = 1; // After LEFT(1) and then RIGHT(2), go back to LEFT buffer
- DmaRegs.CH1.SRC_WRAP_SIZE = 0xFFFF; // Arbitary large value. We'll never hit this.....
- DmaRegs.CH1.DST_WRAP_STEP = 2; // From starting address, move down 2 16-bit addresses to write nxt 32-bit word
- DmaRegs.CH1.CONTROL.bit.PERINTCLR = 1;
- DmaRegs.CH1.CONTROL.bit.SYNCCLR = 1;
- DmaRegs.CH1.CONTROL.bit.ERRCLR = 1;
- DmaRegs.CH1.MODE.bit.CHINTE = 1; // Enable DMA channel interrupts
- DmaRegs.CH1.MODE.bit.CHINTMODE = 0; // Interrupt at beginning of transfer
- DmaRegs.CH1.MODE.bit.PERINTSEL = 15; // McBSP MREVTA
- DmaRegs.CH1.MODE.bit.CONTINUOUS = 1; // Enable continuous mode (continuously receives)// Enable interrupts from peripheral (to trigger DMA)
- DmaRegs.CH1.MODE.bit.PERINTE = 1; // Enable interrupts from peripheral (to trigger DMA)
- /* DMA Channel 2 - McBSP-A Transmit */
- DmaRegs.CH2.BURST_SIZE.all = 1; // 2 16-bit words/burst (1 32-bit word) - value bumped up by 1 internally
- DmaRegs.CH2.SRC_BURST_STEP = -1; // Copy data at address N+1 to DXR2 first then data at N to DXR1. Hence -1
- DmaRegs.CH2.DST_BURST_STEP = 1; // DXR2 must be written to first & then DXR1. Increment by 1. Hence a value of +1. (This is a 2's C #)
- DmaRegs.CH2.TRANSFER_SIZE = 1023;//511; // DMA Interrupt every 1024 (n+1) 16-bit words. McBSP still handles 16-bit data only in registers
- DmaRegs.CH2.SRC_TRANSFER_STEP = 1025;//513; // After copying 1 32-bit word L-C data, move down to R-C data in a given buffer
- DmaRegs.CH2.DST_TRANSFER_STEP = -1; // Decrement dest. address by 1 (DXR1 back to DXR2) after processing a burst of data
- DmaRegs.CH2.SRC_ADDR_SHADOW = out1_offset;//; // First read from ping_buffer[1]
- DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = out1_offset;//;
- DmaRegs.CH2.DST_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR2.all; // First write to DXR2
- DmaRegs.CH2.DST_BEG_ADDR_SHADOW = (Uint32) &McbspaRegs.DXR2.all;
- DmaRegs.CH2.SRC_WRAP_SIZE = 1; // After LEFT(1) and then RIGHT(2), go back to LEFT buffer
- DmaRegs.CH2.DST_WRAP_SIZE = 0xFFFF; // Arbitary large value. We'll never hit this.....
- DmaRegs.CH2.SRC_WRAP_STEP = 2; // From starting address, move down 2 16-bit addresses to read next 32-bit word
- DmaRegs.CH2.CONTROL.bit.PERINTCLR = 1;
- DmaRegs.CH2.CONTROL.bit.SYNCCLR = 1;
- DmaRegs.CH2.CONTROL.bit.ERRCLR = 1;
- DmaRegs.CH2.MODE.bit.CHINTE = 1; // Enable DMA channel interrupts
- DmaRegs.CH2.MODE.bit.CHINTMODE = 0; // Interrupt at beginning of transfer
- DmaRegs.CH2.MODE.bit.PERINTSEL = 14; // McBSP MXEVTA
- DmaRegs.CH2.MODE.bit.CONTINUOUS = 1; // Enable continuous mode (continuously transmits)
- DmaRegs.CH2.MODE.bit.PERINTE = 1; // Enable interrupts from peripheral (to trigger DMA)
- }
- void I2CA_Init(void)
- {
- // Initialize I2C
- I2caRegs.I2CSAR = 0x001A; // Slave address - EEPROM control code
- #if (CPU_FRQ_150MHZ) // Default - For 150MHz SYSCLKOUT
- I2caRegs.I2CPSC.all = 14; // Prescaler - need 7-12 Mhz on module clk (150/15 = 10MHz)
- #endif
- #if (CPU_FRQ_100MHZ) // For 100 MHz SYSCLKOUT
- I2caRegs.I2CPSC.all = 9; // Prescaler - need 7-12 Mhz on module clk (100/10 = 10MHz)
- #endif
- I2caRegs.I2CCLKL = 100; // NOTE: must be non zero
- I2caRegs.I2CCLKH = 100; // NOTE: must be non zero
- I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts
- // I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
- I2caRegs.I2CMDR.all = 0x0420; // Take I2C out of reset //zq0x0420 // Stop I2C when suspended
- I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
- I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,
- return;
- }
- Uint16 AIC23Write(int Address,int Data)
- {
- if (I2caRegs.I2CMDR.bit.STP == 1)
- {
- return I2C_STP_NOT_READY_ERROR;
- }
- // Setup slave address
- I2caRegs.I2CSAR = 0x1A;
- // Check if bus busy
- if (I2caRegs.I2CSTR.bit.BB == 1)
- {
- return I2C_BUS_BUSY_ERROR;
- }
- // Setup number of bytes to send
- // MsgBuffer + Address
- I2caRegs.I2CCNT = 2;
- I2caRegs.I2CDXR = Address;
- I2caRegs.I2CDXR = Data;
- // Send start as master transmitter
- I2caRegs.I2CMDR.all = 0x6E20;
- return I2C_SUCCESS;
- }
下面是算法部分代码:
- #include <dotp.h>
- #include <string.h>
- #include "LMS.h"
- #include "math.h"
- #pragma DATA_ALIGN(lms_x, 8)
- float lms_x[LMS_M];
- #pragma DATA_ALIGN(lms_x, 8)
- float lms_error[LMS_M];
- //输入信号向量存储数组
- #pragma DATA_ALIGN(lms_w_forward, 8)
- float lms_w_forward[LMS_M]; //用于存储未来一时刻滤波系数向量w(k+1)
- #pragma DATA_ALIGN(lms_w, 8)
- float lms_w[LMS_M]; //用于存储当前时刻滤波系数矢量w(k)
- //#pragma DATA_ALIGN(f, 8)
- //float f1=-0.0975884274,f2=-0.05387716,f3=-0.0100407312,f4=0.0334515497,f5=0.0760843381,f6=0.117433414,f7=0.157142982,f8=0.195035622,f9=-0.0992347822,f10=-0.0552046672,f11=-0.0110044545,f12=0.0329072662,f13=0.0759775937,f14=0.117753103,f15=0.157848254,f16=0.196025595;
- float a=2,b=0.000000000000025;//0.000000000000025;//
- Adaptive_Filter_In lms_param_in;
- Adaptive_Filter_Out lms_param_out;
- void LMS_Gradient_Instantaneous_Estimates(Adaptive_Filter_In *lms_in, Adaptive_Filter_Out* lms_out)
- {
- int i;
- static int FIR_order;
- static unsigned char First_in_flag = 1;
- static float *w_ptr, *w_forward_ptr, *Temp_w_ptr;
- static float *x_ptr,*error;
- float temp,yy=0;
- if(First_in_flag )
- {
- First_in_flag = 0;
- FIR_order = lms_in->length_x;
- memset((void *)lms_w_forward, 0, FIR_order*4);
- memset((void *)lms_w, 0, FIR_order*4);
- w_forward_ptr = lms_w_forward;
- w_ptr = lms_w;
- x_ptr = lms_in->x_ptr;
- error = lms_in->error;
- }
- for(i=0; i<FIR_order; i++)
- {
- yy+=x_ptr[i]*w_ptr[i];
- lms_out->y =yy;
- }
- temp = b*(lms_in->d - lms_out->y);
- for(i=0; i<FIR_order; i++)
- {
- w_forward_ptr[i] = w_ptr[i] +temp*x_ptr[i];//*f1;//0.00000005*lms_out->error*x_ptr[i];
- }
- Temp_w_ptr = w_forward_ptr; //新旧滤波系数矢量指针交换
- w_forward_ptr = w_ptr;
- w_ptr = Temp_w_ptr;
- }
希望对这方面比较了解的人能给小弟一些指点!谢谢了!困扰了我好久的问题了。。。