直流电机控制(PWM)+普中51单片机+江科大自化协

1 实验现象

 2 实验原理

通过按键来控制PWM占空比实现对直流电机的调速,数码管则显示当前速度挡位信息。

(1)直流电机的控制是通过设置PWM波的占空比来控制直流电机的转速,占空比越大,转速越快,越小转速越低;

(2)单片机的I/O口是不能直接驱动电机的,所以还需要用一个驱动芯片。如 LG9110、CMO825、L298 等。驱动芯片可以将单片机I/O输出信号放大,这样电机中流过的电流足够大,电机才能转起来。

(3)直流电机只有两根电源线,直流电机的两根电源线是不分正负极的。假设两根电源线代号分别为A、B。 当A线接正极,B线接负极时,电机正转(反转);那么当B线接正极,A线接负极时,电机反转(正转)。

 

 3 参考程序

3.1 主程序

#include <REGX52.H>
#include "delayms.h"
#include "key.h"
#include "Nixie.h"
#include "timer0.h"

sbit Motor=P1^3;    //直流电机,高电平驱动

unsigned char Counter,Compare;    //计数值和比较值,用于输出PWM
unsigned char KeyNum,Speed;

void main()
{
    timer0_init();
    while(1)
    {
        KeyNum=key();
        if(KeyNum==1)
        {
            Speed++;
            Speed%=4;    //计数值计算范围为0-3
            if(Speed==0) {Compare=0;}
            if(Speed==1) {Compare=50;}
            if(Speed==2) {Compare=75;}
            if(Speed==3) {Compare=100;}
        }
        Nixie(1,Speed);
    }
}

void Timer0_Routine() interrupt 1
{
    TL0 = 0xAE;        //设置定时初始值,100us,@11.0592MHz
    TH0 = 0xFB;        //设置定时初始值,100us,@11.0592MHz
    Counter++;
    Counter%=100;    //计数值计算范围为0-99
    if(Counter<Compare)    //计数值小于比较值
    {
        Motor=1;        //高电平驱动,电机转动
    }
    else
    {
        Motor=0;        //电机停止
    }
}

3.2 延时函数

#include <intrins.h>

void delayms(unsigned int xms)        //@11.0592MHz
{
    unsigned char i, j;

    while(xms--)
    {
        _nop_();
        i = 2;
        j = 199;
        do
        {
            while (--j);
        } while (--i);    
    }
}
#ifndef _delayms_h_
#define _delayms_h_

delayms(unsigned int xms);
    
#endif

3.3 按键扫描函数

#include <reg52.h>
#include "delayms.h"

sbit key1 = P3^1;
sbit key2 = P3^0;
sbit key3 = P3^2;
sbit key4 = P3^3;

/**
  * @brief  获取独立按键键码
  * @param  无
  * @retval 按下按键的键码,范围:0~4,无按键按下时返回值为0
  */

unsigned char key()
{
    unsigned char KeyNumber = 0;
    if(key1==0){delayms(20);while(key1==0);delayms(20);KeyNumber=1;}
    if(key2==0){delayms(20);while(key2==0);delayms(20);KeyNumber=2;}
    if(key3==0){delayms(20);while(key3==0);delayms(20);KeyNumber=3;}
    if(key4==0){delayms(20);while(key4==0);delayms(20);KeyNumber=4;}
    return KeyNumber;
}
#ifndef _key_h_
#define _key_h_

unsigned char key();

#endif

 3.4 数码管扫描函数

#include <REGX52.H>
#include "delayms.h"

sbit HC138_A=P2^2;
sbit HC138_B=P2^3;
sbit HC138_C=P2^4;

//数码管段码表,0-9
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

/**
  * @brief  数码管显示
  * @param  Location 要显示的位置,范围:1~8
  * @param  Number 要显示的数字,范围:段码表索引范围
  * @retval 无
  */
void Nixie(unsigned char Location,Number)
{
    switch(Location)        //位码输出
    {
        case 1:HC138_C=1;HC138_B=1;HC138_A=1;break;
        case 2:HC138_C=1;HC138_B=1;HC138_A=0;break;
        case 3:HC138_C=1;HC138_B=0;HC138_A=1;break;
        case 4:HC138_C=1;HC138_B=0;HC138_A=0;break;
        case 5:HC138_C=0;HC138_B=1;HC138_A=1;break;
        case 6:HC138_C=0;HC138_B=1;HC138_A=0;break;
        case 7:HC138_C=0;HC138_B=0;HC138_A=1;break;
        case 8:HC138_C=0;HC138_B=0;HC138_A=0;break;
    }
    P0=NixieTable[Number];    //段码输出
    delayms(1);                //显示一段时间
    P0=0x00;                //段码清0,消影
}
#ifndef __NIXIE_H__
#define __NIXIE_H__

void Nixie(unsigned char Location,Number);

#endif

3.5 定时器函数

#include <REGX52.H>

/**
  * @brief  定时器0初始化,100微秒@11.0592MHz
  * @param  无
  * @retval 无
  */
void timer0_init(void)        //100微秒@11.0592MHz
{
    TMOD &= 0xF0;    //设置定时器模式,1111_0000,&,高四位保留,低四位清零
    TMOD |= 0x01;    //设置定时器模式,0000_0001,|,高四位保留,设置模式为T0
    TL0 = 0xAE;        //设置定时初始值,100us,@11.0592MHz
    TH0 = 0xFB;        //设置定时初始值,100us,@11.0592MHz
    TF0 = 0;        //清除TF0标志
    TR0 = 1;        //定时器0开始计时
    ET0=1;            //打开定时器T0中断开关
    EA=1;            //打开中断系统总开关
    PT0=0;            //设置T0中断优先级,低
}


/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
    static unsigned int T0Count;
    TL0 = 0x66;        //设置定时初值,1毫秒@11.0592MHz
    TH0 = 0xFC;        //设置定时初值,1毫秒@11.0592MHz
    T0Count++;
    if(T0Count>=1000)
    {
        T0Count=0;
        
    }
}
*/
#ifndef _timer0_h_
#define _timer0_h_

void timer0_init(void);
    
#endif

4 参考资料

posted @ 2023-01-12 21:31  豌豆茶  阅读(1085)  评论(0编辑  收藏  举报