【STM32】BLDC驱动&控制开发笔记 | 07_SPI通信测试 - STM32F407用SPI配置DRV8323驱动芯片

这篇具有很好参考价值的文章主要介绍了【STM32】BLDC驱动&控制开发笔记 | 07_SPI通信测试 - STM32F407用SPI配置DRV8323驱动芯片。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

😶‍🌫️说在最前面 + 实现功能

最近在埋头搞STM32 + 无刷直流电机控制,想实现用自己的STM32F407VGT6芯片板子,外加一块驱动板(目前选用到TI的DRV8302或者DRV8323驱动芯片),搞定电机驱动,最后实现比较好的控制效果。如果不是同一块芯片的同学也不用急着走,大体上都是可借鉴哒~

本文主要实现使用SPI通信,通过STM32F407控制芯片来对DRV8323S驱动芯片进行配置,为使用DRV8323做好准备。

目标操作: 不启动电机,仅使能DRV8323S芯片。使用SPI朝DRV8323S芯片写几个地址的配置,然后再读取这几个位置的状态,检查是否通信正常。调试过程借助Keil的Debug功能中 watch变量的值,或使用UASRT串口通信打印出信息,来检查。

如果文章中有什么错误和待改进的地方,欢迎在评论区指出交流,共同学习和进步!✊
首先是一系列用CubeMX的配置操作。

👀 1 CubeMX - RCC & Clock Configuration时钟配置

🥽 1.1 【System Core】 – 【RCC】

HSE – Crystal/Ceramic Resonator
高速时钟源 – 外部晶振
spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件
会自动分配好管脚RCC_OSC_IN & RCC_OSC_OUT:
PH0 – RCC_OSC_IN
PH1 – RCC_OSC_OUT.

🥽 1.2 【Clock Configuration】

系统定时器配置Cortex System timer – 168MHz
spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件

👀 2 CubeMX -SYS Debug设置

🌠>> SYS Mode and Configuration
Debug – Serial Wire
Timebase Source – SysTick(后续若使用到RTOS,则需改成如TIM7的没用到的定时器!)
spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件

👀 3 CubeMX -UART通讯设置

USART3 —— 暂定用它接收(来自上位机的)控制电机指令
PD8-USART3_TX
PD9-USART3_RX
spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件
🌠>> USART3 – Mode

Item Setting
Mode Asynchronous异步模式
Hardware Flow Control (RS232) Disable

🌠>> Parameter Settings – Basic Parameters

Item Setting
Baud Rate 115200 Bits/s
Word Length 8 Bits (including Parity)
Parity None
Stop Bits 1

🌠>> Parameter Settings – Advanced Parameters

Item Setting
Data Direction Receive and Transmit
Over Sampling 16 Samples

🌠>> NVIC Settings
中断使能,优先级(0,0)。
spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件
🌠>> GPIO Settings

Item Setting
GPIO mode Alternate Function Push Pull
GPIO Pull-up/Pull-down Pull-up 注意⭐
Maximum output speed Very high

👀 4 CubeMX - TIM定时器设置

TIM8-PWM+TIM4-HALL+TIM6简单定时
本文暂时略

👀 5 CubeMX - GPIO设置

KEY+LED+PWM低桥臂
本文暂时略

👀 6 CubeMX - GPIO设置:连接DRV8323S的一些端口⭐

spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件
spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件

🥽 6.1 (STM32 - out) PA9 👈–👉 CAL (DRV8323S - in)

放大器校准输入。设置逻辑高时,内部短接放大器输入,并执行自动偏移校准。完成校准后引脚还要恢复低位,才能正常执行后续测量操作。
🪜详见数据手册【8.3.4.3 Auto Offset Calibration – P44】
spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件
🌠>> GPIO Settings

Item项目 Setting设定
GPIO Output Level Low(引脚低电平)
GPIO mode Output Push Pull(输出推挽模式)
GPIO Pull-up/Pull-down No pull-up and no pull-down
Maximum output speed High(引脚高速)

暂时不用自动校准功能!因此初始就让PA9输出低电平。

🥽6.2 (STM32 - out) PA10 👈–👉 ENABLE (DRV8323S – in,EN_GATE)

