打印

SPI等待问题

[复制链接]
2614|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
aaa2742|  楼主 | 2010-10-22 08:59 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
static void WR_CMD (unsigned char cmd)  
{
  /* Wait for SPI1 Tx buffer empty */
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  //int i;
  //while(SPI1->SR & 0x0002 == 0);
  //for(i = 0;i<5;i++);
  /* Send SPI1 data */
  SPI_I2S_SendData(SPI1,cmd);
  /* Wait for SPI1 data reception */
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
  //while(SPI1->SR & 0x0001 == 0);
  //for(i = 0;i<5;i++);
  /* Read SPI1 received data */
  SPI_I2S_ReceiveData(SPI1);
}为什么不用库函数直接用寄存器等待就运行不了?
沙发
jgphu| | 2010-10-22 12:58 | 只看该作者
SPI等待就读BUSY位就好了啊。

使用特权

评论回复
板凳
jgphu| | 2010-10-22 12:58 | 只看该作者
SPI等待就读寄存器中的BUSY位就好了啊。

使用特权

评论回复
地板
aaa2742|  楼主 | 2010-10-22 14:03 | 只看该作者
为什么会这样:)

使用特权

评论回复
5
香水城| | 2010-10-22 14:05 | 只看该作者
什么现象?

使用特权

评论回复
6
aaa2742|  楼主 | 2010-10-25 13:21 | 只看该作者
调用系统的查询标志函数,在那等待运行结果就正确。但是直接操作寄存器查询运行就不正常?

使用特权

评论回复
7
jgphu| | 2010-10-25 18:09 | 只看该作者
既然你调用系统的查询标志函数是可行的,直接读寄存器就也是可行的,如果不可行,请贴出这个地方的程序。

使用特权

评论回复
8
aaa2742|  楼主 | 2010-10-26 08:53 | 只看该作者
就是一开始贴的地方,画横线的是库函数,方框是直接读寄存器,改为直接读寄存器运行结果不正确,读BUSY也不行。

spi.jpg (44.93 KB )

spi.jpg

使用特权

评论回复
9
jgphu| | 2010-10-26 09:49 | 只看该作者
看不懂你的程序。
帮你理清一下逻辑
1、while(BUSY == 0); //表示SPI总线空闲.
2、SPI_I2S_SendData(SPI,cmd);
3、while(TXE == 0);
4、SPI_I2S_ReceiveData(SPI1);
5、while(RXNE == 0);

想问一下你的SPI是和什么器件通信。

使用特权

评论回复
10
jgphu| | 2010-10-26 09:50 | 只看该作者
看不懂你的程序。
帮你理清一下逻辑
1、while(BUSY == 1); //表示SPI总线空闲.
2、SPI_I2S_SendData(SPI,cmd);
3、while(TXE == 0);
4、SPI_I2S_ReceiveData(SPI1);
5、while(RXNE == 0);

想问一下你的SPI是和什么器件通信。

使用特权

评论回复
11
aaa2742|  楼主 | 2010-10-26 11:46 | 只看该作者
和ADS7843

使用特权

评论回复
12
jgphu| | 2010-10-26 11:51 | 只看该作者
你和ADS7843这样通信肯定会出问题的。

1、while(BUSY == 1); //表示SPI总线空闲.
2、SPI_I2S_SendData(SPI,cmd);
3、while(BUSY == 1); //表示SPI总线空闲.
4、while(7843BUSY == 1); //等待7843的BUSY引脚。也可以去掉这步
5、SPI_I2S_SendData(SPI,0x00);
6、while(BUSY == 1); //表示SPI总线空闲.
7、SPI_I2S_ReceiveData(SPI1);
8、SPI_I2S_SendData(SPI,0x00);
9、while(BUSY == 1); //表示SPI总线空闲.
10、SPI_I2S_ReceiveData(SPI1);
这样才会正确接收坐标,压力等触摸屏信息

使用特权

评论回复
13
jgphu| | 2010-10-26 11:52 | 只看该作者
你要好好看看7843那个协议,用示波器测SPI,严格按照那个协议来写程序。

使用特权

评论回复
14
aaa2742|  楼主 | 2010-10-26 13:49 | 只看该作者
static void WR_CMD (unsigned char cmd)  
{
  /* Wait for SPI1 Tx buffer empty */
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  /* Send SPI1 data */
  SPI_I2S_SendData(SPI1,cmd);
  /* Wait for SPI1 data reception */
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
  /* Read SPI1 received data */
  SPI_I2S_ReceiveData(SPI1);
}
我这样写就可以的。
我说的判忙标志都是指的是stm32的。
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
这一句如果改为直接操作寄存器,还有下面的判忙改为直接读寄存器,那么运行结果就不对。
而直接用库函数就正确.
?????

使用特权

评论回复
15
jgphu| | 2010-10-26 14:04 | 只看该作者
你用库函数这样写能正常接收到触摸屏的坐标信息???

使用特权

评论回复
16
aaa2742|  楼主 | 2010-10-26 15:56 | 只看该作者
是的,直接用寄存器就不行了

使用特权

评论回复
17
香水城| | 2010-10-26 17:28 | 只看该作者
由于AHB与APB之间桥的延迟,还有CM3核心的流水线效应,设置寄存器到器件中真正做动作之间很可能会有延迟。估计这就是你看到的现象,库函数调用引入了等待延迟,导致结果正确,但直接寄存器操作没有等待延迟,导致结果错误。

所以可以尝试在等待循环之前和之后,增加一些小的延迟(最多4个CPU周期),这样应能解决问题。

使用特权

评论回复
18
aaa2742|  楼主 | 2010-10-27 08:39 | 只看该作者
17# 香水城
你说的这种解释我是理解的,我也考虑过延时的问题,所以在第一次贴图的时候,我在后面加了一个for,我想问一下是不是延时加的太短或者比你说的长点,也是不可以的。

使用特权

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

本版积分规则

27

主题

216

帖子

1

粉丝