??????說在最前面 + 實(shí)現(xiàn)功能
最近在埋頭搞STM32 + 無刷直流電機(jī)控制,想實(shí)現(xiàn)用自己的STM32F407VGT6芯片板子,外加一塊驅(qū)動(dòng)板(目前選用到TI的DRV8302或者DRV8323驅(qū)動(dòng)芯片),搞定電機(jī)驅(qū)動(dòng),最后實(shí)現(xiàn)比較好的控制效果。如果不是同一塊芯片的同學(xué)也不用急著走,大體上都是可借鑒噠~
本文主要實(shí)現(xiàn)使用SPI通信,通過STM32F407控制芯片來對(duì)DRV8323S驅(qū)動(dòng)芯片進(jìn)行配置,為使用DRV8323做好準(zhǔn)備。
目標(biāo)操作: 不啟動(dòng)電機(jī),僅使能DRV8323S芯片。使用SPI朝DRV8323S芯片寫幾個(gè)地址的配置,然后再讀取這幾個(gè)位置的狀態(tài),檢查是否通信正常。調(diào)試過程借助Keil的Debug功能中 watch變量的值,或使用UASRT串口通信打印出信息,來檢查。
如果文章中有什么錯(cuò)誤和待改進(jìn)的地方,歡迎在評(píng)論區(qū)指出交流,共同學(xué)習(xí)和進(jìn)步!?
首先是一系列用CubeMX的配置操作。
?? 1 CubeMX - RCC & Clock Configuration時(shí)鐘配置
?? 1.1 【System Core】 – 【RCC】
HSE – Crystal/Ceramic Resonator
高速時(shí)鐘源 – 外部晶振
會(huì)自動(dòng)分配好管腳RCC_OSC_IN & RCC_OSC_OUT:
PH0 – RCC_OSC_IN
PH1 – RCC_OSC_OUT.
?? 1.2 【Clock Configuration】
系統(tǒng)定時(shí)器配置Cortex System timer – 168MHz
?? 2 CubeMX -SYS Debug設(shè)置
??>> SYS Mode and Configuration
Debug – Serial Wire
Timebase Source – SysTick(后續(xù)若使用到RTOS,則需改成如TIM7的沒用到的定時(shí)器?。?br>
?? 3 CubeMX -UART通訊設(shè)置
USART3 —— 暫定用它接收(來自上位機(jī)的)控制電機(jī)指令
PD8-USART3_TX
PD9-USART3_RX
??>> 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
中斷使能,優(yōu)先級(jí)(0,0)。
??>> 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定時(shí)器設(shè)置
TIM8-PWM+TIM4-HALL+TIM6簡單定時(shí)
本文暫時(shí)略
?? 5 CubeMX - GPIO設(shè)置
KEY+LED+PWM低橋臂
本文暫時(shí)略
?? 6 CubeMX - GPIO設(shè)置:連接DRV8323S的一些端口?
?? 6.1 (STM32 - out) PA9 ??–?? CAL (DRV8323S - in)
放大器校準(zhǔn)輸入。設(shè)置邏輯高時(shí),內(nèi)部短接放大器輸入,并執(zhí)行自動(dòng)偏移校準(zhǔn)。完成校準(zhǔn)后引腳還要恢復(fù)低位,才能正常執(zhí)行后續(xù)測(cè)量操作。
??詳見數(shù)據(jù)手冊(cè)【8.3.4.3 Auto Offset Calibration – P44】
??>> GPIO Settings
Item項(xiàng)目 | Setting設(shè)定 |
---|---|
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(引腳高速) |
暫時(shí)不用自動(dòng)校準(zhǔn)功能!因此初始就讓PA9輸出低電平。
??6.2 (STM32 - out) PA10 ??–?? ENABLE (DRV8323S – in,EN_GATE)
柵極驅(qū)動(dòng)器啟用。當(dāng)該引腳為邏輯低時(shí),設(shè)備進(jìn)入低功率睡眠模式。8至40μs的低脈沖可用于重置故障條件。
??詳見數(shù)據(jù)手冊(cè)【8.4.1.1 Sleep Mode – P50】
??>> GPIO Settings
Item項(xiàng)目 | Setting設(shè)定 |
---|---|
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芯片時(shí),把引腳輸出改為高電平。
??6.3 (STM32 - X) 無 ??–?? nFAULT (DRV8323S – open-drain output) – 單片機(jī)連D11發(fā)光二極管
暫時(shí)不額外連STM32引腳來讀狀態(tài)(應(yīng)該也可以連?目前我的板子版本未連),如果發(fā)光二極管D11亮了,則說明出故障了。
??詳見數(shù)據(jù)手冊(cè)【8.3.6 Gate Driver Protective Circuits – P47】
外部硬件電路給他上拉了,出現(xiàn)故障時(shí),nFAULT pin輸出邏輯低,對(duì)應(yīng)發(fā)光二極管D11亮。
?? 7 CubeMX - SPI通信設(shè)置:用來和DRV8323通訊,配置PWM+發(fā)送錯(cuò)誤信息?
??相關(guān)寄存器的配置備忘詳見我的另一篇Blog:【DRV8323】電機(jī)驅(qū)動(dòng)芯片寄存器配置指南,通過STM32F407的SPI通信配置。
SPI - Serial Peripheral Interface串行外圍設(shè)備接口
SPI3是APB1上的設(shè)備,APB1 peripheral clocks = 42MHz,最高通信速率為 21Mbits/s。
SPI3_nSCS需要用GPIO單獨(dú)配置,另外三個(gè)是SPI3自動(dòng)配置的。
引腳名 | STM32自命名 | 原理圖中引腳命名 |
---|---|---|
PD1 | SPI3_nSCS | NSCS(片選)【?這個(gè)是GPIO_Output單獨(dú)設(shè)!】 |
PC10 | SPI3_SCK | SPI_SCLK (時(shí)鐘) |
PC11 | SPI3_MISO | SPI_SDO (從機(jī)DRV8323輸出數(shù)據(jù),主機(jī)STM32輸入。連DRV8323的SDO口) |
PC12 | SPI3_MOSI | SPI_SDI (主機(jī)STM32輸出數(shù)據(jù),發(fā)給從機(jī)DRV8323。連DRV8323的SDI口) |
??7.1 Connectivity – SPI 3
??>> SPI3 – Mode
Item項(xiàng)目 | Setting設(shè)定 |
---|---|
Mode | Full-Duplex Master (全雙工主機(jī)模式) |
Hardware NSS Signal | Disable(不是硬件控制) |
??>> Parameter Settings – Basic Parameters
Item項(xiàng)目 | Setting設(shè)定 |
---|---|
Frame Format | Motorola |
Data Size | 16 Bits |
First Bit | MSB First |
??>> Parameter Settings – Clock Parameters
Item項(xiàng)目 | Setting設(shè)定 |
---|---|
Prescaler (for Baud Rate) | 16 (?一定要至少選16,稍微小一點(diǎn)都會(huì)因?yàn)樘炝藬?shù)據(jù)出錯(cuò)?。?/td> |
Baud Rate | 2.625 MBits/s |
Clock Polarity (CPOL) | Low (空閑態(tài)時(shí),SCLK處于低電平) |
Clock Phase (CPHA) | 2 Edge(CPHA=1) |
??>> Parameter Settings – Advanced Parameters
Item項(xiàng)目 | Setting設(shè)定 |
---|---|
CRC Calculation | Disabled |
NSS Signal Type | Software |
??7.2 System Core – GPIO
??>> GPIO - PD1 Configuration
Item項(xiàng)目 | Setting設(shè)定 |
---|---|
GPIO Output Level | High(初始狀態(tài)引腳高電平,低電平有效) |
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
(?作者存疑點(diǎn):PC11在CubeMX默認(rèn)是輸出狀態(tài)?實(shí)現(xiàn)功能來說應(yīng)該是輸入)
Item項(xiàng)目 | Setting設(shè)定 |
---|---|
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通信相關(guān)代碼摘錄
【motor_drv8323.c】代碼(含寄存器和HAL庫函數(shù)對(duì)比的詳細(xì)版本)??
/**
******************************************************************************
* @file motor_drv8323.c
* @date 2023-05-08
* @brief 驅(qū)動(dòng)芯片DRV8323相關(guān) - 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工作狀態(tài)
* @function 0 - SPI讀&寫一體化函數(shù) 16位 - HAL庫函數(shù)版本
* @function 1 - SPI 讀 & 寫16bit函數(shù) - 寄存器版本
* @function 2 - DRV8323寫入函數(shù) 16位 - 寄存器版本
* @function 3 - DRV8323讀取函數(shù) 16位 - 寄存器版本
* @function 4 - SPI功能異常提示函數(shù)
* @function 5 - 用SPI配置DRV8323的函數(shù) (操作封裝)
*/
// 0 - SPI讀&寫一體化函數(shù) 16位 - HAL庫函數(shù)版本 【要么用后三個(gè),要么就用這個(gè)】
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寄存器操作版本,需要加上延時(shí),否則速度太快可能會(huì)出錯(cuò)!
HAL_SPI_TransmitReceive(&hspi3, (uint8_t*)&ReadAddr, (uint8_t*)&value, 1, 1000); // 通過一個(gè)強(qiáng)制轉(zhuǎn)換“騙過”庫函數(shù)接口
//HAL_Delay(500); // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延時(shí),否則速度太快可能會(huì)出錯(cuò)!
SPI3_nSCS_HIGH(); // SPI3-nSCS 拉高關(guān)斷 //HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(500);
return value;
}
// 1 - SPI讀&寫16bit函數(shù) - 寄存器版本
uint16_t SPI_ReadWrite16bit(uint16_t ReadAddr)
{
int SPITimeout = SPIT_FLAG_TIMEOUT; // 等待超時(shí)時(shí)間 設(shè)為0x1000
// Loop while DR register in not emplty 等待發(fā)送緩沖區(qū)為空,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 寫入數(shù)據(jù)寄存器,把要寫入的數(shù)據(jù)寫入發(fā)送緩沖區(qū)
WRITE_REG(hspi3.Instance->DR, ReadAddr);
SPITimeout = SPIT_FLAG_TIMEOUT;
// Wait to receive a Half Word 等待接收緩沖區(qū)非空,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 讀取數(shù)據(jù)寄存器,獲取接收緩沖區(qū)數(shù)據(jù)
return READ_REG(hspi3.Instance->DR);
}
// 2 - DRV8323寫入函數(shù) 16位 - 寄存器版本
uint16_t SPI_WRITE_DRV8323(uint16_t WriteData)
{
uint16_t RxData;
SPI3_nSCS_LOW(); // SPI3-nSCS 拉低使能
HAL_Delay(100); // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延時(shí),否則速度太快可能會(huì)出錯(cuò)!
SPI_ReadWrite16bit(WriteData);
HAL_Delay(100); // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延時(shí),否則速度太快可能會(huì)出錯(cuò)!
SPI3_nSCS_HIGH(); // SPI3-nSCS 拉高關(guān)斷
HAL_Delay(100); // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延時(shí),否則速度太快可能會(huì)出錯(cuò)!
return RxData; // 對(duì)于Write操作不用有返回值,這里有只是更方便調(diào)試觀察,看看是否正確寫入
}
// 3 - DRV8323讀取函數(shù) 16位 - 寄存器版本
uint16_t SPI_Read_DRV8323(uint16_t ReadAddr)
{
uint16_t RxData;
SPI3_nSCS_LOW(); // SPI3-nSCS 拉低使能
HAL_Delay(100); // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延時(shí),否則速度太快可能會(huì)出錯(cuò)!
RxData = SPI_ReadWrite16bit(ReadAddr);
HAL_Delay(100); // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延時(shí),否則速度太快可能會(huì)出錯(cuò)!
SPI3_nSCS_HIGH(); // SPI3-nSCS引腳拉高,因?yàn)椴挥盟?/span>
HAL_Delay(100); // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延時(shí),否則速度太快可能會(huì)出錯(cuò)!
return RxData;
}
// 4 - SPI功能異常提示函數(shù)
void SPI_ERROR_UserCallback(void)
{
/* 等待超時(shí)后的處理,輸出錯(cuò)誤信息 */
printf("SPI 通信異常! \r\n");
}
// 5 - 用SPI設(shè)置DRV8323的函數(shù) (操作封裝)
void Set_DRV8323(void)
{
//庫函數(shù)版本測(cè)試代碼
Drv8323_ENABLE();//使能Drv-Enable輸入高電平,驅(qū)動(dòng)芯片開始工作
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輸入低電平,驅(qū)動(dòng)芯片停止工作
/* //寄存器版本測(cè)試代碼
Drv8323_ENABLE();//使能Drv-Enable輸入高電平,驅(qū)動(dòng)芯片開始工作
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輸入低電平,驅(qū)動(dòng)芯片停止工作
*/
}
/**
* @brief 【MOTOR-DRV8323 芯片使能】
* @function 1 - DRV8323的芯片使能
* @function 2 - DRV8323的芯片關(guān)閉
*/
// 1 - DRV8323的芯片使能
void Drv8323_ENABLE(void) //DRV8323 Enable
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
//printf("DRV8323S 芯片啟用。\r\n");
}
// 2 - DRV8323的芯片關(guān)閉
void Drv8323_DISABLE(void) //DRV8323 Disable
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
//printf("DRV8323S 芯片關(guān)閉。\r\n");
}
【motor_drv8323.c】代碼(HAL庫函數(shù)的簡潔版本,可直接用)??
/**
******************************************************************************
* @file motor_drv8323.c
* @date 2023-05-08
* @brief 驅(qū)動(dòng)芯片DRV8323相關(guān) - 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工作狀態(tài)
* @function 1 - SPI讀&寫一體化函數(shù) 16位 - HAL庫函數(shù)版本
* @function 2 - SPI功能異常提示函數(shù)
* @function 3 - 用SPI配置DRV8323的函數(shù) (操作封裝)
*/
// 1 - SPI讀&寫一體化函數(shù) 16位 - HAL庫函數(shù)版本
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寄存器操作版本,需要加上延時(shí)(大概500),否則速度太快可能會(huì)出錯(cuò)!
HAL_SPI_TransmitReceive(&hspi3, (uint8_t*)&ReadAddr, (uint8_t*)&value, 1, 1000); // 通過一個(gè)強(qiáng)制轉(zhuǎn)換“騙過”庫函數(shù)接口
HAL_Delay(100); // 如果 LOW & HIGH 操作是使用的BSRR寄存器操作版本,需要加上延時(shí)(大概500),否則速度太快可能會(huì)出錯(cuò)!
SPI3_nSCS_HIGH(); // SPI3-nSCS 拉高關(guān)斷 //HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(500);
return value;
}
// 2 - SPI功能異常提示函數(shù)
void SPI_ERROR_UserCallback(void)
{
/* 等待超時(shí)后的處理,輸出錯(cuò)誤信息 */
printf("SPI 通信異常! \r\n");
}
// 3 - 用SPI設(shè)置DRV8323的函數(shù) (操作封裝)
void Set_DRV8323(void)
{
Drv8323_ENABLE();//使能Drv-Enable輸入高電平,驅(qū)動(dòng)芯片開始工作
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 - 十進(jìn)制
printf("add0x03 = %x \r\n", TIMP2); // %x - 十六進(jìn)制
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輸入低電平,驅(qū)動(dòng)芯片停止工作
//在這里就關(guān)的話就用不了啦!
}
/**
* @brief 【MOTOR-DRV8323 芯片使能】
* @function 1 - DRV8323的芯片使能
* @function 2 - DRV8323的芯片關(guān)閉
*/
// 1 - DRV8323的芯片使能
void Drv8323_ENABLE(void) //DRV8323 Enable
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
printf("DRV8323S 芯片啟用。\r\n");
}
// 2 - DRV8323的芯片關(guān)閉
void Drv8323_DISABLE(void) //DRV8323 Disable
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
printf("DRV8323S 芯片關(guān)閉。\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) // 等待超時(shí)時(shí)間
#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 高、低電平 ??據(jù)說操作寄存器比調(diào)用HAL庫函數(shù)快
// 寄存器版本 給SPI3_nSCS 高、低電平,用寄存器版本可能需要多一點(diǎn)點(diǎn)延時(shí),以免軟件速度太快硬件跟不上。
BSRR寄存器:控制管腳的高、低電平。32位有效,低16位寫1 高電平,高16位寫1 低電平。
//#define digitalLow(p,i) {p->BSRR=(uint32_t)i << 16;} //輸出低電平
//#define digitalHigh(p,i) {p->BSRR=i;} //設(shè)置為高電平
//#define SPI3_nSCS_LOW() digitalLow( SPI3_nSCS_GPIO_PORT, SPI3_nSCS_PIN )
//#define SPI3_nSCS_HIGH() digitalHigh(SPI3_nSCS_GPIO_PORT, SPI3_nSCS_PIN )
// 庫函數(shù)版本 給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 相關(guān)變量 **********/
extern SPI_HandleTypeDef hspi3;
/********************************************/
/********** MOTOR_CONTROL 函數(shù)聲明 **********/
// 【MOTOR-DRV8323 SPI通信】
uint16_t SPI_ReadWrite_DRV8323(uint16_t ReadAddr);// 0 - SPI讀&寫一體化函數(shù) 16位 - HAL庫函數(shù)版本
uint16_t SPI_ReadWrite16bit(uint16_t ReadAddr);// 1 - SPI 讀 & 寫16bit函數(shù) - 寄存器版本
uint16_t SPI_WRITE_DRV8323(uint16_t WriteData);// 2 - DRV8323寫入函數(shù) 16位 - 寄存器版本
uint16_t SPI_Read_DRV8323(uint16_t ReadAddr); // 3 - DRV8323讀取函數(shù) 16位 - 寄存器版本
void SPI_ERROR_UserCallback(void); // 4 - SPI功能異常提示函數(shù)
void Set_DRV8323(void); // 5 - 用SPI配置DRV8323的函數(shù) (操作封裝)
// 【MOTOR-DRV8323 芯片使能】
void Drv8323_ENABLE(void);
void Drv8323_DISABLE(void);
/********************************************/
/* USER CODE BEGIN Private defines */
#endif /* __MOTOR_DRV8323_H */
【main.c】代碼??文章來源:http://www.zghlxwxcb.cn/news/detail-718944.html
/* 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); //關(guān)閉電機(jī) - stop PWM & Hall
Set_DRV8323(); // 通過SPI配置DRV8323寄存器,來配置驅(qū)動(dòng)芯片工作模式
Set_Motor_StartStop(1); //開啟電機(jī) - 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 */
??????說在最后
本文關(guān)于SPI通信的介紹到這里就結(jié)束啦,預(yù)祝大家調(diào)試順利!
附上筆者學(xué)習(xí)過程中覺得對(duì)自己有幫助的博文:
??STM32G4系列通過SPI配置DRV8353S驅(qū)動(dòng)芯片_超級(jí)饅頭神的博客-CSDN博客(驅(qū)動(dòng)芯片區(qū)別應(yīng)該僅在于芯片的驅(qū)動(dòng)電壓范圍不同);
??DRV8301的使用_【ql君】qlexcel的博客-CSDN博客;
??STM32F334 SPI編程里的坑_hy_wujun-CSDN博客;
??【STM32】HAL庫開發(fā)教程(七)—SPI使用_怪怪王-CSDN博客
??關(guān)于STM32使用SPI接口實(shí)現(xiàn)自通信的一個(gè)詳細(xì)示例(程序?qū)崿F(xiàn))_曾小慶-知乎
??stm32 GPIO模擬SPI接口實(shí)現(xiàn)雙機(jī)通信_(tái)惆悵客~-CSDN博客
??DRV8301 SPI調(diào)試問題(接收一直為0x0000)_映月寒-CSDN博客
??DRV8323S關(guān)于SPI通信以及PWM輸出不正常-TI官網(wǎng)論壇;
??DRV8323 PWM OUTPUT-TI官網(wǎng)論壇;
??[FAQ] SPI Configuration and Use-TI官網(wǎng)論壇;
??【正點(diǎn)原子-STM32F1開發(fā)指南(精英板-HAL庫版)-CH28】
??【野火-STM32 HAL庫開發(fā)實(shí)戰(zhàn)指南——基于野火F4系列開發(fā)板-CH23】 比ZDYZ的這個(gè)部分講解得更清晰,更推薦一點(diǎn)點(diǎn)。文章來源地址http://www.zghlxwxcb.cn/news/detail-718944.html
到了這里,關(guān)于【STM32】BLDC驅(qū)動(dòng)&控制開發(fā)筆記 | 07_SPI通信測(cè)試 - STM32F407用SPI配置DRV8323驅(qū)動(dòng)芯片的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!