栅极驱动器启用。当该引脚为逻辑低时,设备进入低功率睡眠模式。8至40µs的低脉冲可用于重置故障条件。
🪜详见数据手册【8.4.1.1 Sleep Mode – P50】

spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件
🌠>> GPIO Settings

Item项目 Setting设定
GPIO Output Level Low(引脚低电平)
GPIO mode Output Push Pull(输出推挽模式)
GPIO Pull-up/Pull-down No pull-up and no pull-down
Maximum output speed High(引脚高速)

初始让PA10输出低电平,要使能DRV8323S芯片时,把引脚输出改为高电平。

🥽6.3 (STM32 - X) 无 👈–👉 nFAULT (DRV8323S – open-drain output) – 单片机连D11发光二极管

暂时不额外连STM32引脚来读状态(应该也可以连?目前我的板子版本未连),如果发光二极管D11亮了,则说明出故障了。
🪜详见数据手册【8.3.6 Gate Driver Protective Circuits – P47】
spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件
外部硬件电路给他上拉了,出现故障时,nFAULT pin输出逻辑低,对应发光二极管D11亮。

👀 7 CubeMX - SPI通信设置:用来和DRV8323通讯,配置PWM+发送错误信息⭐

🪜相关寄存器的配置备忘详见我的另一篇Blog:【DRV8323】电机驱动芯片寄存器配置指南,通过STM32F407的SPI通信配置。
SPI - Serial Peripheral Interface串行外围设备接口
SPI3是APB1上的设备,APB1 peripheral clocks = 42MHz,最高通信速率为 21Mbits/s。
SPI3_nSCS需要用GPIO单独配置,另外三个是SPI3自动配置的。

引脚名 STM32自命名 原理图中引脚命名
PD1 SPI3_nSCS NSCS(片选)【❗这个是GPIO_Output单独设!】
PC10 SPI3_SCK SPI_SCLK (时钟)
PC11 SPI3_MISO SPI_SDO (从机DRV8323输出数据,主机STM32输入。连DRV8323的SDO口)
PC12 SPI3_MOSI SPI_SDI (主机STM32输出数据,发给从机DRV8323。连DRV8323的SDI口)

spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件
spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件

🥽7.1 Connectivity – SPI 3

🌠>> SPI3 – Mode

Item项目 Setting设定
Mode Full-Duplex Master (全双工主机模式)
Hardware NSS Signal Disable(不是硬件控制)

🌠>> Parameter Settings – Basic Parameters

Item项目 Setting设定
Frame Format Motorola
Data Size 16 Bits
First Bit MSB First

🌠>> Parameter Settings – Clock Parameters

Item项目 Setting设定
Prescaler (for Baud Rate) 16 (❗一定要至少选16,稍微小一点都会因为太快了数据出错!)
Baud Rate 2.625 MBits/s
Clock Polarity (CPOL) Low (空闲态时,SCLK处于低电平)
Clock Phase (CPHA) 2 Edge(CPHA=1)

🌠>> Parameter Settings – Advanced Parameters

Item项目 Setting设定
CRC Calculation Disabled
NSS Signal Type Software

spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件

🥽7.2 System Core – GPIO

spi通信测试,# STM32电机驱动,STM32 HAL库(CubeMX),stm32,单片机,嵌入式硬件
🌠>> GPIO - PD1 Configuration

Item项目 Setting设定
GPIO Output Level High(初始状态引脚高电平,低电平有效)
GPIO mode Output Push Pull(输出推挽模式)
GPIO Pull-up/Pull-down No pull-up and no pull-down
Maximum output speed Very High
User Label SPI3_nSCS

🌠>> GPIO - SPI - PC10&PC11&PC12 Configuration
(?作者存疑点:PC11在CubeMX默认是输出状态?实现功能来说应该是输入)

Item项目 Setting设定
GPIO mode Alternate Function Push Pull
GPIO Pull-up/Pull-down No Pull-up and no Pull-down
Maximum output speed Very High

👀 8 Keil - SPI通信相关代码摘录

【motor_drv8323.c】代码(含寄存器和HAL库函数对比的详细版本)👇

/**
  ******************************************************************************
  * @file    motor_drv8323.c
  * @date    2023-05-08
  * @brief   驱动芯片DRV8323相关 - STM32 F407
  ******************************************************************************
  */ 

