拿到一个SPI芯片的时序图:
能够知道这个过程需要24位,因此SPI的的帧长度设置为8位,然后读写3次。
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
如果帧长度设置为16位,读写两次就有32位了。
当然也可以设置帧长度为12位,读写两次,但是这样读回来的数据就需要移位处理。
因此就可以编写下面的程序:
GD_SPI_CS_LOW();
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {} //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x05<<4);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {} //等待接收buf有数据
spi_i2s_data_receive(SPI0);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {} //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x00);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {} //等待接收buf有数据
spi_i2s_data_receive(SPI0);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {} //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x00);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {} //等待接收buf有数据
buf=spi_i2s_data_receive(SPI0);
GD_SPI_CS_HIGH();
上板后波形如下:
需要注意的是,读取一个字节下面的4条语句是必须的:
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {} //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x00);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {} //等待接收buf有数据
buf=spi_i2s_data_receive(SPI0);
先等待发送buf变空,然后再把要发送的数据装入发送buf。接着等待接收buf有数据,然后把接收buf中的数据读出来。
spi_i2s_data_transmit 控制当前字节MOSI引脚波形
spi_i2s_data_receive 读取当前字节MISO引脚的波形
不能因为前面两个字节只发送数据,不需要接收数据,就把后面两行删掉!!
经过测试,不去读取数据,接收buf的数据就不会更新。
如果遇到只需要发送数据,不需要接收数据的,就可以:
GD_SPI_CS_LOW();
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {} //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x05<<4);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {} //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x00);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {} //等待发送buf变空
spi_i2s_data_transmit(SPI0, 0x00);
//while(SET == spi_i2s_flag_get(SPI0, SPI_FLAG_TRANS)); //等待SPI传输完成,变成空闲
GD_SPI_CS_HIGH();
看到波形,最后一个字节还没有发送完,CS就拉高了
因此通过 spi_i2s_data_transmit(SPI0, 0x00); 把数据装入发送buf,程序就继续往下执行了,不管SPI发送完没有,因此要加上一句:
while(SET == spi_i2s_flag_get(SPI0, SPI_FLAG_TRANS)); //等待SPI传输完成,变成空闲
用库函数太慢了,可以换成寄存器:
GD_SPI_CS_LOW();
while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_TBE)); //等待发送buf变空
SPI_DATA(SPI0) = 0x05<<4;
while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_RBNE)); //等待接收buf有数据
SPI_DATA(SPI0);
while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_TBE)); //等待发送buf变空
SPI_DATA(SPI0) = 0x00;
while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_RBNE)); //等待接收buf有数据
SPI_DATA(SPI0);
while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_TBE)); //等待发送buf变空
SPI_DATA(SPI0) = 0x00;
while(RESET == (SPI_STAT(SPI0) & SPI_FLAG_RBNE)); //等待接收buf有数据
buf=SPI_DATA(SPI0);
GD_SPI_CS_HIGH();