来源:https://www.cnblogs.com/wchmcu/p/17880995.html
本文使用V307的USBHS和I2S,实现USB转I2S输出。I2S做主机 UAC2.0 支持384K 2通道 32bit。 V30x时钟树分析 USBHS的时钟来源: 1.HSE->USBDIV->USBHSPLL
I2S的时钟可以有两种来源: 1.HSE->DIV2->PLL3->I2S 2.HSE->DIV2->PLL2->DIV1->PLL->AHB->APB1->I2S
I2S时钟分析 MCK一般用于触发DAC采样,有些DAC需要MCK。CK是I2S的串行时钟线,由主机提供。从输出看,有是否输出MCK的区别,当需要输出MCK时,MCKOE为1,所以CK需要4分频或8分频。CHLEN当16位时为0,其余为1。
以384K 2通道 32位,不输出MCK为例配置。 串行时钟CK=384K*2*32=24.576M 需要计算出HSE通过时钟树得到24.576M的CK和能用给USBHS做参考的值。每个PLL有输入输出的范围,计算中需要加限制条件,然后通过写代码穷举所有可能性,找到以下3种配置。 HSE | DIV2 | PLL2 | DIV1 | PLL | I2SDIV | 16M | 5 | 16 | 5 | 12 | 5 | 16M | 5 | 12 | 5 | 16 | 5 | 24M | 5 | 8 | 5 | 16 | 5 |
可以得到24.576M的CK并且能正常使用USBHS。系统主频为122.88M。 可以写代码让电脑算,也可以通过转化成分数的方式,计算,例如需要得到12.288M的CK,即1536/125=(8*16*12)/(5*5*5)。 USBHS的时钟配置,通过HSE分频,得到一个参考时钟,然后给USBHSPLL倍频到480M,例如24M的HSE通过3分频得到8M的时钟。16M的HSE需要将Div3改为Div2。 I2S使用DMA时的注意点:由于32bit需要用16bit传两次,I2S的DMA没有双缓冲。MCU的存储是小端在前,所以需要手动把数据16bit交换一下顺序。
其它:中断临界处理,当有变量在中断里和中断外处理时,且不是原子指令,比如与或操作、++--等(读-写-改)需要在操作这些变量前关闭中断,以保证不会被中断打断,在中断里修改了,但是退出中断后又被改回来,导致中断里的操作没有起作用。 参考代码:V307_AUDIO_I2S USB回传参考代码:https://www.wch.cn/bbs/thread-104415-1.html
|