这篇,我们讲述SPI接口通信实现既发送数据又接收数据的典型案例——SPI接口驱动SD卡。并在此基础上,创建一个FAT32文件系统,使数据文件存储读写更简便。
SPI接口读写SD卡最关键的地方就是SPI对SD卡的驱动函数。在读写SD卡的时候,主机SPI需要读取SD卡回响的时候,需要打开SPI的片选信号CS,如果主机SPI不需要读取SD卡回响的时候,那么不能打开SPI的片选信号CS,这点非常重要。下面,我贴上这2个驱动函数:
uint8 DrvSPI_SendOneByte_ActiveCS(SPI_MemMapPtr spi, uint8 buffer)
{
uint8 RX_Data;
SPI_SR_REG(spi) = (SPI_SR_EOQF_MASK //在发送数据之前先清除接收最后一帧标志位
| SPI_SR_TFUF_MASK //在发送数据之前先清除TX FIFO下溢标志
| SPI_SR_TFFF_MASK //在发送数据之前先清除TX FIFO充满标志
| SPI_SR_RFOF_MASK //在发送数据之前先清除RX FIFO溢出标志
| SPI_SR_RFDF_MASK); //在发送数据之前先清除RX FIFO不空标志
SPI_MCR_REG(spi) |= (SPI_MCR_CLR_TXF_MASK
| SPI_MCR_CLR_RXF_MASK); //在发送数据之前先清除TX FIFO和RX FIFO
SPI_SR_REG(spi) |= SPI_SR_TCF_MASK; //清除发送完成标志
SPI_PUSHR_REG(spi) = (SPI_PUSHR_CTAS(0) //选择CTAR0寄存器定义传输特性
| SPI_PUSHR_EOQ_MASK //该帧SPI数据是最后一帧数据
| SPI_PUSHR_PCS(1) //片选信号PCS0
| SPI_PUSHR_TXDATA(buffer)); //写入数据
SPI_MCR_REG(spi) &= ~SPI_MCR_HALT_MASK; //启动SPI数据传输
while((SPI_SR_REG(spi) & SPI_SR_TCF_MASK) == 0); //等待发送完成
SPI_SR_REG(spi) |= SPI_SR_TCF_MASK; //清除传送完成标志
while((SPI_SR_REG(spi) & SPI_SR_RFDF_MASK) == 0); //等待接收缓冲区有有效数据,即等待RX FIFO不为空为止
RX_Data = (uint8)SPI_POPR_REG(spi); //读取RX FIFO内部数据
SPI_SR_REG(spi) |= SPI_SR_RFDF_MASK; //清除RX FIFO不为空标志
SPI_MCR_REG(spi) |= SPI_MCR_HALT_MASK; //停止SPI数据传输
return (RX_Data);
}
void DrvSPI_SendOneByte_InactiveCS(SPI_MemMapPtr spi, uint8 buffer)
{
SPI_SR_REG(spi) = (SPI_SR_EOQF_MASK //在发送数据之前先清除接收最后一帧标志位
| SPI_SR_TFUF_MASK //在发送数据之前先清除TX FIFO下溢标志
| SPI_SR_TFFF_MASK //在发送数据之前先清除TX FIFO充满标志
| SPI_SR_RFOF_MASK //在发送数据之前先清除RX FIFO溢出标志
| SPI_SR_RFDF_MASK); //在发送数据之前先清除RX FIFO不空标志
SPI_MCR_REG(spi) |= (SPI_MCR_CLR_TXF_MASK
| SPI_MCR_CLR_RXF_MASK); //在发送数据之前先清除TX FIFO和RX FIFO
SPI_SR_REG(spi) |= SPI_SR_TCF_MASK; //清除发送完成标志
SPI_PUSHR_REG(spi) = (SPI_PUSHR_CTAS(0) //选择CTAR0寄存器定义传输特性
| SPI_PUSHR_EOQ_MASK //该帧SPI数据是最后一帧数据
| SPI_PUSHR_PCS(0) //片选信号PCS0关闭
| SPI_PUSHR_TXDATA(buffer)); //写入数据
SPI_MCR_REG(spi) &= ~SPI_MCR_HALT_MASK; //启动SPI数据传输
while((SPI_SR_REG(spi) & SPI_SR_TCF_MASK) == 0); //等待发送完成
SPI_SR_REG(spi) |= SPI_SR_TCF_MASK; //清除传送完成标志
SPI_MCR_REG(spi) |= SPI_MCR_HALT_MASK; //停止SPI数据传输
|