您的位置 首页 5G

Cortex-M3 (NXP LPC1788)之IIS使用–UDA1380进行音频数据播映

LPC1788发送到I2S总线上的音频数据要通过音频解码芯片才能输出模拟音频信号。开发板上使用的是UDA1380,对它的寄存器的配置可以通…

LPC1788发送到I2S总线上的音频数据要经过音频解码芯片才干输出模仿音频信号。开发板上运用的是UDA1380,对它的寄存器的装备能够经过L3总线或许I2C总线进行,这儿运用I2C总线进行操控,关于I2C总线的操作能够参阅之前I2C的介绍。UDA1380的寄存器首要分红3类,系统操控、插值滤波(interpolation filter)、抽取滤波(decimator filter)。插值滤波和DAC转化有关,用于操控操控声响的输出参数。抽取滤波和ADC有关,用于操控对音频的采样。寄存器的地址和功用如图1所示。

图1:UDA1380寄存器地址和功用

依据图1的赤色符号中的内容,能够知道两个滤波器的正常运用需求一个128fs的clock,这个时钟能够经过SYSCLK引脚或许WSI的信号取得。在硬件连接上,经过将LPC1788的MCLK输出的时钟,连接到UDA1380的SYSCLK引脚。因而,咱们需求装备I2S的发送形式操控寄存器I2STXMODE,使能TX_REF在MCLK输出,使UDA1380内部发生一个滤波器需求的时钟。

程序中咱们经过I2S发送一段音频数据,该数据是我从WAV格局的文件中去掉WAV头格局后得到的一个纯音频数据数组。该WAV音频为16位双通道 采样频率为44.1KHZ。LPC1788将该数组发送到I2S总线,UDA1380读取该数据进行声响的输出。程序如下

  1. #include”i2c.h”
  2. #include”audio.h”
  3. #definerI2SDAO(*(volatileunsigned*)(0x400A8000))
  4. #definerI2STXFIFO(*(volatileunsigned*)(0x400A8008))
  5. #definerI2STXRATE(*(volatileunsigned*)(0x400A8020))
  6. #definerI2STXBITRATE(*(volatileunsigned*)(0x400A8028))
  7. #definerI2STXMODE(*(volatileunsigned*)(0x400A8030))
  8. #definerI2SDMA1(*(volatileunsigned*)(0x400A8014))
  9. #definerI2SDMA2(*(volatileunsigned*)(0x400A8018))
  10. #definerI2SSTATE(*(volatileunsigned*)(0x400A8010))
  11. #definerI2SIRQ(*(volatileunsigned*)(0x400A801C))
  12. #definerI2SDAI(*(volatileunsigned*)(0x400A8004))
  13. #definerI2SRXFIFO(*(volatileunsigned*)(0x400A800C))
  14. #definerI2SRXRATE(*(volatileunsigned*)(0x400A8024))
  15. #definerI2SRXBITRATE(*(volatileunsigned*)(0x400A802C))
  16. #definerI2SRXMODE(*(volatileunsigned*)(0x400A8034))
  17. #definerIOCON_P0_07(*(volatileunsigned*)(0x4002C01C))
  18. #definerIOCON_P0_08(*(volatileunsigned*)(0x4002C020))
  19. #definerIOCON_P0_09(*(volatileunsigned*)(0x4002C024))
  20. #definerIOCON_P1_16(*(volatileunsigned*)(0x4002C0C0))
  21. #defineUDA1380_ADDRESS0x1A
  22. voidUda1380_WriteData(unsignedcharreg,unsignedshortintdata)
  23. {
  24. unsignedcharconfig[3];
  25. config[0]=reg;
  26. config[1]=(data>>8)&0xFF;//MS
  27. config[2]=data&0xFF;//LS
  28. I2C0_MasterTransfer(UDA1380_ADDRESS,config,sizeof(config),0,0);
  29. I2C0_MasterTransfer(UDA1380_ADDRESS,config,1,&config[1],2);//校验写入的数据是否正确
  30. if((config[1]<<8|config[2])!=data)
  31. {
  32. while(1);//写入和读出的数据不一致
  33. }
  34. }
  35. voidUda1380_config()
  36. {
  37. I2C0_Init();
  38. Uda1380_WriteData(0x7F,0x0);//restoreL3-defaultvalues
  39. Uda1380_WriteData(0x01,0x0);//数据格局为规范的I2S格局
  40. Uda1380_WriteData(0x13,0x0);//装备音频的输出
  41. Uda1380_WriteData(0x14,0x0);
  42. Uda1380_WriteData(0x00,0x2|0x1<<8|0x1<<9);//使能DAC的时钟,挑选运用SYSCLK发生128fs的时钟
  43. Uda1380_WriteData(0x02,0x1<<15|0x1<<13|0x1<<10|0x1<<8);//使能DAC电源
  44. }
  45. intmain(void)
  46. {
  47. unsignedintcount=0,i;
  48. unsignedcharflag=1;
  49. rIOCON_P0_07=(rIOCON_P0_07&(~0x3))|0x1;//I2S_TX_SCK
  50. rIOCON_P0_08=(rIOCON_P0_08&(~0x3))|0x1;//I2S_TX_WS
  51. rIOCON_P0_09=(rIOCON_P0_09&(~0x3))|0x1;//I2S_TX_SDA
  52. rIOCON_P1_16=(rIOCON_P1_16&(~0x3))|0x2;//I2SMCLK
  53. rPCONP|=0x1<<27;
  54. rI2SDAO=(16-1)<<6|0x1<<4|0x1<<3|0x1;//16位,立体音,制止发送
  55. rI2STXMODE|=0x1<<3;//使能MCLK输出,使TX_REF输出到UDA1380的SYSCLK引脚
  56. rI2STXRATE=0x1<<8|0x1;//装备分数速率寄存器得到TX_REF=CCLK/(1/1)/2
  57. rI2STXBITRATE=CCLK/2/(44100*2*16)-1;//44.1KHZ采样16位
  58. for(i=0;i<0x1000000;i++);//延时等候UDA1380内部经过SYSCLK发生安稳的128fs供给插值滤波和抽取滤波运用
  59. Uda1380_config();
  60. rI2SDAO&=~(1<<4);
  61. rI2SDAO&=~(1<<3);
  62. rI2SDAO&=~(1<<15);//发动I2S数据传输
  63. while(flag)
  64. {
  65. if(((rI2SSTATE>>16)&0xFF)<=4)//假如发送FIFO中的数据小于或等于4个字
  66. {
  67. for(i=0;i<8-(((rI2SSTATE>>16)&0xFF));i++)//将FIFO填充到8个字
  68. {
  69. rI2STXFIFO=*(unsignedint*)(audio+count);//转化成int类型的指针,从指针指向的方位读取32位数据
  70. count+=4;//读取一个字,相当于读取char类型数组中的4个元素
  71. if(count>=sizeof(audio))//数组中的数据发送完
  72. {
  73. flag=0;
  74. break;
  75. }
  76. }
  77. }
  78. }
  79. rI2SDAO|=0x1<<3|0x1<<4;//中止I2S传输
  80. return0;
  81. }

