打印
[DSP]

28335的AIC23B左右通道的问题。。。

[复制链接]
1271|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
buda|  楼主 | 2019-9-4 17:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ic, AI, ui, se, IO
如题,我现在在利用28335开发板来设计一个音频信号处理系统。我仿照《Interfacing the TMS320F2833x the AIC23B Stereo Audio Codec》的例子程序,通过DMA左右声道的方法来读取两路输入的音频信号,即将ping_buffer和pong_buffer的前半部分存储进数组作为接入左声道的输入,后半部分存进一个数组作为接入右声道的输入,然后再进行算法的计算,然后输出一个音频信号。目前主要碰到的问题就是,输出的信号可以听到期望的音频部分,但是总会掺杂着一个嘟嘟嘟的噪声。尝试过修改各个寄存器的设置,发现这个噪声的频率随着语音芯片采样率的变化而改变,改变数据接口McBSPa相关设置对于噪声也有一定的影响,但是始终没办法达到实现消除噪声的目的。
以下是部分代码:
#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;

}

希望对这方面比较了解的人能给小弟一些指点!谢谢了!困扰了我好久的问题了。。。

使用特权

评论回复
评论
2858874703 2019-9-17 15:43 回复TA
@buda :能加个好友吗?这程序工程能发过来看看吗? 
buda 2019-9-12 16:54 回复TA
@2858874703 :你能帮我解决我现在这个问题吗? 
2858874703 2019-9-10 13:40 回复TA
方便 的话能交流一下吗 

相关帖子

沙发
zhangmangui| | 2019-9-4 23:15 | 只看该作者
不加信号处理的话   直接进行采集后送出  正常吗

使用特权

评论回复
板凳
buda|  楼主 | 2019-9-5 10:29 | 只看该作者
zhangmangui 发表于 2019-9-4 23:15
不加信号处理的话   直接进行采集后送出  正常吗

如果不加信号处理,输出是正常的

使用特权

评论回复
地板
zhangmangui| | 2019-10-6 09:27 | 只看该作者
问题解决了 麻烦分享一下  谢谢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

13

帖子

1

粉丝