专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

UDA1341TS驱动程序

作者:佚名   来源:本站原创   点击数:  更新时间:2014年04月21日   【字体:
虽然滤波器的设置上还不是那么完美,但应该也算是于征服了UDA1341TS。这个驱动做了很久一直在用串口监测录音数据,但由于噪声的影响, 一直不知怎么回事,今天算是大功告成了,甚是开心,决定把代码贴出来做个庆祝,同时希望后学者能用得上。直管coppy不会介意的。注解:端口初始化函数 (uda_io_init())L3操作函数(WriteL3())录音函数(record())播放函数(playsound())。提示:时钟要知道 怎么设置(我使用MDK的启动代码设置了)对照S3C2440A 和UDA1341TS的datasheet来设置IIS和L3问题不大了,我这个驱动没有使用DMA,而是通过CPU来读写的,不用多说了,我想你懂的。

/*L3MODE:J7(GPB2);L3DATA:K3(GPB3);L3CLOCK:K4(GPB4)*/
#define L3MODE  (1<<2)    
#define L3DATA   (1<<3)    
#define L3CLOCK  (1<<4)
//**********uda1341ts端口初始化
void uda_io_init()
{
 /*IISLRCLK=GPE0,IISSCLK=GPE1,CDCLK=GPE2,IISSDI=GPE3,IISSDO=GP4*/
 GPECON|=(1<<1)|(1<<3)|(1<<5)|(1<<7)|(1<<9);
 GPEUP|=(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0);;
 
 GPBCON|=(1<<4)|(1<<6)|(1<<8);
 GPBUP|=(1<<4)|(1<<3)|(1<<2);
}   
//**********L3写
void WriteL3(unsigned char data, unsigned char mode)
{    
 
 //mode = 0,地址模式;mode = 1,数据传输模式     
 int i, k;
 uda_io_init();   
 if(mode == 0)  //地址模式时序
 {    
    GPBDAT = GPBDAT & ~(L3MODE|L3DATA|L3CLOCK )|L3CLOCK;    
 }    
 else     //数据模式时序
 {    
    GPBDAT = GPBDAT & ~(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE);       
 }
     
 for(k = 0; k < 5; k++);          //延时
    
 for(i = 0; i < 8; i++)
 {    
     if(data & 0x1)
  {    
         GPBDAT &= ~L3CLOCK;    
         GPBDAT |= L3DATA;          //发送高电平    
         for(k = 0; k < 5; k++);
          
         GPBDAT |= L3CLOCK;    
         GPBDAT |= L3DATA;    
         for(k = 0; k < 5; k++);    
     }    
     else
  {    
         GPBDAT &= ~L3CLOCK;    
         GPBDAT &= ~L3DATA;    //发送低电平  
         for(k = 0; k < 5; k++);
      
         GPBDAT |= L3CLOCK;    
         GPBDAT &= ~L3DATA;    
         for(k = 0; k < 5; k++);    
     }    
     data >>= 1;    
 }    
 GPBDAT = GPBDAT & ~(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE);    
}
//**********记录录音止
void record()

   unsigned short int temp;
   unsigned int i,stop=0,count=0;
        
    GPBDAT = GPBDAT & ~(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE);
    
    WriteL3(0x14+2,0);    
        
    WriteL3(0x60,1);   //复位  
        
    WriteL3(0x14+2,0);          
    WriteL3(0x10,1);     //00010000 系统时钟频率384fs
       
    WriteL3(0x14+2,0);         
    WriteL3(0xa2,1);    //10100010 输入增益6db,ADC开,DAC关  
           
    WriteL3(0x14+0,0);  
    WriteL3(0x0,1);          //音量衰减0db    
   WriteL3(0x14+0,0);  
    WriteL3(0x7b,1);         //01,1110,11 (BB 18dB~24dB) Treble 6dB
 
   WriteL3(0x14+0,0);  
    WriteL3(0x90,1);         //采样频率为44.1khz  
     
    WriteL3(0xc0,1); 
    WriteL3(0xe0,1);         //000,00000 MA 0dB  
      
    WriteL3(0xc4,1); 
    WriteL3(0xf0,1);         //100,1,00,00 AGC使能          
     
    WriteL3(0xc2,1); 
    WriteL3(0xf9,1);         //010,110,11 MIC 27dB input 1选择 通道2关闭
 
    WriteL3(0xc6,1); 
    WriteL3(0xe0,1);         //output lever -9db ATTACK TIME=11ms,DECAY TIME=100ms         
     
    /*IIS配置*/     
         
    IISCON = (0<<5)|(0<<4)|(1<<3)|(0<<2)|(1<<1);         //DMA禁止,在接受空闲状态,不产生IISLRCK信号,IIS预分频使能    
       
    IISMOD = (0<<9)|(0<<8)|(1<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0); //主设备时钟PCLK,主设备模式,接收模式,串行数据16位,主时钟是384fs,串行位时钟32fs     
           
    IISPSR = (2<<5)|2;            //预分频都是N=2    
         
    IISFCON = (0<<14)|(1<<12);       //发送FIFO正常,发送FIFO使能 
  
 IISCON|=(1<<0);      //iis开启   
      
   while(stop==0)
   {
      if((IISCON & (1<<6))==0)          //检查输入FIFO是否为满
      {    
         //FIFO中的数据为16位,深度为32
         //当输入FIFO为满时,一次性读取FIFO中的32个16位数据
         for(i=0;i<32;i++)
         {
            temp=IISFIFO;
   record_buffer[count+2*i]=temp;
            record_buffer[count+2*i+1]=(temp>>8);
         }
   //IISFIFO=0;
         count+=64;
         if(count>500000)
         stop=1;                    //当录制的数据超过数组长度时,退出         
  }
 }
 stop=0;
 IISCON = 0x0;               //关闭IIS
 GPBCON|=1;           //蜂鸣器输出
 GPBDAT|=1;       //蜂鸣器输出高点平
 delay_us(100);
 GPBDAT&=~(1<<0);     //蜂蜜输出低电平
}

