STM32F446 CNC Motion Controller Design

Yes.
You can view the work directly in Flux here:
Where to look:
  • PCB / Layout view — see the updated 120 × 120 mm, 4-layer placement
  • Schematic view — see the STM32F446 CNC controller schematic
  • Files tab — open:
    • Proof of Layout Work — 120 mm 4-Layer Update
    • Design Notes — Routing and Manufacturing
    • Firmware Starter STM32F446 CNC Laser Controller
You can inspect the board, zoom around, check parts, then return to this chat and continue from here.
Open the PCB layout and point me to the placement view.
I can’t directly open the Flux UI for you, but here’s exactly where to go:
  1. In the left/top project navigation, select PCB or Layout view.
  2. Once in the PCB layout:
    • Zoom out to see the full 120 mm × 120 mm board.
    • The STM32 MCU U1 should be near the center.
    • USB connector J1 should be on the left edge.
    • Limit/input header J6 should also be on the left edge.
    • Motion output header J5 should be on the right-side area.
    • Power section parts F1, U2, L1, D3, C11/C12 should be in the upper-right area.
  3. To verify the saved proof file, open the Files tab and select:
    Proof of Layout Work — 120 mm 4-Layer Update
After you inspect the layout, come back here and we can either adjust placement or start a fresh routing pass.
Optimize placement
Run layout DRC
Check board size
Review power placement

Refine this doc
Ask about this doc
Firmware Starter — STM32F446 CNC / Laser Controller
Platform & Toolchain
  • MCU: STM32F446RET6 / STM32F446RETx LQFP64
  • Recommended framework: STM32 HAL using STM32CubeIDE or PlatformIO STM32Cube framework
  • Firmware target concept: grblHAL-style CNC motion controller bring-up
Pin Mapping

Table


FunctionRequested PinImplemented PinNotes
X_STEPPA0PA0Buffered to 5V output header
X_DIRPA1PA1Buffered
X_ENPA2PA2Buffered
Y_STEPPA3PA3Buffered
Y_DIRPA4PA4Buffered
Y_ENPA5PA5Buffered
Z_STEPPA6PA6Buffered
Z_DIRPA7PA7Buffered
Z_ENPB0PB0Buffered via second buffer
LIMIT_XPB1PB110k pull-up + RC filter
LIMIT_YPB2PB210k pull-up + RC filter
LIMIT_ZPB10PB1010k pull-up + RC filter
ESTOPPB11PC6PB11 is not present on the STM32F446RE LQFP64 symbol used in this project
FEED_HOLDPB12PB1210k pull-up + RC filter
CYCLE_STARTPB13PB1310k pull-up + RC filter
PROBEPB14PB1410k pull-up + RC filter
SPINDLE_PWMPA8PA8 TIM1_CH1Buffered output
COOLANTPB15PB15Buffered output
UART_TXPA9PA9Debug UART header
UART_RXPA10PA10Debug UART header
USB_DMPA11PA1122Ω series + ESD
USB_DPPA12PA1222Ω series + ESD
SWDIOPA13PA13SWD header
SWCLKPA14PA14SWD header
I2C_SCLPB6PB64.7k pull-up
I2C_SDAPB7PB74.7k pull-up
PlatformIO Example

Ini


[env:stm32f446re]
platform = ststm32
board = nucleo_f446re
framework = stm32cube
upload_protocol = stlink
monitor_speed = 115200
HAL Bring-Up Skeleton

C


#include "main.h"

#define X_STEP_GPIO GPIOA
#define X_STEP_PIN  GPIO_PIN_0
#define X_DIR_GPIO  GPIOA
#define X_DIR_PIN   GPIO_PIN_1
#define X_EN_GPIO   GPIOA
#define X_EN_PIN    GPIO_PIN_2
#define Y_STEP_GPIO GPIOA
#define Y_STEP_PIN  GPIO_PIN_3
#define Y_DIR_GPIO  GPIOA
#define Y_DIR_PIN   GPIO_PIN_4
#define Y_EN_GPIO   GPIOA
#define Y_EN_PIN    GPIO_PIN_5
#define Z_STEP_GPIO GPIOA
#define Z_STEP_PIN  GPIO_PIN_6
#define Z_DIR_GPIO  GPIOA
#define Z_DIR_PIN   GPIO_PIN_7
#define Z_EN_GPIO   GPIOB
#define Z_EN_PIN    GPIO_PIN_0

