1.说在前面:最近尝试操做VS1053音频模块 使用的数据传输方法使用SPI协议,打算学一下SPI的配置方式函数
2.SPIcode
2-1:SPI(Secial Periperal interface),做为四线的通讯接口,有着MISO MOSI SCLK和CSblog
MISO:主进从出接口
MOSI:主出从进ip
SCLK: 时间信号ci
CS:片选信号同步
2-2:CPHA和CPOLit
CPHA为时钟相位,能够配置为1/0,控制数据的采样方式,设置为0的时候,控制在时钟周期的第一个跳变沿进行数据采集,设置为1的时候在第二个跳变沿进行采集class
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等 是一种高速全双工,同步的通讯总线