#include "motor_drv8323.h"

	uint16_t TIMP01, TIMP02, TIMP03, TIMP04, TIMP05;
	uint16_t TIMP1, TIMP2, TIMP3, TIMP4, TIMP5;

 /**
  * @brief    【MOTOR-DRV8323 SPI通信】
  *             配置 DRV8323工作状态
  * @function  0 - SPI读&写一体化函数 16位 - HAL库函数版本
  * @function  1 - SPI 读 & 写16bit函数 - 寄存器版本
  * @function  2 - DRV8323写入函数 16位 - 寄存器版本
  * @function  3 - DRV8323读取函数 16位 - 寄存器版本
  * @function  4 - SPI功能异常提示函数
  * @function  5 - 用SPI配置DRV8323的函数  (操作封装)
*/
// 0 - SPI读&写一体化函数 16位 - HAL库函数版本  【要么用后三个,要么就用这个】
uint16_t SPI_ReadWrite_DRV8323(uint16_t ReadAddr)
{
	uint16_t value; 
	
	SPI3_nSCS_LOW();   // SPI3-nSCS 拉低使能  //HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_RESET);
	
	//HAL_Delay(500);      // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延时,否则速度太快可能会出错!
	HAL_SPI_TransmitReceive(&hspi3, (uint8_t*)&ReadAddr, (uint8_t*)&value, 1, 1000);  // 通过一个强制转换“骗过”库函数接口
	//HAL_Delay(500);      // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延时,否则速度太快可能会出错!
	SPI3_nSCS_HIGH();  // SPI3-nSCS 拉高关断  //HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_SET);
	
	HAL_Delay(500);
	
  return value;
}
// 1 - SPI读&写16bit函数 - 寄存器版本
uint16_t SPI_ReadWrite16bit(uint16_t ReadAddr)
{
	int SPITimeout = SPIT_FLAG_TIMEOUT;     // 等待超时时间 设为0x1000
    // Loop while DR register in not emplty 等待发送缓冲区为空,TXE 事件
    while (__HAL_SPI_GET_FLAG( &hspi3,  SPI_FLAG_TXE ) == RESET)
    {
      if((SPITimeout--) == 0)
			  {  SPI_ERROR_UserCallback();  return 0;    }
    }
    // Send Half Word through the SPIx peripheral 写入数据寄存器,把要写入的数据写入发送缓冲区
    WRITE_REG(hspi3.Instance->DR, ReadAddr);

    SPITimeout = SPIT_FLAG_TIMEOUT;
    // Wait to receive a Half Word 等待接收缓冲区非空,RXNE 事件
    while (__HAL_SPI_GET_FLAG( &hspi3, SPI_FLAG_RXNE ) == RESET)
    {
      if((SPITimeout--) == 0)
			  {    SPI_ERROR_UserCallback();  return 0;  }
    }
    // Return the Half Word read from the SPI bus 读取数据寄存器,获取接收缓冲区数据
    return READ_REG(hspi3.Instance->DR);
}

// 2 - DRV8323写入函数 16位 - 寄存器版本
uint16_t SPI_WRITE_DRV8323(uint16_t WriteData)
{
  uint16_t RxData; 
	
  SPI3_nSCS_LOW();   // SPI3-nSCS 拉低使能
  HAL_Delay(100);       // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延时,否则速度太快可能会出错!
  SPI_ReadWrite16bit(WriteData);
  HAL_Delay(100);       // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延时,否则速度太快可能会出错!
  SPI3_nSCS_HIGH();  // SPI3-nSCS 拉高关断
  HAL_Delay(100);       // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延时,否则速度太快可能会出错!
	
  return RxData;  // 对于Write操作不用有返回值,这里有只是更方便调试观察,看看是否正确写入
}

// 3 - DRV8323读取函数 16位 - 寄存器版本
uint16_t SPI_Read_DRV8323(uint16_t ReadAddr)  
{
	uint16_t RxData;
	
	SPI3_nSCS_LOW();    // SPI3-nSCS 拉低使能
    HAL_Delay(100);        // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延时,否则速度太快可能会出错!
	RxData = SPI_ReadWrite16bit(ReadAddr);
    HAL_Delay(100);        // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延时,否则速度太快可能会出错!
	SPI3_nSCS_HIGH();   // SPI3-nSCS引脚拉高,因为不用它了
	HAL_Delay(100);        // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延时,否则速度太快可能会出错!
	
    return RxData;
}

