MENU

基于51单片机的直流电机PWM控制系统

• October 26, 2020 • 工业控制

设计思路

直流电机PWM控制系统的主要功能包括:直流电机的加减速、电机的正反转以及电机的启停,并且可以调整电机的转速,还可以方便的读出电机转速的大小,能够很方便的实现电机的智能控制。该直流电机系统由以下电路模块组成:

组成模块

振荡器和时钟电路:这部分电路主要由80C51单片机和一些电容、晶振组成。
设计输入部分:这一模块主要是利用6个独立的按键来实现。
设计控制部分:主要由80C51单片机的外部中断扩展电路组成。
设计显示部分:由LCD1602液晶显示模块组成; 
直流电机PWM控制实现部分:主要由一些二极管、电机和L298直流电机驱动模块组成。

基本原理 

当按键扫描到有输入信号时,通过80C51单片机产生脉宽可调的脉冲信号并输入到L298驱动芯片来控制直流电机工作,从而实现电机的调速功能。再通过分析电机运转发出的脉冲周期计算出电机的速度,送给LCD1602显示。

总体设计框图

方案说明:直流电机PWM调速系统以AT89C51单片机为控制核心,由命令输入模块、LCD显示模块及电机驱动模块组成。单片机在程序控制下,定时不断给直流电机驱动芯片发送PWM波形,L298完成电机正,反转控制;同时单片机不停的将从电机发出的脉冲处理后,送到LCD显示模块去显示转速。整个系统的组成原理图如下图所示。

1

系统原理图

2

程序设计

整个程序由主程序以及9个子程序外加两个中断服务子程序组成。这9个子程序分别是:按键扫描、定时器初始化、LCD初始化、按键消抖、欢迎界面延时、LCD写数据、LCD写命令、LCD速度显示、LCD欢迎界面显示。

按键扫描:用来判断按钮是否被按下,从而实现相关功能。

void BtnSca() 
{
    if ( start == 0 || btnforward == 0 ) 
    {
        backward    = 0;
        forward        = 1;
        Flag        = 1;
        TR0        = 1;
    } else if ( stop == 0 ) 
    {
        backward    = 1;
        forward        = 1;
        Flag        = 0;
        TR0        = 0;
    } else if ( btnbackward == 0 && Flag == 1 ) 
    {
        backward    = 1;
        forward        = 0;
        Flag        = 0;
        /* TR0=1; */
    }
    if ( speedup == 0 ) 
    {
        BtnDelay( 10 );
        /* 消抖 */
        if ( speedup == 0 ) 
        {
            Hcount++;
            if ( Hcount >= Lcount ) 
            {
                Hcount = 16;
            }
        }
        while ( !speedup )
                    ;
        /* 等待键松开 */
    }
    if ( speeddown == 0 ) 
    {
        BtnDelay( 10 );
        /* 消抖 */
        if ( speeddown == 0 ) 
        {
            Hcount--;
            if ( Hcount <= 0 ) 
            {
                Hcount = 0;
            }
        }
        while ( !speeddown );
        /* 等待键松开 */
    }
}

定时器初始化:初始化定时器用,设定相关参数

/****************定时器初始化*****************/
void TInit()
{
    TMOD    = 0x11;                       /* 设置定时器T工作于方式 */
    TH0    = setTHTL / 256;
    TL0    = setTHTL % 256;
    ET0    = 1;                            /* 开定时器中断 */
    EA    = 1;                            /* 开总中断 */

    TH1    = (65536 - 50000) / 256;        /* TH1装初值为65536-50000=15536,即定时50000us,相当于50毫秒。 */
    TL1    = (65536 - 50000) % 256;        /* TL1装初值为65536-50000=15536 */
    EX1    = 1;                            /* 开外部中断1允许 */
    IT1    = 1;                            /* 设置外部中断0下降触发中断 */
    ET1    = 1;                            /* 打开定时器1中断允许 */
    TR1    = 1;                            /* 开定时器1 */

}

LCD初始化:初始化LCD1602面板

void lcd_init()
{
    writecmd( 0x38 );       /* 设置16*2显示模式 */
    writecmd( 0x0c );       /* 开显示 */
    writecmd( 0x01 );       /* 清屏 */
    writecmd( 0x06 );       /* 地址指针+1 */
}

按键消抖:用来消除按键的抖动,防止输入错误信号
/****************延时消抖**********************/
void BtnDelay( i )
{
    for ( j = i; j > 0; j-- )
        for ( k = 125; k > 0; k-- )
            ;
}

欢迎界面延时:起到显示欢迎界面时长的作用,延时到达就擦除

/****************首屏欢迎延时****************/
void delay( void )
{
    unsigned char a, b, c;
    for ( c = 167; c > 0; c-- )
        for ( b = 171; b > 0; b-- )
            for ( a = 1; a > 0; a-- )
                ;
}

LCD写数据:写数据到LCD1602

/* 写数据 */
void writedat( unsigned char wd )
{
    busy();
    RS    = 1;
    RW    = 0;
    P2    = wd;
    EN    = 1;
    EN    = 0;
}

LCD写命令:通过1602的一些端口操作1602相关设置

/* 写命令 */
void writecmd( unsigned char wr )
{
    busy();
    RS    = 0;
    RW    = 0;
    P2    = wr;
    EN    = 1;
    EN    = 0;
}

LCD速度显示:通传入参数,将参数显示在1602上

/* 显示函数 */
void display( unsigned int rate )
{
    unsigned char wan, qian, bai, shi, ge;
    wan    = rate / 10000;
    qian    = rate / 1000 % 10;
    bai    = rate / 100 % 10;
    shi    = rate / 10 % 10;
    ge    = rate % 10;
    v    = 0;
    writecmd( 0x80 | 0x00 );
    while ( dis3[v] != '\0' )
    {
        writedat( dis3[v] );
        v++;
    }
    ;
    writecmd( 0x80 | 0x40 );        /* 显示地址 */
    writedat( '0' + wan );          /* 将字符常量v写入LCD */
    writedat( '0' + qian );
    writedat( '0' + bai );
    writedat( '0' + shi );
    writedat( '0' + ge );
    v = 0;
    while ( dis4[v] != '\0' )
    {
        writedat( dis4[v] );
        v++;
    }
    ;
}

LCD欢迎界面显示:通传入参数,将参数显示在1602上

/****************首屏欢迎词****************/
void displayWelcome()
{
    writecmd( 0x80 | 0x00 );        /* 显示地址 */
    while ( dis1[v] != '\0' )
    {
        writedat( dis1[v] );
        v++;
    }
    v = 0;
    writecmd( 0x80 | 0x40 );        /* 显示地址 */
    while ( dis2[v] != '\0' )
    {
        writedat( dis2[v] );
        v++;
    }
}

附件下载

包括Proteus仿真以及Keil5的工程文件。
普通下载

原文链接:https://blog.zwying.com/archives/38.html

- - - The END - - -
  • 文章标题:基于51单片机的直流电机PWM控制系统
  • 文章链接:http://blog.uiuweb.cn/index.php/archives/12213.html
  • 版权所有:本文版权归 刘一彪 所有,转载请注明出处!除特殊注明外 (如有侵权,请 点此联系我 )
  • Archives QR Code Tip
    QR Code for this page
    Tipping QR Code
    Leave a Comment

    已有 1 条评论
    1. LCD 速度显示:通传入参数,将参数显示在 1602 上