USB+I2S——V307 USBHS Audio转I2S方案验证
本文使用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