任务需求:在一个CS周期内需要32个SPI 的sclk,但是根据spi的配置程序,最多实现16个SCLK。 请问如何实现在一个CS周期内产生32个sclk??? 程序代码: //SPI初始化 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly; //双线只接受 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式 SPI3->CR1|=1<<10; //只接受 SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; //设置SPI的数据大小 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(AD_SPI, &SPI_InitStructure); 主程序: while (1) { GPIO_ResetBits(AD_CS_GPIO_PORT,AD_CS_PIN); //CS=0 Delay(5); SPI_Cmd(AD_SPI, ENABLE); //SPI使能 data= SPIx_ReadWriteByte(); // 返回SPI_DR数据 SPI_Cmd(AD_SPI, DISABLE); //SPI失能 Delay(120); //增加延时 GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN); //CS=1 Delay(5); } 波形图: |
1个CS产çç16个å¨æçSCLK
具体要产生32个连续时钟,就是连续发4个字节。用软件查询,或用DMA方式。软件查询要查的状态多一点,DMA需要查询BSY就可以。
评分
查看全部评分
确实啊,根据自己的要求来使能时钟,很麻烦。请问下,
1. 您说的查询模式是什么啊?
2. 如何实现4个byte或者2个16bit的32时钟呢?
3. 我尝试过在一个CS周期内,两次使能和关闭SPI,实现32个周期(虽然能达到32个周期,但是SPI不能提高SPI的分频系数,故不能使用,代码如下:) while (1)
{
GPIO_ResetBits(AD_CS_GPIO_PORT,AD_CS_PIN); //CS=0
Delay(5); //
SPI_Cmd(AD_SPI, ENABLE); //SPI使能
data=SPIx_ReadWriteByte(); //写入数据
SPI_Cmd(AD_SPI, DISABLE); //SPI失能
SPI_Cmd(AD_SPI, ENABLE); //SPI使能
data=SPIx_ReadWriteByte(); //写入数据
SPI_Cmd(AD_SPI, DISABLE); //SPI失能
Delay(120); //增加延时
GPIO_SetBits(AD_CS_GPIO_PORT,AD_CS_PIN); //CS=1
Delay(5);
其中有个函数SPIx_ReadWriteByte():
u16 SPIx_ReadWriteByte(void)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(AD_SPI, SPI_I2S_FLAG_RXNE) == RESET) //长时间等待,影响了数据传输;若不加这一句则不能实现
{ //32个周期的sclk
retry++;
if(retry>200)
return 0;
}
return SPI_I2S_ReceiveData(AD_SPI);
}
请指教下不足或者其他的思路,谢谢你
您说的很对。在我对采样速度有要求的时候,用到SPIx_ReadWriteByte2 ();里面总有查询等待的过程。去掉等待速度能提高,但是又不能产生指定的波形(很矛盾)。
所以再尝试下,DMA 发送数据的方式,可以避免状态位的查询,同时用另一个DMA接收,希望能成功。谢谢您!!!
(这就是那个写和收的SPI数据传输的函数)
u16 SPIx_ReadWriteByte2 (u16 byte) //SPI双工,收发数据
{
SPITimeout = SPIT_FLAG_TIMEOUT;
/* 等待发送缓冲区为空,TXE事件 */
while (SPI_I2S_GetFlagStatus(AD_SPI, SPI_I2S_FLAG_TXE) == RESET)
{
if((SPITimeout--) == 0) return 0;
}
/*写入数据寄存器,把要写的数据写入发送缓冲区 */
SPI_I2S_SendData(AD_SPI, byte);
/* 等待接收缓冲区非空,RXNE事件*/
SPITimeout = SPIT_FLAG_TIMEOUT;
while (SPI_I2S_GetFlagStatus(AD_SPI, SPI_I2S_FLAG_RXNE) == RESET)
{
if((SPITimeout--) == 0) return 0; //等待超时
}
return SPI_I2S_ReceiveData(AD_SPI); //返回数据
}
评分
查看全部评分
评分
查看全部评分
但是,我配置的是双线只接收模式,那也可以使用发送空数据来满足吗?或者说满足成倍的时钟周期,则都是通过发送空数据来完成的吗,谢谢指教??
查询模式,就是手动查询状态标志物。。。然后连续发送4个byte数据。。。。
谢谢您的指点。意思就是:主要的思想就是需要发送4个字节的数据。
在我的硬件设计中,是主控通过SPI的方式只接收AD芯片的采样数据;故程序中配置SPI时,是配置为双线只接受模式(AD芯片只有三个接口:cs,sclk,DATA输出)。 故疑问是否在这种条件下能否实现向AD发送数据,然后产生32个周期呢?(我先尝试下其他的模式下,试试看否能行),谢谢啦
哦哦,懂了,懂您的意思了。谢谢啊。我先尝试下
对的对的,要遵循协议才行。谢谢提醒,
SPI的收发是同时的,发送的同时也在接收。
只是配置成只发送的话,接收数据线上的数据被忽略;要接收的话,也得发送个数,只是这个数并不关心罢了。
评分
查看全部评分