硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3335|回复: 5
收起左侧

[有问必答] 使用SPI遇到的问题

[复制链接]

20

主题

56

回帖

116

积分

初级会员

积分
116
发表于 2017-7-20 18:57:58 | 显示全部楼层 |阅读模式
今天使用SPI接口调试TLC5618,上午按设想配置了SPI但调试没有成功,由于是首次使用STM32的SPI,TLC5618也是首次,不知器件是否焊接正常,下午先改用GPIO模拟SPI成功了。又将程序改为STM32硬件的SPI,发现两个问题有些奇怪。
先上TLC5618的资料
微信截图_20170720182911.jpg

这是TLC5618的通信时序图
微信截图_20170720182939.jpg

这是TLC5618的指令格式
问题1:
根据时序图,可选择SCK静态是为低,在脉冲的第二个沿进行数据捕捉,代码如下

SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;//16位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//时钟悬空低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//第二个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//内部NSS信号由SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//预分频值为2
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7;//用于CRC值计算的多项式
SPI_Init(SPI2,&SPI_InitStructure);//初始化配置
SPI_Cmd(SPI2,ENABLE);//使能或者失能SPI外设
GPIO_ResetBits(GPIOA, GPIO_Pin_12);//清除指定的数据端口位,CS=0;
SPI_I2S_SendData(SPI2,0x00A5);//通过外设SPI/I2S发送一个数据
while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET);//检查指定的SPI/I2S标志位设置与否
GPIO_SetBits(GPIOA, GPIO_Pin_12);//设置指定的数据端口位,CS=1
说明:GPIO等配置已设置正确,PA12为控制TLC5618的CS片选,使用SPI2发送数据,结果不成功。
将SPI2的配置改为

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;//16位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//时钟悬空高
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//第一个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//内部NSS信号由SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//预分频值为2
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7;//用于CRC值计算的多项式
SPI_Init(SPI2,&SPI_InitStructure);//初始化配置

SPI_Cmd(SPI2,ENABLE);//使能或者失能SPI外设GPIO_ResetBits(GPIOA, GPIO_Pin_12);//清除指定的数据端口位,CS=0;
SPI_I2S_SendData(SPI2,0x00A5);//通过外设SPI/I2S发送一个数据while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET);//检查指定的SPI/I2S标志位设置与否
GPIO_SetBits(GPIOA, GPIO_Pin_12);//设置指定的数据端口位,CS=1
偶尔还是不行,后来又在代码中插入延时,后面的配置倒是成功了,但我觉得根据时序图这两种配置都应该可行的,但前一种就是不可以。

问题2:SPI_I2S_FLAG_RXNE标志的问题,在SPI_I2S_FLAG_RXNE有效后,直接CS=1,是无法控制TLC5618的,必须在测试SPI_I2S_FLAG_RXNE循环结束后,在假一段延时才不会出错
GPIO_ResetBits(GPIOA, GPIO_Pin_12);//清除指定的数据端口位,CS=0;
SPI_I2S_SendData(SPI2,0x00A5);//通过外设SPI/I2S发送一个数据
while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET);//检查指定的SPI/I2S标志位设置与否
for (a = 0; a < 5; a++);//插入延时
GPIO_SetBits(GPIOA, GPIO_Pin_12);//设置指定的数据端口位,CS=1
这样才成功了。
我的疑问是在GPIO模拟SPI时CS=1是不需要延时的,而while (SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET);之后不进行延时就不行,难道是SPI_I2S_FLAG_RXNE标示到来时,SPI的传输还未结束?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107031
QQ
发表于 2017-7-21 01:51:59 | 显示全部楼层
有示波器或者逻辑分析仪不,有的话,抓一下这几个引脚的波形,这样就很容易找问题了。
另外把这四个完整的语句都写上,试试看:
===================
     /* 等待发送缓冲区空 */
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

    /* 发送一个字节 */
    SPI_I2S_SendData(SPI1, _ucByte);

    /* 等待数据接收完毕 */
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

    /* 读取接收到的数据 */
    SPI_I2S_ReceiveData(SPI1);
回复

使用道具 举报

20

主题

56

回帖

116

积分

初级会员

积分
116
 楼主| 发表于 2017-7-21 18:42:01 | 显示全部楼层
基本找到原因,第一个问题采用时钟空闲高电平下降沿(第一沿)采样是没问题的,采用时钟空闲低电平下降沿(第二沿)采样则正确率50%。第二个问题,用检测BSY标志比较方便,无需加延时,但手册不推荐用BSY在所有情况做标志,使用RXNE标志必须在使用前读一次DR寄存器先清除上一次的RXNE状态,昨天就是因为前一次的状态信号未被清除,造成检测失误。因此,可检测的标志方法可为:
1  检测BSY
while (SPI2->SR & SPI_SR_BSY);
2 检测RXNE
uint16_t temp;
  temp = SPI2->DR;
  while (!(SPI2->SR & SPI_SR_RXNE));
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107031
QQ
发表于 2017-7-21 18:57:53 | 显示全部楼层

回 bucker 的帖子

bucker:基本找到原因,第一个问题采用时钟空闲高电平下降沿(第一沿)采样是没问题的,采用时钟空闲低电平下降沿(第二沿)采样则正确率50%。第二个问题,用检测BSY标志比较方便,无需加延时,但手册不推荐用BSY在所有情况做标志,使用RXNE标志必须在使用前读一次DR寄存器先清除上一次的R .. (2017-07-21 18:42) 
对,就是我上面程序的这句话

/* 读取接收到的数据 */
SPI_I2S_ReceiveData(SPI1);

所以四个都写上,才靠谱。
回复

使用道具 举报

0

主题

10

回帖

0

积分

新手上路

积分
0
发表于 2017-10-13 16:48:44 | 显示全部楼层
谢谢您们的交流,学习了
回复

使用道具 举报

0

主题

1

回帖

0

积分

新手上路

积分
0
发表于 2017-10-26 17:57:40 | 显示全部楼层
学习了,谢谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-15 01:35 , Processed in 0.182069 second(s), 34 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表