打印
[STM32F1]

SPI/I2S调试经验总结

[复制链接]
884|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hehhehee|  楼主 | 2022-5-28 22:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、调试中首先检查SPI使能总线是否正确;
     检查时序(现有时钟,后片选拉低),接收时必须有发送才能有时钟
二、对照flash芯片手册查看SPI时序
三、检查状态位

使用特权

评论回复
沙发
hehhehee|  楼主 | 2022-5-28 22:56 | 只看该作者
1.查询 标志位:

         1)while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);//检查发送是否完成

         2)while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)==RESET);//检查接受标志位



SPI运行时有一定几率程序会卡死在检查接受标志位处RXNE,论坛上的解决方案是将检查接受标志位改为检查忙状态,即:

         while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_BSY)==SET);

此方案可行。

其根本原因是因为STM32F105的SPI增加了FIFO端口,使传输数据有了缓冲区。可以在SPI初始化是增加语句SPI_RxFIFOThresholdConfig(SPI1,SPI_RxFIFOThreshold_QF);,将应答数据位设置为8位。

使用特权

评论回复
板凳
hehhehee|  楼主 | 2022-5-28 22:57 | 只看该作者
有些库函数没有SPI_RxFIFOThresholdConfig函数,完整函数如下:

/**

* [url=home.php?mod=space&uid=247401]@brief[/url] Configures the FIFO reception threshold forthe selected SPI.

* @param SPIx: where x can be 1 or 2 to select the SPIperipheral.

* [url=home.php?mod=space&uid=536309]@NOTE[/url] SPI2 is not available for STM32F031 devices.

* @param SPI_RxFIFOThreshold: specifies the FIFOreception threshold.

* This parameter can be one of thefollowing values:

* [url=home.php?mod=space&uid=2817080]@ARG[/url] SPI_RxFIFOThreshold_HF: RXNEevent is generated if the FIFO

* levelis greater or equal to 1/2.

* @arg SPI_RxFIFOThreshold_QF: RXNEevent is generated if the FIFO

* levelis greater or equal to 1/4.

* @retval None

*/

voidSPI_RxFIFOThresholdConfig(SPI_TypeDef* SPIx, uint16_t SPI_RxFIFOThreshold)

{

/* Check the parameters */

assert_param(IS_SPI_ALL_PERIPH(SPIx));

assert_param(IS_SPI_RX_FIFO_THRESHOLD(SPI_RxFIFOThreshold));


/* Clear FRXTH bit */

SPIx->CR2 &=(uint16_t)~((uint16_t)SPI_CR2_FRXTH);


/* Set new FRXTH bit value*/

SPIx->CR2 |= SPI_RxFIFOThreshold;

}

使用特权

评论回复
地板
hehhehee|  楼主 | 2022-5-28 22:57 | 只看该作者
PS:如果RXNE仍然反复置位,可参考STM32F030与STM32F411的SPI调试经验–兼RXNE不能置位的原因一文关闭SPI寄存器的监控窗口或者修正硬件。

使用特权

评论回复
5
hehhehee|  楼主 | 2022-5-28 22:58 | 只看该作者
2. STM32105芯片的SPI允许的最大fsck为18MHz,设置分频系数时注意不要超过这个数。

使用特权

评论回复
6
hehhehee|  楼主 | 2022-5-28 22:59 | 只看该作者
3.I2S的输出频率

音频的采样频率可以是96kHz、48kHz、44.1kHz、32kHz、22.05kHz、16kHz、11.025kHz或者8kHz(或任何此范围内的数值)。

使用特权

评论回复
7
hehhehee|  楼主 | 2022-5-28 23:00 | 只看该作者
为了获得需要的频率,需按照以下公式设置线性分频器:

1)当需要生成主时钟时(寄存器SPI_I2SPR的MCKOE位为1):

①声道的帧长为16位,Fs = I2SxCLK/ [(16*2) * ((2*I2SDIV) + ODD)*8]

②声道的帧长为32位,Fs =I2SxCLK / [(32*2) * ((2*I2SDIV) + ODD)*4]

使用特权

评论回复
8
hehhehee|  楼主 | 2022-5-28 23:00 | 只看该作者
2)当关闭主时钟时(MCKOE位为0):

①声道的帧长为16位,Fs =I2SxCLK / [(16*2) * ((2*I2SDIV) + ODD)]

②声道的帧长为32位,Fs =I2SxCLK / [(32*2) * ((2*I2SDIV) + ODD)]

I2SDIV、ODD由寄存器SPI-I2SPR的第[7:0]位和第8位设置。

使用特权

评论回复
9
hehhehee|  楼主 | 2022-5-28 23:01 | 只看该作者
3.使用SPI,I2S传送数据时,注意时序,否则数据可能会变成一段一段的。

使用特权

评论回复
10
hehhehee|  楼主 | 2022-5-28 23:01 | 只看该作者
4.在调试过程中,更改数据(右移一位,相当于音量减半)再次播放则变成了杂音,其原因为原数据设置成了无符号数,实际上是有正负之分的,单纯的右移打乱了数据。

使用特权

评论回复
11
carpsnow| | 2022-5-29 11:20 | 只看该作者
i2s一直用不好

使用特权

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

本版积分规则

80

主题

945

帖子

0

粉丝