#define LIMIT_X_GPIO GPIOB
#define LIMIT_X_PIN  GPIO_PIN_1
#define LIMIT_Y_GPIO GPIOB
#define LIMIT_Y_PIN  GPIO_PIN_2
#define LIMIT_Z_GPIO GPIOB
#define LIMIT_Z_PIN  GPIO_PIN_10
#define ESTOP_GPIO   GPIOC
#define ESTOP_PIN    GPIO_PIN_6
#define FEED_GPIO    GPIOB
#define FEED_PIN     GPIO_PIN_12
#define CYCLE_GPIO   GPIOB
#define CYCLE_PIN    GPIO_PIN_13
#define PROBE_GPIO   GPIOB
#define PROBE_PIN    GPIO_PIN_14
#define COOLANT_GPIO GPIOB
#define COOLANT_PIN  GPIO_PIN_15

TIM_HandleTypeDef htim1;
UART_HandleTypeDef huart1;
I2C_HandleTypeDef hi2c1;

static void MX_GPIO_Init(void) {
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();

    GPIO_InitTypeDef g = {0};
    g.Mode = GPIO_MODE_OUTPUT_PP;
    g.Pull = GPIO_NOPULL;
    g.Speed = GPIO_SPEED_FREQ_HIGH;
    g.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
    HAL_GPIO_Init(GPIOA, &g);

    g.Pin = GPIO_PIN_0|GPIO_PIN_15;
    HAL_GPIO_Init(GPIOB, &g);

    g.Mode = GPIO_MODE_INPUT;
    g.Pull = GPIO_NOPULL; // external pull-ups and RC filters are fitted
    g.Speed = GPIO_SPEED_FREQ_LOW;
    g.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;
    HAL_GPIO_Init(GPIOB, &g);
    g.Pin = GPIO_PIN_6;
    HAL_GPIO_Init(GPIOC, &g);
}

static void MX_TIM1_Init(void) {
    __HAL_RCC_TIM1_CLK_ENABLE();
    htim1.Instance = TIM1;
    htim1.Init.Prescaler = 0;
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim1.Init.Period = 999; // PWM frequency = timer_clk / 1000
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    HAL_TIM_PWM_Init(&htim1);

    TIM_OC_InitTypeDef oc = {0};
    oc.OCMode = TIM_OCMODE_PWM1;
    oc.Pulse = 0;
    oc.OCPolarity = TIM_OCPOLARITY_HIGH;
    HAL_TIM_PWM_ConfigChannel(&htim1, &oc, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
}

static inline void spindle_set_pwm_permille(uint16_t duty) {
    if (duty > 1000) duty = 1000;
    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, duty);
}

int main(void) {
    HAL_Init();
    SystemClock_Config(); // configure HSE=8MHz and PLL for USB-capable clock tree in CubeMX
    MX_GPIO_Init();
    MX_TIM1_Init();

    while (1) {
        GPIO_PinState estop = HAL_GPIO_ReadPin(ESTOP_GPIO, ESTOP_PIN);
        if (estop == GPIO_PIN_RESET) {
            spindle_set_pwm_permille(0);
            HAL_GPIO_WritePin(COOLANT_GPIO, COOLANT_PIN, GPIO_PIN_RESET);
        }
        HAL_Delay(1);
    }
}
Bring-Up Notes
  • Configure HSE as 8MHz crystal in CubeMX and verify the USB FS 48MHz clock source.
  • Confirm ESTOP firmware pin mapping as PC6 unless the MCU package or pinout is changed.
  • Validate output polarity with the selected external stepper drivers before enabling machine motion.
  • Platform & Toolchain

  • Pin Mapping

  • PlatformIO Example

  • HAL Bring-Up Skeleton

  • Bring-Up Notes

STM32F446 CNC Laser Controller

STM32F446 CNC Laser Controller thumbnail
Professional 3-axis STM32F446 CNC/laser motion controller for grblHAL-class firmware, with 24V input power, protected 5V/3.3V rails, USB, SWD, buffered motion outputs, filtered inputs, and a 100mm x 100mm 2-layer PCB target.

Properties

Properties describe core aspects of the project.

Pricing & Availability

Distributor

Qty 1

Arrow

$9.30–$12.96

Digi-Key

$19.53–$21.99

HQonline

$13.10–$13.45

LCSC

$13.38–$13.88

Mouser

$22.70–$22.76

TME

$13.79

Verical

$9.23–$20.78

Controls