Overview
This project implements stepper motor control using an STC89C52RC microcontroller (running at 11.0592MHz crystal frequency), interfaced with a TB6600 stepper driver to manage a 42/57 series stepper motor. The system supports both position control (specifying number of steps) and speed regulation (adjustable pulse frequency). Key features include:
- Pulse Generation: Precise pulses generated via timer interrupts (frequency range: 1Hz–10kHz, error <1%);
- Direction Control: Digital output on an I/O pin to switch motor rotation direction;
- Enable Functionality: Low-level enable signal activates the driver, high-level disables it;
- Microstepping Support: Compatible with 2/4/8/16 microstep settings via hardware DIP switches on the TB6600.
Applications: Suitable for devices requiring precise motion control such as 3D printers, CNC routers, and robotic arms.
Hardware Design
2.1 Component Selection
| Module | Model/Parameters | Description |
|---|---|---|
| **Controller** | STC89C52RC (8-bit, 11.0592MHz) | Generates pulses, controls direction and enable signals, counts steps |
| **Driver Module** | TB6600 (up to 3A/40V, 2/4/8/16 mircosteps) | Amplifies MCU pulses to drive motor windings |
| **Stepper Motor** | 42BYGH40 (1.8°/step, 4-phase, 1.5A rated) | Motion actuator (operates in 4-phase 8-step or 2-phase 4-step modes based on microstepping) |
| **Power Supply** | 24V/3A DC (for motor) + 5V/1A (for MCU) | Separate power supplies to avoid interference (TB6600 requires dedicated 24V supply) |
2.2 Circuit Connections
| Component | 51 MCU Pin (STC89C52RC) | TB6600 Pin | Description |
|---|---|---|---|
| **Pulse Output (PUL)** | P1.0 (Timer0 Output) | PUL+ | Pulse signal (rising edge triggers) |
| **Direction Signal (DIR)** | P1.1 | DIR+ | High = forward, Low = reverse |
| **Enable Signal (EN)** | P1.2 | ENA+ | Low = active, High = inactive |
| **Logic Power** | 5V/GND | VCC/GND | Logic level supply for MCU and driver |
| **Motor Power** | 24V/3A Supply | VCC/GND | Power source for driver and motor |
Software Implementation (Keil C51)
3.1 Development Environment
- IDE: Keil μVision5 with C51 compiler
- Crystal Frequency: 11.0592MHz (ensures accurate timer calculations)
- Control Strategy: Timer0 interrupts generate pulses; main function handles step count, direction, and enable state
3.2 Core Logic
- Pulse Generation: Achieved through Timer0 interrupts. The initial value determines pulse frequency (f = 1/(2×Ttimer));
- Direction Control: Output on P1.1 sets motor rotation direction;
- Enable Control: P1.2 controls driver activation (low enables, high disables);
- Step Counting: Each pulse increments/decrements a counter. When the target is reached, pulse generation halts.
3.3 Source Code
3.3.1 Header Files and Pin Definitions
#include <reg52.h>
#include <intrins.h>
// ==================== Pin Definitions ====================
sbit PUL = P1^0; // Pulse output (connected to TB6600 PUL+)
sbit DIR = P1^1; // Direction control (connected to TB6600 DIR+)
sbit EN = P1^2; // Enable control (connected to TB6600 ENA+, low active)
// ==================== Global Variables ====================
unsigned int pulse_count = 0; // Number of pulses sent
unsigned int target_steps = 0; // Target step count (positive = forward, negative = backward)
unsigned int pulse_freq = 1000; // Pulse frequency in Hz (default 1kHz)
unsigned char motor_dir = 1; // Direction flag: 1 = forward, 0 = backward
bit motor_enable = 1; // Enable status: 1 = enabled, 0 = disabled
3.3.2 Delay Functions (Microsecond/Millisecond)
// Microsecond delay (±1us accuracy, ~1.085us per machine cycle)
void DelayUs(unsigned int us) {
while (us--) {
_nop_(); _nop_(); _nop_(); _nop_(); // 4 NOPs ≈ 3.6us
}
}
// Millisecond delay
void DelayMs(unsigned int ms) {
unsigned int i, j;
for (i=0; i<ms; i++)
for (j=0; j<110; j++); // Approx. 1ms per loop
}
3.3.3 Timer0 Initialization (Pulse Generation)
Purpose: Configure Timer0 in mode 1 (16-bit), compute initial values based on desired frequency, and start interrupt handling.
// Initialize Timer0 for pulse generation at specified frequency
void Timer0_Init(unsigned int freq) {
TMOD |= 0x01; // Mode 1 (16-bit timer)
TH0 = (65536 - (11059200/12)/freq/2) / 256; // High byte of reload value
TL0 = (65536 - (11059200/12)/freq/2) % 256; // Low byte of reload value
ET0 = 1; // Enable Timer0 interrupt
EA = 1; // Enable global interrupts
TR0 = 1; // Start Timer0
}
3.3.4 Timer0 Interrupt Service Routine (Pulse Toggle)
Purpose: Toggle the PUL pin on each interrupt to create a square wave pulse.
// Timer0 ISR for generating pulses
void Timer0_ISR() interrupt 1 {
TH0 = (65536 - (11059200/12)/pulse_freq/2) / 256; // Reload high byte
TL0 = (65536 - (11059200/12)/pulse_freq/2) % 256; // Reload low byte
PUL = ~PUL; // Toggle pulse output
if (motor_enable) { // Only increment if enabled
pulse_count++;
// Stop when target steps reached
if ((motor_dir && pulse_count >= target_steps) ||
(!motor_dir && pulse_count >= -target_steps)) {
TR0 = 0; // Halt Timer0
pulse_count = 0;
}
}
}
3.3.5 Motor Control Functions
// Set motor rotation direction
void Set_Motor_Dir(unsigned char dir) {
motor_dir = dir;
DIR = dir; // Apply direction signal
}
// Enable/disable motor
void Set_Motor_Enable(bit enable) {
motor_enable = enable;
EN = !enable; // TB6600 uses low-active enable
}
// Run motor with specified steps and speed
void Motor_Run(int steps, unsigned int speed) {
target_steps = (steps < 0) ? -steps : steps; // Absolute step count
Set_Motor_Dir(steps > 0); // Determine direction
pulse_freq = speed; // Set new speed (Hz)
pulse_count = 0; // Reset counter
Timer0_Init(pulse_freq); // Start pulse generation
}
3.3.6 Main Function (Test Routine)
void main() {
Set_Motor_Enable(1); // Activate motor
while (1) {
// Test 1: Forward 1000 steps at 2kHz
Motor_Run(1000, 2000);
DelayMs(1000);
// Test 2: Reverse 500 steps at 1.5kHz
Motor_Run(-500, 1500);
DelayMs(1000);
// Test 3: Disable motor
Set_Motor_Enable(0);
DelayMs(1000);
Set_Motor_Enable(1);
}
}
Testing and Validation
- Hardware Setup: Connect all components according to secsion 2.2. Ensure common ground between 24V and 5V supplies.
- Functional Tests:
- Power up and observe that motor rotates correctly during test cycles;
- Use an oscilloscope to verify pulse frequency matches configured values (e.g., 2kHz should yield 0.5ms period).
- Microstepping Verification: Set TB6600 to 16 microstep mode. A full rotation should require 3200 steps (200 steps/revolution × 16).
Conclusion
This implementation demonstrates basic control of a stepper motor using the TB6600 driver with a 51 microcontroller. The core mechanism releis on Timer0 interrupts for precise pulse generation and GPIOs for direction and enable control. Modular functions allow easy integration into multi-axis control systems.