// 4 - SPI功能异常提示函数
void SPI_ERROR_UserCallback(void)
{
    /* 等待超时后的处理,输出错误信息 */
    printf("SPI 通信异常! \r\n");
}

// 5 - 用SPI设置DRV8323的函数  (操作封装)
void Set_DRV8323(void)
{
	  //库函数版本测试代码
	  Drv8323_ENABLE();//使能Drv-Enable输入高电平,驱动芯片开始工作
      HAL_Delay(1000);
	//SPI_ReadWrite_DRV8323(Dummy_Byte);HAL_Delay(500);
//	TIMP1 = SPI_ReadWrite_DRV8323(0x9000);//取地址0x02
//  TIMP2 = SPI_ReadWrite_DRV8323(0x9800);//取地址0x03
//  TIMP3 = SPI_ReadWrite_DRV8323(0xA000);//取地址0x04
//  TIMP4 = SPI_ReadWrite_DRV8323(0xA800);//取地址0x05
//  TIMP5 = SPI_ReadWrite_DRV8323(0xB000);//取地址0x06
	TIMP01 = SPI_ReadWrite_DRV8323(0x1000); //address 02
	TIMP02 = SPI_ReadWrite_DRV8323(0x1bff); //address 03
	TIMP03 = SPI_ReadWrite_DRV8323(0x27ff); //address 04
	TIMP04 = SPI_ReadWrite_DRV8323(0x2a59); //address 05
	TIMP05 = SPI_ReadWrite_DRV8323(0x3283); //address 06
//	SPI_ReadWrite_DRV8323(0x1000); //address 02
//  SPI_ReadWrite_DRV8323(0x1B22); //address 03
//  SPI_ReadWrite_DRV8323(0x2722); //address 04
//  SPI_ReadWrite_DRV8323(0x2B66); //address 05
//  SPI_ReadWrite_DRV8323(0x3280); //address 06
    HAL_Delay(500);

    TIMP1 = SPI_ReadWrite_DRV8323(0x9000);//取地址0x02
    TIMP2 = SPI_ReadWrite_DRV8323(0x9800);//取地址0x03
    TIMP3 = SPI_ReadWrite_DRV8323(0xA000);//取地址0x04
    TIMP4 = SPI_ReadWrite_DRV8323(0xA800);//取地址0x05
    TIMP5 = SPI_ReadWrite_DRV8323(0xB000);//取地址0x06

	printf("add0x02 = %d \r\n", TIMP1);
	printf("add0x03 = %d \r\n", TIMP2);
	printf("add0x04 = %d \r\n", TIMP3);
	printf("add0x05 = %d \r\n", TIMP4);
	printf("add0x06 = %d \r\n", TIMP5);
	
	Drv8323_DISABLE();//使能Drv-Enable输入低电平,驱动芯片停止工作
	
	/*  //寄存器版本测试代码
	  Drv8323_ENABLE();//使能Drv-Enable输入高电平,驱动芯片开始工作
    HAL_Delay(1000);
	
//  TIMP01 = SPI_WRITE_DRV8323(0x1000); //address 02
//  TIMP02 = SPI_WRITE_DRV8323(0x1bff); //address 03
//  TIMP03 = SPI_WRITE_DRV8323(0x27ff); //address 04
//  TIMP04 = SPI_WRITE_DRV8323(0x2a59); //address 05
//  TIMP05 = SPI_WRITE_DRV8323(0x3283); //address 06
//    HAL_Delay(500);

  TIMP1 = SPI_Read_DRV8323(0x9000);//取地址0x02
  TIMP2 = SPI_Read_DRV8323(0x9800);//取地址0x03
  TIMP3 = SPI_Read_DRV8323(0xA000);//取地址0x04
  TIMP4 = SPI_Read_DRV8323(0xA800);//取地址0x05
  TIMP5 = SPI_Read_DRV8323(0xB000);//取地址0x06

	printf("add0x02 = %d \r\n", TIMP1);
	printf("add0x03 = %d \r\n", TIMP2);
	printf("add0x04 = %d \r\n", TIMP3);
	printf("add0x05 = %d \r\n", TIMP4);
	printf("add0x06 = %d \r\n", TIMP5);
	
	  Drv8323_DISABLE();//使能Drv-Enable输入低电平,驱动芯片停止工作
	*/
}

 /**
  * @brief    【MOTOR-DRV8323 芯片使能】
  * @function  1 - DRV8323的芯片使能
  * @function  2 - DRV8323的芯片关闭
*/
// 1 - DRV8323的芯片使能
void Drv8323_ENABLE(void)   //DRV8323 Enable
{
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
	//printf("DRV8323S 芯片启用。\r\n");
}
// 2 - DRV8323的芯片关闭
void Drv8323_DISABLE(void)   //DRV8323 Disable
{
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
	//printf("DRV8323S 芯片关闭。\r\n");
}

