GPIO口模拟SPI

对于如何操作GPIO来模拟SPI的过程是简单的,不赘述了。代码如下。

 void _spi_tx(int8u data_tx)

{
int8u i;


//发送一个数据
for(i=0;i<8;i++)
{
//改变数据位(准备数据发送)
if((data_tx<_spi_tx_pin_up();
else
_spi_tx_pin_down();

//下降沿(数据将被发送)
_spi_clk_pin_down();
//延时
//bsp_time_delay(6);
bsp_time_delay(8);
//bsp_time_delay(10);


//上升沿(数据将被接收)
_spi_clk_pin_up();
//延时
//bsp_time_delay(6);
bsp_time_delay(8);
//bsp_time_delay(10);
}


//时钟信号拉高
_spi_clk_pin_up();
//时钟引脚拉低
_spi_clk_pin_down();

}


int8u _spi_rx(int8u data_tx)
{
int8u i;
int8u data_rx=0;

//发送一个数据
for(i=0;i<8;i++)
{
//改变数据位(准备数据发送)
if((data_tx<_spi_tx_pin_up();
else
_spi_tx_pin_down();

//下降沿(数据将被发送)
_spi_clk_pin_down();
//延时
//bsp_time_delay(6);
bsp_time_delay(8);
//bsp_time_delay(10);
//上升沿(数据将被接收)
_spi_clk_pin_up();
//接收数据
data_rx|=((_spi_rx_pin_bit()&SPI_RX_BIT_MASK)>>4);
//最后一次操作不用移位了
if(i<7)
data_rx<<=1;
//延时
//bsp_time_delay(6);
bsp_time_delay(8);
//bsp_time_delay(10);
}


//时钟信号拉高
_spi_clk_pin_up();
//时钟引脚拉低
_spi_clk_pin_down();



return data_rx;

}


但是问题在于代码通信不稳定,在高强度的读写状态下,容易出错。

初次认定以为是以下问题:

GPIO模拟的CLK频率太高。

GPIO口的电压不够大,容易受到干扰。


通过尝试,发现CLK的频率降低后,反而更容易出错。提高GPIO口的电压也没用。

最后通过仔细阅读文档,查看时序图,发现TX PIN的引脚在空闲时为低电平。所以强制拉低了TX PIN引脚的电压(也可以直接把这个PIN配置为下拉)


这次修改出错率大大下降,但是还是会有。第六感告诉我,出错还可能与通信间CS片选空闲时间不够长有关(CS拉高的时间)。

所以增加了每次通信时,CS先保持高电平一段时间。修改后,出错消失。


测试用例如下:while中无任何延时,所以通信强度还是相当大的。

while(1)

{

read()

}


你可能感兴趣的:(ARM)