//以下是 SPI 模块的初始化代码,配置成主机模式
//SPI 口初始化
//这里针是对 SPI1 的初始化
void SPI1_Init(void)
{
u16 tempreg=0;
RCC->AHB1ENR|=1<<0; //使能 PORTA 时钟
RCC->APB2ENR|=1<<12; //SPI1 时钟使能
GPIO_Set(GPIOB,7<<3,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,
GPIO_PUPD_PU); //PB3~5 复用功能输出
GPIO_AF_Set(GPIOB,3,5); //PB3,AF5
GPIO_AF_Set(GPIOB,4,5); //PB4,AF5
GPIO_AF_Set(GPIOB,5,5); //PB5,AF5
//这里只针对 SPI 口初始化
RCC->APB2RSTR|=1<<12; //复位 SPI1
RCC->APB2RSTR&=~(1<<12);//停止复位 SPI1
tempreg|=0<<10; //全双工模式
tempreg|=1<<9; //软件 nss 管理
tempreg|=1<<8;
tempreg|=1<<2; //SPI 主机
tempreg|=0<<11; //8 位数据格式
tempreg|=1<<1; //空闲模式下 SCK 为 1 CPOL=1
tempreg|=1<<0; //数据采样从第 2 个时间边沿开始,CPHA=1
//对 SPI1 属于 APB2 的外设.时钟频率最大为 84Mhz 频率.
tempreg|=7<<3; //Fsck=Fpclk1/256
tempreg|=0<<7; //MSB First
tempreg|=1<<6; //SPI 启动
SPI1->CR1=tempreg; //设置 CR1
SPI1->I2SCFGR&=~(1<<11);//选择 SPI 模式
SPI1_ReadWriteByte(0xff);//启动传输
}
//SPI1 速度设置函数
//SpeedSet:0~7
//SPI 速度=fAPB2/2^(SpeedSet+1)
//fAPB2 时钟一般为 84Mhz
void SPI1_SetSpeed(u8 SpeedSet)
{
SpeedSet&=0X07; //限制范围
SPI1->CR1&=0XFFC7;
SPI1->CR1|=SpeedSet<<3; //设置 SPI1 速度
SPI1->CR1|=1<<6; //SPI 设备使能
}
//SPI1 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{
while((SPI1->SR&1<<1)==0); //等待发送区空
SPI1->DR=TxData; //发送一个 byte
while((SPI1->SR&1<<0)==0); //等待接收完一个 byte
return SPI1->DR; //返回收到的数据
}
此部分代码主要初始化 SPI,这里我们选择的是 SPI1,所以在 SPI1_Init 函数里面,其相关
的操作都是针对 SPI1 的,其初始化步骤和我们上面介绍的一样。在初始化之后,我们就可以开
始使用 SPI1 了,这里特别注意,SPI 初始化函数的最后有一个启动传输,这句话最大的作用就
是维持 MOSI 为高电平,而且这句话也不是必须的,可以去掉。
在 SPI1_Init 函数里面,把 SPI1 的频率设置成了最低(84Mhz,256 分频)。在外部函数里
面,我们通过 SPI1_SetSpeed 来设置 SPI1 的速度,而我们的数据发送和接收则是通过
SPI1_ReadWriteByte 函数来实现的。
|