【motor_drv8323.c】代码(HAL库函数的简洁版本,可直接用)👇

/**
  ******************************************************************************
  * @file    motor_drv8323.c
  * @date    2023-05-08
  * @brief   驱动芯片DRV8323相关 - STM32 F407
  ******************************************************************************
  */ 

#include "motor_drv8323.h"

	uint16_t TIMP01, TIMP02, TIMP03, TIMP04, TIMP05;
	uint16_t TIMP1, TIMP2, TIMP3, TIMP4, TIMP5;

 /**
  * @brief    【MOTOR-DRV8323 SPI通信】
  *             配置 DRV8323工作状态
  * @function  1 - SPI读&写一体化函数 16位 - HAL库函数版本
  * @function  2 - SPI功能异常提示函数
  * @function  3 - 用SPI配置DRV8323的函数  (操作封装)
*/
// 1 - SPI读&写一体化函数 16位 - HAL库函数版本
uint16_t SPI_ReadWrite_DRV8323(uint16_t ReadAddr)
{
	uint16_t value; 
	
	SPI3_nSCS_LOW();   // SPI3-nSCS 拉低使能  //HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_RESET);
	HAL_Delay(100);      // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延时(大概500),否则速度太快可能会出错!
	HAL_SPI_TransmitReceive(&hspi3, (uint8_t*)&ReadAddr, (uint8_t*)&value, 1, 1000);  // 通过一个强制转换“骗过”库函数接口
	HAL_Delay(100);      // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延时(大概500),否则速度太快可能会出错!
	SPI3_nSCS_HIGH();  // SPI3-nSCS 拉高关断  //HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_SET);
	HAL_Delay(500);
	
  return value;
}

// 2 - SPI功能异常提示函数
void SPI_ERROR_UserCallback(void)
{
  /* 等待超时后的处理,输出错误信息 */
  printf("SPI 通信异常! \r\n");
}

// 3 - 用SPI设置DRV8323的函数  (操作封装)
void Set_DRV8323(void)
{
	Drv8323_ENABLE();//使能Drv-Enable输入高电平,驱动芯片开始工作
    HAL_Delay(1000);
	TIMP01 = SPI_ReadWrite_DRV8323(0x1000); //address 02
	TIMP02 = SPI_ReadWrite_DRV8323(0x1bff); //address 03
	TIMP03 = SPI_ReadWrite_DRV8323(0x27ff); //address 04
	TIMP04 = SPI_ReadWrite_DRV8323(0x2a59); //address 05
	TIMP05 = SPI_ReadWrite_DRV8323(0x3283); //address 06
    HAL_Delay(200);

  TIMP1 = SPI_ReadWrite_DRV8323(0x9000);//取地址0x02
  TIMP2 = SPI_ReadWrite_DRV8323(0x9800);//取地址0x03
  TIMP3 = SPI_ReadWrite_DRV8323(0xA000);//取地址0x04
  TIMP4 = SPI_ReadWrite_DRV8323(0xA800);//取地址0x05
  TIMP5 = SPI_ReadWrite_DRV8323(0xB000);//取地址0x06

    printf("======DRV8323寄存器配置情况======\r\n");
	printf("add0x02 = %x \r\n", TIMP1);    // %d - 十进制
	printf("add0x03 = %x \r\n", TIMP2);    // %x - 十六进制
	printf("add0x04 = %x \r\n", TIMP3);
	printf("add0x05 = %x \r\n", TIMP4);
	printf("add0x06 = %x \r\n", TIMP5);
	printf("=================================\r\n");
	
	//Drv8323_DISABLE();//使能Drv-Enable输入低电平,驱动芯片停止工作
	//在这里就关的话就用不了啦!
}

 /**
  * @brief    【MOTOR-DRV8323 芯片使能】
  * @function  1 - DRV8323的芯片使能
	* @function  2 - DRV8323的芯片关闭
*/
// 1 - DRV8323的芯片使能
void Drv8323_ENABLE(void)   //DRV8323 Enable
{
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
	printf("DRV8323S 芯片启用。\r\n");
}
// 2 - DRV8323的芯片关闭
void Drv8323_DISABLE(void)   //DRV8323 Disable
{
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
	printf("DRV8323S 芯片关闭。\r\n");
}

