STM32G031K LL库的使用 - SPI

说明:驱动基于STm32G031K6测试,其他型号需自行做改动。

SPI在开始配置的时候遇到些问题,这里也记录下,我这边用的是SPI2,其他SPI也可以参考

SPI2 初始化:

void STM32LLSpi2Init(void)
{
  LL_SPI_InitTypeDef SPI_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);            //使能外设时钟
  
  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);             //GPIO时钟使能
  /**SPI2 GPIO Configuration  
  PB6   ------> SPI2_MISO
  PB7   ------> SPI2_MOSI
  PB8   ------> SPI2_SCK 
  */
  GPIO_InitStruct.Pin = gpioSPI2_MISO_PIN;                       //MISOPin指定
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;                 //io模式配置为复用功能
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;               //设置为高速率
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;          //设置Pin为输出模式
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;                        //输入口设置不带上拉
  GPIO_InitStruct.Alternate = LL_GPIO_AF_4;                      //当前芯片PB6复用功能AF4为SPI2的MISO,其他芯片的配置参考相应的芯片手册
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = gpioSPI2_MOSI_PIN;                       //MOSIPin指定
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;                 //
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;               //
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;          //
  GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;                      //输出口配置为下拉
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;                      //io 功能选择
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = gpioSPI2_SCK_PIN;                        
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;                      //输出口配置为下拉
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;                      //io 功能选择
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* SPI2 interrupt Init */                                 //因为SPI需要进行不同设备数据读取,所以这里不使用中断模式会更方便
  //NVIC_SetPriority(SPI2_IRQn, 0);
  //NVIC_EnableIRQ(SPI2_IRQn);

  SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;    //spi功能选择全双工
  SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;                 //SPI主设备模式
  SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;         //数据宽度8位
  SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH;      //Clk空闲时状态为高 根据使用的从设备进行配置
  SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE;           //在第二次时钟跳变开始发送数据
  SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;                     //片选方式为软件设置
  SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;  //时钟波特率设置
  SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;               //字节传输方式,从高位开始
  SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;//不开启crc校验
  SPI_InitStruct.CRCPoly = 7;                                //CRC多项式
  LL_SPI_Init(SPI2, &SPI_InitStruct);

  LL_SPI_SetStandard(SPI2, LL_SPI_PROTOCOL_MOTOROLA);        //使用的SPI协议,可选MT和TI的
  LL_SPI_EnableNSSPulseMgt(SPI2);                            //仅做主设备时可用
    /* Configure the SPI2 FIFO Threshold */
  LL_SPI_SetRxFIFOThreshold(SPI2, LL_SPI_RX_FIFO_TH_QUARTER);//设置RX非空事件产生的FIFO阈值,根据通信时最小数据的大小设置,我这边最小为8位,所以设置为四分之一
	
  LL_SPI_Enable(SPI2);                                        //最后不要忘记使能SPI2,也可以在其他初始化完了之后的地方使能,为了防止忘记,这里先使能了

}

我个人在配置的时候,就是因为GPIO_InitStruct.Alternate 都设置的默认的AF0,导致一直通信不成功,曾一度怀疑是硬件问题。这里也提醒大家一下。

SPI数据收发:

//通过SPI在从设备内读写一个字节的数据,SPI特性,在MOSI写数据的时候MISO会获得应答数据
uint8_t STM32LLSpi2WRByte(uint8_t byte)        //因为采用的非中断方式,所以数据直接获取
{
    uint8_t wait_cnt=0;
 	while(!LL_SPI_IsActiveFlag_TXE(SPI2))        //等待数据发送完成
	{
		if(wait_cnt++ >100)
			break;
	}
	LL_SPI_TransmitData8(SPI2, byte);            //发送8位数据
	wait_cnt = 0;
	while(!LL_SPI_IsActiveFlag_RXNE(SPI2))       //等待接收缓存非空
	{
		if(wait_cnt++ >100)
			break;
	}
	return LL_SPI_ReceiveData8(SPI2);            //返回SPI2接收到的数据
}

SPI的读写多个字节的操作,都可以通过循环调用读写一个字节的函数去实现,这里不做说明。

 

你可能感兴趣的:(STM32,LL库)