STM32
直播中

杨言

12年用户 555经验值
私信 关注
[问答]

如何对STM32的SPI1、SPI2以及SPI3进行初始化呢

如何对STM32的SPI1、SPI2以及SPI3进行初始化呢?

基于标准库与HAL库的RF1101有何应用?

回帖(1)

彭菲

2021-10-29 16:44:54
  STM32的SPI1、SPI2、SPI3初始化及RF1101的应用(标准库与HAL库)
  ——基于STM32F103RCT6
  ---- 标准库:
  说明:相关文件共有两个:bsp_spi_cc1101.h;bsp_spi_cc1101.c;以SPI2为例。
  1、“bsp_spi_cc1101.h”中的参数定义:
  #ifndef _BSP_SPI_1101_H_
  #define _BSP_SPI_1101_H_
  #include 《stdio.h》
  #include “stm32f10x.h”
  #include “misc.h”
  #include “os_cfg_app.h”
  #include “os.h”
  #include “core_cm3.h”
  #include “bsp.h”
  #include “stm32f10x_spi.h”
  #define CSN_CC1101_GPIO GPIOB
  #define CSN_CC1101_GPIO_PIN GPIO_Pin_12
  #define SPI_CC1101_GPIO GPIOB
  #define SCK_CC1101_GPIO_PIN GPIO_Pin_13
  #define MISO_CC1101_GPIO_PIN GPIO_Pin_14
  #define MOSI_CC1101_GPIO_PIN GPIO_Pin_15
  #define GDO0_CC1101_GPIO GPIOA
  #define GDO0_CC1101_GPIO_PIN GPIO_Pin_11
  #define SPI_GPIO_RCC_1 RCC_APB2Periph_GPIOB
  #define SPI_GPIO_RCC_2 RCC_APB2Periph_GPIOA
  #define CC1101_SPI SPI2
  #define CSN_SET GPIO_SetBits(GPIOB,GPIO_Pin_12)
  #define CSN_RESET GPIO_ResetBits(GPIOB,GPIO_Pin_12)
  void SPI_CC1101_Init(void);
  u8 SPI2_ReadWriteByte(u8 TxData);
  #endif
  2、“bsp_spi_cc1101.c”中的引脚及SPI功能初始化:
  #include “bsp_spi_cc1101.h”
  void SPI_CC1101_Init(void)
  {
  GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef SPI_InitStructure;
  RCC_APB2PeriphClockCmd(SPI_GPIO_RCC_1 | SPI_GPIO_RCC_2,ENABLE); //初始化GPIO时钟
  /*********SPI1初始化内容****
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE); //初始化SPI1时钟
  ******SPI1初始化内容******/
  /*********SPI2初始化内容************/
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE); //初始化SPI2时钟
  /********SPI3需要初始化的内容********
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE); //初始化SPI3时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //初始化复用IO时钟,重定向IO口
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //由于SPI3占用JTAG口,所以需要关闭JTAG
  ******SPI3需要初始化的内容*******/
  //片选设定成通用IO模式
  GPIO_InitStructure.GPIO_Pin=CSN_CC1101_GPIO_PIN;
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
  GPIO_Init(CSN_CC1101_GPIO,&GPIO_InitStructure);
  //SCK时钟IO初始化
  GPIO_InitStructure.GPIO_Pin=SCK_CC1101_GPIO_PIN;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
  GPIO_Init(SPI_CC1101_GPIO,&GPIO_InitStructure);
  //MISO的IO初始化
  GPIO_InitStructure.GPIO_Pin=MISO_CC1101_GPIO_PIN;
  GPIO_Init(SPI_CC1101_GPIO,&GPIO_InitStructure);
  //MOSI的IO初始化
  GPIO_InitStructure.GPIO_Pin=MOSI_CC1101_GPIO_PIN;
  GPIO_Init(SPI_CC1101_GPIO,&GPIO_InitStructure);
  //RF1101中用到的GDO0的IO初始化
  GPIO_InitStructure.GPIO_Pin=GDO0_CC1101_GPIO_PIN;
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
  GPIO_Init(GDO0_CC1101_GPIO,&GPIO_InitStructure);
  //SPI模式设置
  SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex; //全双工模式
  SPI_InitStructure.SPI_Mode=SPI_Mode_Master; //主设备模式
  SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b; //8字节数据通信
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟空闲时为低电平
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //时钟奇数边沿采样
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //软件控制NSS(CSN)位
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //通信速率设定,波特率预分频值
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB开始
  SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC计算多项式
  SPI_Init(CC1101_SPI, &SPI2_InitStructure); //初始化
  SPI_Cmd(CC1101_SPI, ENABLE); //使能
  SPI2_ReadWriteByte(0xFF); //RF1101启动传输
  }
  u8 SPI2_ReadWriteByte(u8 TxData)
  {
  u8 Rxdata;
  uint32_t SPITimeout =0x1000;
  while (SPI_I2S_GetFlagStatus(CC1101_SPI , SPI_I2S_FLAG_TXE) == RESET) //检测发送缓存区是否为空
  {
  if((SPITimeout--) == 0)
  return 0;
  }
  SPI_I2S_SendData(CC1101_SPI,TxData); //发送一个字节
  while (SPI_I2S_GetFlagStatus(CC1101_SPI , SPI_I2S_FLAG_RXNE) == RESET) //检测接收缓存区是否为空
  {
  if((SPITimeout--) == 0) return 0;
  }
  Rxdata = SPI_I2S_ReceiveData(CC1101_SPI); //存储一个字节
  return Rxdata;
  }
  }
  ---- HAL库:
  以SPI1为例:
  SPI_HandleTypeDef SPI1_Handler;
  void SPI1_Init(void)
  {
  GPIO_InitTypeDef GPIO_Initure;
  __HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
  __HAL_RCC_SPI1_CLK_ENABLE(); //使能SPI1时钟
  //NSS配置成通用IO口
  GPIO_Initure.Pin=GPIO_PIN_4;
  GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;
  GPIO_Initure.Pull=GPIO_PULLUP;
  GPIO_Initure.Speed=GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOA,&GPIO_Initure);
  //SPI引脚初始化
  GPIO_Initure.Pin=GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
  GPIO_Initure.Mode=GPIO_MODE_AF_PP;
  GPIO_Initure.Pull=GPIO_PULLUP;
  GPIO_Initure.Speed=GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOA,&GPIO_Initure);
  //SPI功能配置
  SPI1_Handler.Instance=SPI1; //SPI1
  SPI1_Handler.Init.Mode=SPI_MODE_MASTER; //主模式
  SPI1_Handler.Init.Direction=SPI_DIRECTION_2LINES; //双线模式
  SPI1_Handler.Init.DataSize=SPI_DATASIZE_8BIT; //发送接收8位帧结构
  SPI1_Handler.Init.CLKPolarity=SPI_POLARITY_LOW; //时钟的空闲状态为高电平
  SPI1_Handler.Init.CLKPhase=SPI_PHASE_1EDGE; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
  SPI1_Handler.Init.NSS=SPI_NSS_SOFT; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
  SPI1_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_256; //定义波特率预分频的值:波特率预分频值为256
  SPI1_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
  SPI1_Handler.Init.TIMode=SPI_TIMODE_DISABLE; //关闭TI模式
  SPI1_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE; //关闭硬件CRC校验
  SPI1_Handler.Init.CRCPolynomial=7; //CRC值计算的多项式
  HAL_SPI_Init(&SPI1_Handler); //初始化
  __HAL_SPI_ENABLE(&SPI1_Handler); //使能SPI1
  SPI1_ReadWriteByte(0xFF); //RF1101启动传输
  }
  //SPI底层驱动,时钟使能,引脚配置
  //此函数会被HAL_SPI_Init()调用
  //hspi:SPI句柄
  void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
  {
  GPIO_InitTypeDef GPIO_Initure;
  __HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
  __HAL_RCC_SPI1_CLK_ENABLE(); //使能SPI1时钟
  //PB13,14,15
  GPIO_Initure.Pin=GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
  GPIO_Initure.Mode=GPIO_MODE_AF_PP;
  GPIO_Initure.Pull=GPIO_PULLUP;
  GPIO_Initure.Speed=GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOA,&GPIO_Initure);
  }
  void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler)
  {
  assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler)); //判断有效性
  __HAL_SPI_DISABLE(&SPI1_Handler); //关闭SPI
  SPI1_Handler.Instance-》CR1&=0XFFC7; //位3~5清零,用来设置波特率
  SPI1_Handler.Instance-》CR1|=SPI_BaudRatePrescaler; //设置SPI速度
  __HAL_SPI_ENABLE(&SPI1_Handler); //使能SPI
  }
  u8 SPI1_ReadWriteByte(u8 TxData)
  {
  u8 Rxdata;
  HAL_SPI_TransmitReceive(&SPI1_Handler,&TxData,&Rxdata,1, 1000);
  return Rxdata;
  }
  注:与HAL库有一定的区别;重点注意SPI3与其他两个的区别;务必要检测缓存区是否为空。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分