【motor_drv8323.h】代码👇

#ifndef __MOTOR_DRV8323_H
#define	__MOTOR_DRV8323_H
#include "stm32f4xx.h"

#include "spi.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/**********  MOTOR_CONTROL 宏定义  **********/
#define Dummy_Byte   0xFFFF
#define SPIT_FLAG_TIMEOUT         ((uint32_t)0x1000)  // 等待超时时间
#define SPI3_CLK_ENABLE()           __HAL_RCC_SPI3_CLK_ENABLE()
//SCK 引脚
#define SPI3_SCK_PIN   GPIO_PIN_10
#define SPI3_SCK_      GPIO_PORT GPIOC
//MISO 引脚
#define SPI3_MISO_PIN        GPIO_PIN_11
#define SPI3_MISO_GPIO_PORT  GPIOC
//MOSI 引脚
#define SPI3_MOSI_PIN        GPIO_PIN_12
#define SPI3_MOSI_GPIO_PORT  GPIOC
//CS(nSCS) 引脚
#define SPI3_nSCS_PIN         GPIO_PIN_1
#define SPI3_nSCS_GPIO_PORT   GPIOD

// 以下是两种方法给SPI3_nSCS 高、低电平        ??据说操作寄存器比调用HAL库函数快
// 寄存器版本 给SPI3_nSCS 高、低电平,用寄存器版本可能需要多一点点延时,以免软件速度太快硬件跟不上。
 BSRR寄存器:控制管脚的高、低电平。32位有效,低16位写1 高电平,高16位写1 低电平。
//#define digitalLow(p,i)  {p->BSRR=(uint32_t)i << 16;}  //输出低电平
//#define digitalHigh(p,i) {p->BSRR=i;}                  //设置为高电平
//#define SPI3_nSCS_LOW()  digitalLow( SPI3_nSCS_GPIO_PORT, SPI3_nSCS_PIN )
//#define SPI3_nSCS_HIGH() digitalHigh(SPI3_nSCS_GPIO_PORT, SPI3_nSCS_PIN )
// 库函数版本 给SPI3_nSCS 高、低电平
#define SPI3_nSCS_LOW()   HAL_GPIO_WritePin(SPI3_nSCS_GPIO_PORT, SPI3_nSCS_PIN, GPIO_PIN_RESET)
#define SPI3_nSCS_HIGH()  HAL_GPIO_WritePin(SPI3_nSCS_GPIO_PORT, SPI3_nSCS_PIN, GPIO_PIN_SET)
/********************************************/

/********** MOTOR_CONTROL 相关变量 **********/
extern SPI_HandleTypeDef hspi3;

/********************************************/

/********** MOTOR_CONTROL 函数声明 **********/
// 【MOTOR-DRV8323 SPI通信】
uint16_t SPI_ReadWrite_DRV8323(uint16_t ReadAddr);// 0 - SPI读&写一体化函数 16位 - HAL库函数版本
uint16_t SPI_ReadWrite16bit(uint16_t ReadAddr);// 1 - SPI 读 & 写16bit函数 - 寄存器版本
uint16_t SPI_WRITE_DRV8323(uint16_t WriteData);// 2 - DRV8323写入函数 16位 - 寄存器版本
uint16_t SPI_Read_DRV8323(uint16_t ReadAddr);  // 3 - DRV8323读取函数 16位 - 寄存器版本
void SPI_ERROR_UserCallback(void);  // 4 - SPI功能异常提示函数
void Set_DRV8323(void);    // 5 - 用SPI配置DRV8323的函数  (操作封装)

