TJHXPCB
Published © CC BY-ND

Custom BLDC Motor Controller PCB: Design to Assembly

How we designed and assembled a compact BLDC motor controller PCB — covering schematic, layout, DFM, and turnkey PCBA in Tianjin, China.

AdvancedFull instructions providedOver 1 day44
Custom BLDC Motor Controller PCB: Design to Assembly

Things used in this project

Story

Read more

Schematics

Schematic

Code

drv8301.c

C Header File
#include "drv8301.h"
#include <stdio.h>   // 

extern SPI_HandleTypeDef hspi3;   // CubeMX  SPI 

// ====================  SPI  ====================
static uint16_t drv8301_transfer(uint16_t txdata)
{
    uint8_t tx[2] = {(txdata >> 8) & 0xFF, txdata & 0xFF};
    uint8_t rx[2] = {0};

    HAL_GPIO_WritePin(DRV8301_CS_GPIO_Port, DRV8301_CS_Pin, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(&hspi3, tx, rx, 2, HAL_MAX_DELAY);
    HAL_GPIO_WritePin(DRV8301_CS_GPIO_Port, DRV8301_CS_Pin, GPIO_PIN_SET);

    return (rx[0] << 8) | rx[1];
}

// ====================  ====================
uint16_t DRV8301_Read(uint8_t addr)
{
    uint16_t cmd = (1 << 15) | ((addr & 0x0F) << 11);   // Read bit + 
    drv8301_transfer(cmd);          // 
    return drv8301_transfer(0x0000); // 
}

// ====================  ====================
void DRV8301_Write(uint8_t addr, uint16_t data)
{
    uint16_t cmd = ((addr & 0x0F) << 11) | (data & 0x07FF);   // Write bit=0
    drv8301_transfer(cmd);
}

// ====================  DRV8301 ====================
void DRV8301_Init(void)
{
    // 
    DRV8301_DisableGate();
    HAL_Delay(10);
    DRV8301_EnableGate();
    HAL_Delay(10);

    //  Control Register 16x PWM +  + 10
    DRV8301_Write(DRV_REG_CTRL1, PWM_MODE_6X | OCP_RETRY | GAIN_10);

    //  Control Register 2 400ns
    DRV8301_Write(DRV_REG_CTRL2, DEADTIME_400NS);

    printf("DRV8301 \r\n");
}

// ====================  ====================
uint16_t DRV8301_ReadStatus1(void) { return DRV8301_Read(DRV_REG_STATUS1); }
uint16_t DRV8301_ReadStatus2(void) { return DRV8301_Read(DRV_REG_STATUS2); }

// ==================== / ====================
void DRV8301_EnableGate(void)
{
    HAL_GPIO_WritePin(DRV8301_EN_GPIO_Port, DRV8301_EN_Pin, GPIO_PIN_SET);
}
void DRV8301_DisableGate(void)
{
    HAL_GPIO_WritePin(DRV8301_EN_GPIO_Port, DRV8301_EN_Pin, GPIO_PIN_RESET);
}

// ====================  ====================
uint8_t DRV8301_CheckFault(void)
{
    return HAL_GPIO_ReadPin(DRV8301_FAULT_GPIO_Port, DRV8301_FAULT_Pin) == GPIO_PIN_RESET;
}

drv8301.h

C Header File
#ifndef __DRV8301_H
#define __DRV8301_H

#include "stm32f4xx_hal.h"

// ====================  ====================
#define DRV8301_CS_GPIO_Port   GPIOC
#define DRV8301_CS_Pin         GPIO_PIN_13
#define DRV8301_EN_GPIO_Port   GPIOB
#define DRV8301_EN_Pin         GPIO_PIN_12
#define DRV8301_FAULT_GPIO_Port GPIOD
#define DRV8301_FAULT_Pin      GPIO_PIN_2

// ====================  ====================
#define DRV_REG_STATUS1   0x00
#define DRV_REG_STATUS2   0x01
#define DRV_REG_CTRL1     0x02
#define DRV_REG_CTRL2     0x03

// ==================== CTRL1  ====================
#define PWM_MODE_6X       (1 << 5)      // 6x PWM 
#define PWM_MODE_3X       (0 << 5)
#define OCP_RETRY         (0 << 10)     // 
#define OCP_LATCH         (1 << 10)
#define GAIN_10           (0 << 0)      //  10V/V
#define GAIN_20           (1 << 0)
#define GAIN_40           (2 << 0)

// ==================== CTRL2  ====================
#define DEADTIME_100NS    (0x0 << 8)    // 
#define DEADTIME_200NS    (0x1 << 8)
#define DEADTIME_400NS    (0x2 << 8)    // 

// 
void DRV8301_Init(void);
uint16_t DRV8301_Read(uint8_t addr);
void DRV8301_Write(uint8_t addr, uint16_t data);
uint16_t DRV8301_ReadStatus1(void);
uint16_t DRV8301_ReadStatus2(void);
void DRV8301_EnableGate(void);
void DRV8301_DisableGate(void);
uint8_t DRV8301_CheckFault(void);

#endif

main.c

C Header File
#include "drv8301.h"
extern TIM_HandleTypeDef htim1;   // CubeMX  TIM1

void TIM1_PWM_Init(void)
{
    // CubeMX  PWM
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1N);  // 
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2N);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3N);
}

int main(void)
{
    HAL_Init();
    SystemClock_Config();   // CubeMX 
    MX_GPIO_Init();
    MX_SPI3_Init();
    MX_TIM1_Init();

    printf("STM32F4 + DRV8301 \r\n");

    DRV8301_Init();         //  DRV8301
    TIM1_PWM_Init();        //  6  PWM

    //  50%  FOC
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 500);
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 500);
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 500);

    while (1)
    {
        if (DRV8301_CheckFault()) {
            printf("FAULT! SR1=0x%04X SR2=0x%04X\r\n",
                   DRV8301_ReadStatus1(), DRV8301_ReadStatus2());
            DRV8301_DisableGate();   // 
        } else {
            printf("...\r\n");
        }
        HAL_Delay(500);
    }
}

Credits

TJHXPCB
2 projects • 0 followers
PCB design and assembly manufacturer based in Tianjin, China. One-stop services: PCB assembly, electronic enclosure,, motor controllers.

Comments