下面临程序需求留意的做下阐明:

1,i2c.h中是上一篇介绍I2C总线中所用的函数,aduio.h中寄存的是音频数据的数组,const unsigned char audio[]={0,0,0,0,0,………………….

2,I2C总线每次发送的数据为1个字节,而UDA1380的寄存器为16为,因而咱们先发送高字节然后再发送低字节,详细的时序能够参阅UDA1380的数据手册。

3,程序中装备发送操控寄存器I2STXMODE使能了MCLK输出TX_REF的时钟到UDA1380的SYSCLK引脚,而UDA1380中装备成运用该时钟发生内部滤波器需求的128fs的时钟。在图1中标志中阐明run at ….因而在程序中装备UDA1380之前,运用了一个for延时,用于等候UDA1380内部发生安稳的128fs时钟。只要这样才干正确的装备0x10之后的滤波器相关寄存器。不然对0x10之后的滤波器相关寄存器操作会失利。这点没有验证,可是在debug调试的时分能够正常的有声响输出,可是下载到板子上运转,则没有作用。假如去掉for循环延时作用也不正常发音。假如不使能MCLK输出,则写0x13寄存器的值不会成功,读取该寄存器的值永远都是其默认值。因而估测和UDA1380的SYSCLK发生内部滤波器运用的128fs时钟有关。

参阅了linux内核晒干的uda1380的驱动,其间也提到了装备0x10今后的滤波器相关寄存器要分量条件

  1. 107/*theinterpolator&decimatorregsmustonlybewrittenwhenthe
  2. 108*codecDAIisactive.
  3. 109*/

谁有这方面的经历,期望多指导!

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/5g/265746.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部