// 【MOTOR-DRV8323 芯片使能】
void Drv8323_ENABLE(void);
void Drv8323_DISABLE(void);
/********************************************/


/* USER CODE BEGIN Private defines */


#endif  /* __MOTOR_DRV8323_H */

【main.c】代码👇

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "LED/led.h"
#include "KEY/key.h"
#include "MOTOR/motor_tim.h"
#include "MOTOR/motor_control.h"
#include "MOTOR/motor_drv8323.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */


/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM4_Init();
  MX_SPI3_Init();
  MX_UART4_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();
  MX_TIM6_Init();
  MX_TIM8_Init();
  /* USER CODE BEGIN 2 */

	Init_Motor();      // MX_TIMx_Init();也在里面
	Init_LED();
	Set_Motor_StartStop(0);  //关闭电机 - stop PWM & Hall
	Set_DRV8323();           // 通过SPI配置DRV8323寄存器,来配置驱动芯片工作模式
	
	Set_Motor_StartStop(1);  //开启电机 - enable PWM & Hall
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 168;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

😶‍🌫️说在最后

本文关于SPI通信的介绍到这里就结束啦,预祝大家调试顺利!
附上笔者学习过程中觉得对自己有帮助的博文:
🎫STM32G4系列通过SPI配置DRV8353S驱动芯片_超级馒头神的博客-CSDN博客(驱动芯片区别应该仅在于芯片的驱动电压范围不同);
🎫DRV8301的使用_【ql君】qlexcel的博客-CSDN博客;
🎫STM32F334 SPI编程里的坑_hy_wujun-CSDN博客;
🎫【STM32】HAL库开发教程(七)—SPI使用_怪怪王-CSDN博客
🎫关于STM32使用SPI接口实现自通信的一个详细示例(程序实现)_曾小庆-知乎
🎫stm32 GPIO模拟SPI接口实现双机通信_惆怅客~-CSDN博客
🎫DRV8301 SPI调试问题(接收一直为0x0000)_映月寒-CSDN博客
🎫DRV8323S关于SPI通信以及PWM输出不正常-TI官网论坛;
🎫DRV8323 PWM OUTPUT-TI官网论坛;
🎫[FAQ] SPI Configuration and Use-TI官网论坛;
🎫【正点原子-STM32F1开发指南(精英板-HAL库版)-CH28】
🎫【野火-STM32 HAL库开发实战指南——基于野火F4系列开发板-CH23】 比ZDYZ的这个部分讲解得更清晰,更推荐一点点。文章来源地址https://www.toymoban.com/news/detail-718944.html

