51单片机正反转可控的直流电机设计 C程序、proteus仿真、报告! 支持按键设置直流电机的正转、反转、急停。

这个暑假折腾了个好玩的——用51单片机做个能正反转带急停的直流电机控制器。别看功能简单,里面按键消抖、PWM调速、电机驱动这些坑一个没少踩,现在把核心代码和仿真模型整理出来,给想入门的兄弟参考参考。

先上硬件框图:STC89C52芯片做主控,L293D电机驱动模块负责功率放大,三个轻触按键接在P3.2-P3.4,电机接在L293D的输出端。Proteus里连线时注意给电机两端反向并联个1N4007续流二极管,不然关断瞬间的反向电动势可能烧管子。

核心控制代码其实就两大块——按键扫描和电机驱动。先看按键处理部分:

sbit MOTOR_A = P1^0; // 电机控制端A
sbit MOTOR_B = P1^1; // 电机控制端B

void Key_Scan(){
    static uint8_t key_up = 1;
    if((KEY_FORWARD==0 || KEY_REVERSE==0 || KEY_STOP==0) && key_up){
        DelayMs(10); // 消抖延时
        key_up = 0;
        if(KEY_FORWARD == 0) Motor_Ctrl(FORWARD);
        else if(KEY_REVERSE == 0) Motor_Ctrl(REVERSE);
        else if(KEY_STOP == 0) Motor_Ctrl(STOP);
    }else if(KEY_FORWARD && KEY_REVERSE && KEY_STOP){
        key_up = 1; 
    }
}

这个状态机结构的按键扫描比直接if判断可靠得多。注意static变量key_up用来记录按键释放状态,配合10ms延时消抖,实测在proteus里能稳定识别动作。遇到按键失灵别急着怀疑硬件,先检查引脚定义有没有和仿真图对应上。

电机驱动函数才是重头戏,L293D的逻辑控制其实很简单:

void Motor_Ctrl(uint8_t mode){
    switch(mode){
        case FORWARD:
            MOTOR_A = 1;
            MOTOR_B = 0; // 正转
            break;
        case REVERSE:
            MOTOR_A = 0;
            MOTOR_B = 1; // 反转
            break;
        default:
            MOTOR_A = 0; // 急停
            MOTOR_B = 0;
    }
    // 启动PWM调速
    PWM_Init(); 
}

重点在于正反转时A、B两个控制端的电平组合。有个坑要注意——急停时如果直接断开使能端,电机可能因为惯性继续转动,所以这里采用短路制动(两个输出端同时置低),实测制动效果明显比单纯断电好。

51单片机正反转可控的直流电机设计 C程序、proteus仿真、报告! 支持按键设置直流电机的正转、反转、急停。

PWM调速用的是定时器0中断实现占空比调节:

void Timer0_Init(){
    TMOD |= 0x01; // 16位定时器模式
    TH0 = 0xFC; // 1ms定时
    TL0 = 0x18;
    ET0 = 1;
    EA = 1;
    TR0 = 1;
}

void Timer0_ISR() interrupt 1{
    static uint8_t pwm_count = 0;
    pwm_count++;
    if(pwm_count >= 100) pwm_count = 0;
    
    if(pwm_count < duty){ // duty是占空比变量
        ENA = 1; // 使能端
    }else{
        ENA = 0;
    }
    // 重装初值
    TH0 = 0xFC;
    TL0 = 0x18; 
}

这里把PWM周期设为100级可调,通过修改duty变量(0-100)就能改变转速。调试时发现电机启动瞬间电流很大,后来在程序初始化时加了软启动——让占空比从30%逐渐增加到设定值,解决了电机抖动问题。

Proteus仿真有个小技巧:在L293D的VSS(逻辑电源)和VS(电机电源)之间记得接个10uF的电容,否则仿真时可能出现驱动芯片逻辑紊乱。仿真效果和实物基本一致,急停时电机大约0.5秒内就能完全停止。

最后说下硬件保护:实际做实物时一定要在单片机IO口和L293D之间加光耦隔离,我在实验室烧过两个芯片才明白这个道理。另外程序里可以加个堵转检测,当电流持续超过阈值时自动急停,这个功能正在完善中。

完整代码和仿真文件已上传Github,需要报告模板的兄弟可以私信。下期准备做无线遥控版本,打算用NRF24L01实现,有兴趣的可以持续关注。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