*学习路线指引*:
1.SPI通信介绍
2.软件模拟SPI
3.硬件模拟SPI
4.硬件资源使用DMA搬运数据,减轻CPU负担
一、我的学习认知程度--SPI通信介绍
通信方式:
交换字节。移位寄存器和数据寄存器紧密配合实现,高位先行。实现流程就是
时序:
CPOL和CPHA位配置交换数据的时机。常用模式0。
写操作波形:
开始+写指令+从机地址+写入数据+结束,由于是交换字节,所以此过程会得到从机的交换过来的无用数据。
读操作波形:
开始+指令+从机地址+数据+结束,由于是交换字节,所以此过程主机会发送一个无用字节去换取有用数据,为统一,可规定无用字节为0xFF,不是一定,看情况。
二、我的学习认知程度--软件模拟SPI
结合代码理解:
void MySPI_Start(void)
{
MySPI_W_SS(0);
}
void MySPI_Stop(void)
{
MySPI_W_SS(1);
}
uint8_t MySPI_SwapByte(uint8_t ByteSend)
{
uint8_t i, ByteReceive = 0x00;
for (i = 0; i < 8; i ++)
{
MySPI_W_MOSI(ByteSend & (0x80 >> i));
MySPI_W_SCK(1); //手动翻转电平实现写读
if (MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);}
MySPI_W_SCK(0);
}
return ByteReceive;
}
void W25Q64_ReadID(uint8_t *MID, uint16_t *DID)
{
MySPI_Start(); //开始
MySPI_SwapByte(W25Q64_JEDEC_ID); //写读ID指令,外设手册有说明
*MID = MySPI_SwapByte(W25Q64_DUMMY_BYTE); //交换数据
*DID = MySPI_SwapByte(W25Q64_DUMMY_BYTE); //交换数据
*DID <<= 8;
*DID |= MySPI_SwapByte(W25Q64_DUMMY_BYTE);
MySPI_Stop();
}
void W25Q64_WriteEnable(void)
{
MySPI_Start(); //开始
MySPI_SwapByte(W25Q64_WRITE_ENABLE); //写 写指令,即告诉外设我要写数据
MySPI_Stop(); //结束
}
三、我的学习认知程度--硬件模拟SPI
结合代码理解:
void MySPI_Start(void)
{
MySPI_W_SS(0);
}
void MySPI_Stop(void)
{
MySPI_W_SS(1);
}
uint8_t MySPI_SwapByte(uint8_t ByteSend)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET); //由软件的翻转电平变成硬件的等待标志位,等待TXE标志位置位,即发送寄存器为空
SPI_I2S_SendData(SPI1, ByteSend); //发送寄存器空后,发送数据到数据寄存器
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET); //接收寄存器为满,表示对方接收到我发送的数据,并交换回一个数据,我们变可以在这个时机去读取数据
return SPI_I2S_ReceiveData(SPI1);
}
void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count)
{
uint16_t i;
W25Q64_WriteEnable(); //交换写指令
MySPI_Start(); //开始
MySPI_SwapByte(W25Q64_PAGE_PROGRAM); //交换擦除指令
MySPI_SwapByte(Address >> 16); //写数据
MySPI_SwapByte(Address >> 8);
MySPI_SwapByte(Address);
for (i = 0; i < Count; i ++)
{
MySPI_SwapByte(DataArray[i]);
}
MySPI_Stop();
W25Q64_WaitBusy(); //写忙指令,告诉从机我正在写入,还没写完,没空,你不要让别人读或写
}
四、我的学习认知程度--硬件资源使用DMA搬运数据,减轻CPU负担
实例分析:
单次模式DMA,写数据到存储器模块W25Q64,DMA搬运目标数据到数据寄存器。
五.总结
最后,总结一下:
1.时序很重要。
2.SPI是指令加交换字节方式通信的,具体就是,给从机发送指令,这些指令都是外设规定好的,我们要查看它们的手册才知道具体指令是干嘛的,比读指令,就是先发一个读指令给从机,从机就知道了,主机是要进行读操作,当然,这些都是通过交换字节实现的,有可能一方的字节数据为无用数据。
3.软件要注意SCL的高低电平时机进行交换字节,而硬件则是看标志位,两者实质一样,只是方式不一样而已。
4.软件只有高低电平时机标志,硬件则是有寄存器标志位。