到了这里,关于【STM32】BLDC驱动&控制开发笔记 | 07_SPI通信测试 - STM32F407用SPI配置DRV8323驱动芯片的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32初学入门笔记(5):使用STM32CubeMX通过SPI,IIC驱动OLED屏幕

    随着时代的进步,OLED显示屏成为了继LCD显示屏之后的新一代显示屏技术,OLED具有可视角高,功耗低,厚度薄,耐冲击、振动能力强,像素响应时间低等优点,在嵌入式开发中,OLED显示器也是一个主要的部分,制作OLED显示模块的驱动也是学习STM32路上的重要一部分,本篇将从

    2024年02月04日
    浏览(18)
  • 【DRV8323】电机驱动芯片寄存器配置指南,通过STM32F407的SPI通信配置

    笔者计划使用一块使用到STM32F407控制芯片与DRV8323s驱动芯片的板子,驱动BLDC。了解到需要使用SPI通信来配置DRV8323s驱动芯片,配置过程中涉及DRV8323数据手册中提及的几个寄存器,故写此文做个记录。 另外,DRV8323芯片和DRV8302、DRV8303、DRV8353都有极大的相似之处,可以相互参考

    2024年02月02日
    浏览(33)
  • STM32之CubeMX学习笔记(7)SPI驱动OLED及其优化

    购买了逻辑分析仪后,总想着把所有的通讯信号全都看一遍。之前一篇笔记讲的是串口通信,做了一些小实验,搞清楚了如何基于底层利用串口传一些“非标”的数据。关于通信协议的第二篇,我想来看看SPI通信。 SPI通信是Serial peripheral interface的缩写,中文是串行外设接口,

    2024年02月04日
    浏览(31)
  • STM32C0开发(1)----SPI 驱动WS2812灯珠

    本文介绍了如何使用STM32微控制器,结合STM32CubeMX配置工具和SPI通讯接口,来驱动和控制WS2812 LED灯带。这是一个集硬件连接、软件配置和编程开发于一体的综合性项目,目标是实现对LED灯带颜色和亮度的精确控制。 最近在弄ST的课程,需要样片的可以加群申请:615061293 。 ht

    2024年02月04日
    浏览(14)
  • STM32H5开发(6)----SPI驱动TFT-LCD屏

    在嵌入式领域,TFT-LCD屏是最常用的显示解决方案之一,因为它们提供了丰富的颜色和高分辨率的图像显示能力。STM32H5作为ST的高性能微控制器系列,具备了强大的处理能力和多种通信接口,非常适合于驱动TFT-LCD显示屏,该液晶屏st7796或者ILI9488驱动芯片,这两个屏幕都是兼容

    2024年02月05日
    浏览(20)
  • STM32 SPI+DMA 驱动 SRAM LY68L6400SLIT 应用笔记

    : 库函数,STM32F407,SPI+DMA ,SPI-DMA,SRAM , LY68L6400SLIT,STM32CubeMX 编 辑: 大黄蜂 说明: 本笔记记录 基于 STM32F407 + RT RTOS 采用 SPI接口和 SPI+DMA接口 调试 SRAM LY68L6400SLIT (8M 字节 SRAM) 重点: STM32 HAL SPI 库函数;STM32CubeMX SPI 配置;STM32CubeMX SPI 配置+DMA配置;SPI+DMA 读写SR

    2024年02月12日
    浏览(18)
  • 基于 MM32SPIN0280 无感方波 BLDC 电动工具驱动篇应用笔记

    M32SPIN0280 是灵动微电机新推出的针对电机控制市场的专用 MCU,该系列 MCU 搭载了Arm®Cortex®-M0 内核,最高工作频率可达 96MHz,内置高速存储器,并集成了 I/O 端口和多种外设。MM32SPIN0280 系列 MCU 适用于各类电机应用场景,其典型应用包括风机、水泵、电动自行车、服务器风机

    2024年01月23日
    浏览(20)
  • STM32F103单片机通过SPI全双工通信协议与W25Q64(FLASH)进行通信【串行同步通信(数据线与时钟线配合),(一主多从模式)】附相关驱动代码详解

    1.W25Qxx系列是一种低成本、小型化、使用简单的 非易失性存储器 ,常应用于数据存储、字库存储、固件程序存储等场景 2.存储介质: Nor Flash(闪存) 3.时钟频率:80MHz / 160MHz (Dual SPI) / 320MHz (Quad SPI) 4.存储容量(24位地址): W25Q40: 4Mbit / 512KByte W25Q80: 8Mbit / 1MByte W25Q16: 16

    2024年04月13日
    浏览(24)
  • STM32——SPI通信

    SPI(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线 四根通信线: SCK(Serial Clock)【CLK或SCL或CK】、 MOSI(Master Output Slave Input)【DO(Data Output)】、 MISO(Master Input Slave Output)【DI(Data Input)】、 SS(Slave Select)【CS或NSS】 同步,全双工 支持总线挂载多设备

    2024年02月11日
    浏览(16)
  • Qt实现安卓手机蓝牙通信并控制stm32f103c8t6驱动VFD屏

    Qt具有跨平台的特性所以非常适合写通信的demo,但是在这个例程中Qt蓝牙部分不支持Windows平台,安卓平台使用没问题。 Qt蓝牙主要涉及到三个类的使用: QBluetoothDeviceDiscoveryAgent //扫描周围蓝牙设备 QBluetoothLocalDevice //扫描本地蓝牙 QBluetoothSocket //建立蓝牙的socket读写 安卓不支

    2024年02月08日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包