1.说在前面:最近尝试操作VS1053音频模块 使用的数据传输方法使用SPI协议,打算学一下SPI的配置方式
2.SPI
2-1:SPI(Secial Periperal interface),作为四线的通信接口,有着MISO MOSI SCLK和CS
MISO:主进从出
MOSI:主出从进
SCLK: 时间信号
CS:片选信号
2-2:CPHA和CPOL
CPHA为时钟相位,可以配置为1/0,控制数据的采样方式,设置为0的时候,控制在时钟周期的第一个跳变沿进行数据采集,设置为1的时候在第二个跳变沿进行采集
CPOL为时钟极性,可以配置为1/0,控制空闲状态的时钟极性,设置为0的时候空闲状态为低电平,设置为1空闲状态为高电平
时序图:
3.配置思路
3-1:设置SPI1的时钟和复用引脚时钟(spi_clock APB2ENR的12位)
在设置设置PA5 6 7(SCK MISO MOSI)为复用模式
3-2:设置工作模式(说实话 库函数设置采用结构体方式看起来很清晰,寄存器直接对SPI->CR1进行设置)
设置主/从机模式 数据的位数和时间记性和相位以及SPI时钟的时钟频率
oid SPI1_Init(void)
{
RCC->APB2ENR|=1<<2; //PORTA时钟使能
RCC->APB2ENR|=1<<12; //SPI1时钟使能
//这里只针对SPI口初始化
GPIOA->CRL&=0X000FFFFF;
GPIOA->CRL|=0XBBB00000;//PA5.6.7复用
GPIOA->ODR|=0X7<<5; //PA5.6.7上拉
SPI1->CR1|=0<<10;//全双工模式
SPI1->CR1|=1<<9; //软件nss管理
SPI1->CR1|=1<<8;
SPI1->CR1|=1<<2; //SPI主机
SPI1->CR1|=0<<11;//8bit数据格式
SPI1->CR1|=1<<1; //空闲模式下SCK为1 CPOL=1 空闲信号下的时钟极性
SPI1->CR1|=1<<0; //数据采样从第二个时间边沿开始,CPHA=1 时间相位(数据在第几个边沿(第几个周期结束的地方)被锁存)
SPI1->CR1|=7<<3; //Fsck=Fcpu/256
SPI1->CR1|=0<<7; //MSBfirst
SPI1->CR1|=1<<6; //SPI设备使能
SPI1_ReadWriteByte(0xff);//启动传输(主要作用:维持MOSI为高)
}
3-3:SPI的速度设置以及使能(对SPI->CR1配置)
使能位:SPI1->CR1|=1<<6;
//SPI1 速度设置函数
//SpeedSet:0~7
//SPI速度=fAPB2/2^(SpeedSet+1)
//APB2时钟一般为72Mhz
void SPI1_SetSpeed(u8 SpeedSet)
{
SpeedSet&=0X07; //限制范围
SPI1->CR1&=0XFFC7;
SPI1->CR1|=SpeedSet<<3; //设置SPI1速度
SPI1->CR1|=1<<6; //SPI设备使能
}
3-4:发送数据配置(检查发送区的数据是否进行发送(发送区是否为空)SPI1->SR的最低位是否为0)
u8 SPI1_ReadWriteByte(u8 TxData)
{
u16 retry=0;
while((SPI1->SR&1<<1)==0)//等待发送区空
{
retry++;
if(retry>0XFFFE)return 0;
}
SPI1->DR=TxData; //发送一个byte
retry=0;
while((SPI1->SR&1<<0)==0) //等待接收完一个byte
{
retry++;
if(retry>0XFFFE)return 0;
}
return SPI1->DR; //返回收到的数据
}
3-5:spi的作用范围为EEPROM FLASH RTC AD等 是一种高速全双工,同步的通信总线