第一次写博客有点紧张哈哈哈 所以话不多说先上代码压压惊
//以下是SPI模块的初始化代码,配置成主机模式
//SPI口初始化
//这里针是对SPI2的初始化
void SPI2_Init(void)
{
u16 tempreg=0;
RCC->AHB1ENR|=1<<1; //使能PORTB时钟
RCC->APB1ENR|=1<<14; //SPI2时钟使能
GPIO_Set(GPIOB,7<<13,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //PB13~15复用功能输出
GPIO_AF_Set(GPIOB,13,5); //PB13,AF5
GPIO_AF_Set(GPIOB,14,5); //PB14,AF5
GPIO_AF_Set(GPIOB,15,5); //PB15,AF5
//这里只针对SPI口初始化
RCC->APB1RSTR|=1<<14; //复位SPI2
RCC->APB1RSTR&=~(1<<14);//停止复位SPI2
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
//对SPI2属于APB1的外设.时钟频率最大为168Mhz频率.
tempreg|=7<<3; //Fsck=Fpclk/256
tempreg|=0<<7; //MSB First
tempreg|=1<<6; //SPI启动
SPI2->CR1=tempreg; //设置CR1
SPI2->I2SCFGR&=~(1<<11);//选择SPI模式
SPI2_ReadWriteByte(0xff);//启动传输
}
//SPI1速度设置函数
//SpeedSet:0~7
//SPI速度=fAPB1/2^(SpeedSet+1)
//fAPB1时钟一般为168Mhz
void SPI2_SetSpeed(u8 SpeedSet)
{
SpeedSet&=0X07; //限制范围
SPI2->CR1&=0XFFC7;
SPI2->CR1|=SpeedSet<<3; //设置SPI1速度
SPI2->CR1|=1<<6; //SPI设备使能
}
//SPI1 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI2_ReadWriteByte(u8 TxData)
{
while((SPI2->SR&1<<1)==0); //等待发送区空
SPI2->DR=TxData; //发送一个byte
while((SPI2->SR&1<<0)==0); //等待接收完一个byte
return SPI2->DR; //返回收到的数据
}
程序配置IO口用了原子历程里面的GPIO_AF_Set();如果没有自行配置
下面是GPIO_AF_Set()函数
//GPIO复用设置
//GPIOx:GPIOA~GPIOI.
//BITx:0~15,代表IO引脚编号.
//AFx:0~15,代表AF0~AF15.
//AF0~15设置情况(这里仅是列出常用的,详细的请见407数据手册,56页Table 7):
//AF0:MCO/SWD/SWCLK/RTC AF1:TIM1/TIM2; AF2:TIM3~5; AF3:TIM8~11
//AF4:I2C1~I2C3; AF5:SPI1/SPI2; AF6:SPI3; AF7:USART1~3;
//AF8:USART4~6; AF9;CAN1/CAN2/TIM12~14 AF10:USB_OTG/USB_HS AF11:ETH
//AF12:FSMC/SDIO/OTG/HS AF13:DCIM AF14: AF15:EVENTOUT
void GPIO_AF_Set(GPIO_TypeDef* GPIOx,u8 BITx,u8 AFx)
{
GPIOx->AFR[BITx>>3]&=~(0X0F<<((BITx&0X07)*4));
GPIOx->AFR[BITx>>3]|=(u32)AFx<<((BITx&0X07)*4);
}
要注意SPI2用的fAPB1时钟 最大为168M
SPI1 用的FAPB2时钟 最大为84M
其次如果各位想要了解SPI寄存机每一位的功能可以看一下这篇文章