void playsound(unsigned char *buffer, int length)
{
 int count,i;
 
 char flag; 

 GPBDAT = GPBDAT & ~(L3MODE|L3CLOCK|L3DATA) |(L3MODE|L3CLOCK); //L3开始传输:L3M=H, L3C=H
 
 
 
 //配置UDA1341
 
 WriteL3(0x14 + 2,0);            //状态模式(000101xx+10)
 
 WriteL3(0x60,1);          //0,1,10, 000,0 : 状态0,复位
 
 
 
 WriteL3(0x14 + 2,0);            //状态模式 (000101xx+10)
 
 WriteL3(0x10,1);          //0,0,01, 000,0 : 状态0, 384fs,IIS,no DC-filtering
 
 
 
 WriteL3(0x14 + 2,0);     //状态模式 (000101xx+10)
 
 WriteL3(0xc1,1);           //1,0,0,0, 0,0,01:状态1,
 
 //Gain of DAC 6 dB,Gain of ADC 0dB,ADC non-inverting,
 
 //DAC non-inverting,Single speed playback,ADC-Off DAC-On
 
 
 
 //配置s3c2440的IIS寄存器
 
 //预分频器为2,所以CDCLK=PCLK/(3+1)=16.928kHz
 
 IISPSR = 2<<5|2;
 
 //无效DMA,输入空闲,预分频器有效
 
 IISCON  = (0<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1);   
 
 //PCLK为时钟源,输出模式,IIS模式,每个声道16位,CODECLK=384fs,SCLK=32fs
 
 IISMOD  = (0<<9)|(0<<8)|(2<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0);     
 
 IISFCON = (0<<15)|(1<<13);           //输出FIFO正常模式,输出FIFO使能
 
 
 
 flag=1;
 
 count=0;
 
 //开启IIS
 
 IISCON |= 0x1;
 
 while(flag)
 
 {
 
  if((IISCON & (1<<7))==0)               //检查输出FIFO是否为空
  
  {    
   
   //FIFO中的数据为16位,深度为32
   
   //当输出FIFO为空时,一次性向FIFO写入32个16位数据
   
   for(i=0;i<32;i++)
   
   {
   
    IISFIFO=(buffer[2*i+count])+(buffer[2*i+1+count]<<8);
   
   }                  
   
   count+=64;
   
   if(count>length)
   
   flag=0;                  //音频数据传输完,则退出
  
  }
 
 }
 
 IISCON = 0x0;            //关闭IIS
}

关闭窗口

相关文章