STM32 SPI接收数据问题

hnushixueqian 2011-02-15 03:45:56
STM32和ADS8328一块AD转换芯片进行通讯,使用SPI。问题是,接收数据时RXNE始终为reset状态,部分程序如下,望各位高人指点,急用,多谢
void ADS8328_SPI_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

/* Enable SPI1 clocks */
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 ,ENABLE);

/* Configure SPI1 pins: SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; //SCK MISO MOSI
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure PA4 as Output push-pull, used as select */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //片选
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure PA9 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //采样启动信号CONVEST
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure PA8 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //采样结束标志信号
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);


/* SPI1 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //全双工模式
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位数据
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //空闲状态为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //数据在第一个边沿采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS为软件控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; //波特率预分频为4
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);

/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE); //开启SPI设备
}



/*******************************************************************************
* Function Name :
* Description : Reads a byte from the SPI Flash.
* This function must be used only if the Start_Read_Sequence
* function has been previously called.
* Input : None
* Output : None
* Return : Byte Read from the SPI Flash.
*******************************************************************************/
u8 ADS8328_ReadByte()
{
ADS8328WriteHalfword(Dummy_Byte);
/* Loop while DR register in not emplty */
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //等待发送缓冲器为空
/* Send byte through the SPI1 peripheral */
SPI_I2S_SendData(SPI1, 0x00); //发送一个数据

// Wait to receive a byte
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); // 此处运行不下去了
SPI_I2S_ClearFlag(SPI1,SPI_I2S_FLAG_RXNE); //直接软件清除标志位。
return SPI_I2S_ReceiveData(SPI1);

//return ();
}
...全文
2675 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
hello.thanks 2012-02-26
  • 打赏
  • 举报
回复
我也正忙着这个,看了各位似乎有启示
hnushixueqian 2011-06-02
  • 打赏
  • 举报
回复
谢谢各位的回答,问题解决了,今天逛论坛才发现忘记结贴了,程序没问题,是调试的时候把断点设在了while循环那里,但是当运行到while的时候,状态已经改变了,所以就死在那里了
wxdhr 2011-05-25
  • 打赏
  • 举报
回复
请问最后是怎么解决的呢?
myhzcs 2011-05-09
  • 打赏
  • 举报
回复
大致看了一下,基本上没有问题,读写函数OK的,

这句没用“SPI_I2S_ClearFlag(SPI1,SPI_I2S_FLAG_RXNE); //直接软件清除标志位。”没开中断没影响

这里面有个最大的问题就是IO时钟没开?不知道你发现没有?少了一句RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);少了这句/* Configure SPI1 pins: SCK, MISO and MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; //SCK MISO MOSI
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

这段就白写了。
tangchangjun 2011-04-21
  • 打赏
  • 举报
回复
最后怎么解决的呢?
yuyishiwo 2011-03-27
  • 打赏
  • 举报
回复
时序貌似也有点问题
aleda303 2011-03-25
  • 打赏
  • 举报
回复
加上上拉电阻之后 就解决了, 我估计原因是 哪里配置的问题,期间SPI总线应该置位的时候 ,IO变成了三态的了
aleda303 2011-03-25
  • 打赏
  • 举报
回复
你在两个传输信号线上 分别加一个10K左右上拉电阻。

我也遇到这个问题。 我试过 调试程序,加延时等 都没用
elitebbs 2011-03-20
  • 打赏
  • 举报
回复
void SPI2_WRByte(INT8U* pWBuffer, INT16U wNumByte, INT8U* pRBuffer, INT16U rNumByte)
{
INT8U* writeBuffer = pWBuffer;
INT8U* readBuffer = pRBuffer;

if( g_spi2_device.state.init==FALSE || g_spi2_device.state.open==FALSE )
return;

//send datas to device
if( pWBuffer && wNumByte )
{
while(wNumByte)
{
/*!< Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

/*!< Send byte through the SPI1 peripheral */
SPI_I2S_SendData( SPI2, *(writeBuffer++) );

wNumByte--;
}
}
//read datas from device
if( pRBuffer && rNumByte )
{
while(rNumByte)
{
/*!< Loop while DR register in not emplty */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

/*!< Send byte through the SPI1 peripheral */
SPI_I2S_SendData( SPI2, 0 );

/*!< Wait to receive a byte */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);

/*!< Return the byte read from the SPI bus */
*(readBuffer++) = SPI_I2S_ReceiveData(SPI2);

rNumByte--;
}
}//
}
因为spi是全双工的,在主机发送数据的时候才会产生spi的时钟,所以接收数据时也要写空数据到spi总线上,才能产生读数据的时序。
ml_liumangtu 2011-02-26
  • 打赏
  • 举报
回复

STM32的 spi没问题,但它的IIC 设计有缺陷,你的程序是逻辑问题!
深呼吸 2011-02-24
  • 打赏
  • 举报
回复
这个代码逻辑有问题。SPI是同步传输方式,主机给从机提供时钟才能接受到数据,发送完数据就接受完了。所以当你发完数据后,用while在那里等待,就是个无限循环,因为从机没有时钟信号来传数据。
blueicewind 2011-02-16
  • 打赏
  • 举报
回复
测量spi的各个管脚,定位一下问题原因。
lbing7 2011-02-16
  • 打赏
  • 举报
回复
不知道是不是STM32的问题

在用它的IIC的时候也一得行

LZ,不行自己写一个模拟的吧。。。

27,382

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