其实各种协议是很重要的,这篇文章就当做我对spi协议的一个整理吧。
前几天在网上看到一段关于oled的程序
不过那段程序是用的io口模拟spi来控制oled模块的
我在想stm32本身就有spi为何要用io口来模拟spi协议呢
所以就想自己试着写一写。
首先第一部分是关于stm32的spi引脚:
http://www.eeworld.com.cn/mcu/2015/0615/article_20333.html
SPI1->CS ------ PA4
SPI1->MISO ------ PA6
SPI2->CS ------ PB12
SPI2->CLK ------ PB13
SPI2->MISO ------ PB14
SPI2->MOSI ------ PB15
SPI3->CS ------ PA15
SPI3->CLK ------ PB3
SPI3->MISO ------ PB4
SPI3->MOSI ------ PB5
对于SPI ,需要打开相关RCC时钟
主模式下
CLK 配置成复用推挽输出
MOSI 配置成复用推挽输出
MISO 配置成富哦那个或带上拉输入
CS若采用硬件则配置成推挽输出,若采用软件模式,则采用普通IO推挽输出即可。
引脚配置好了,我们下面进行spi模式的配置。下面的图片仅供参考,具体问题还需具体分析。spi的极性和相位为4中,我们还需要根据实际情况去查看。
配置好了之后,我们就开始写应用了,也就是收发函数,收发函数把数据通过配置好的底层发出去。
对于应用函数,我们应该设置好形参,形参主要是用来保存协议来往的数据的。
这个协议的收发函数有两种(因为这个协议是双工的):读写分开的函数,读写一起的。
读写分开的函数:
void SPI_Ecah_Buffer_Send(u8* pBuffer, u16 NumByteToRead) //发送
{
for(int i = 0; i < NumByteToRead; i++)
{
SPI_Conmunication_SendByte(*pBuffer);
pBuffer++;
}
}
void SPI_Buffer_Receive(u8* pBuffer, u16 NumByteToRead) //接收
{
while (NumByteToRead--)
{
*pBuffer = SPI_Conmunication_SendByte (Dummy_Byte);
pBuffer++;
}
}
void SPI_Ecah_Buffer_Send(u8* str , u8* pBuffer, u16 NumByteToRead)
{
for(int i = 0; i < NumByteToRead; i++)
{
*str = SPI_Conmunication_SendByte(*pBuffer);
pBuffer++;
str++;
}
}