步进电机控制+普中51单片机+普中官方

1 实验现象

  通过ULN2003驱动模块控制28BYJ48步进电机运行方向及速度,当按下KEY1键可调节电机旋转方向;当按下KEY2键,电机加速(5档);当按下KEY3键,电机减速(5档);同时将电机转速档位显示在数码管上。

2 实验原理

(1)步进电机必须加驱动才可以运转,驱动信号必须为脉冲信号,没有脉冲的时候,步进电机禁止,加入适当的脉冲信号,就会以一定的角度(成为步角)转动。转动的速度和脉冲的频率成正比。

(2)步进电机具有瞬间启动和急速停止的优越特性;

(3)改变脉冲的顺序,可以方便的改变转动的方向。

3 系统框图

 

4 硬件设计

    见《普中-2&普中-3&普中-4开发板原理图》:独立按键模块、单片机核心、动态数码管模块(包含74HC138)、五线四相步进电机模块。

5 软件设计

5.1 主函数

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

// 定义步进电机速度,值越小,速度越快
#define MAX 1         //延时时间,脉冲周期
#define MIN 5        //延时时间,脉冲周期

unsigned char key_num=0;
unsigned char dir=0;    //默认逆时针方向
unsigned char step=0;
unsigned char speed=5;

void main()
{
    while(1)
    {
        key_num=key();
        if(key_num==1)                //换向
        {
            dir=!dir;
        }
        else if(key_num==2)            //加速,延时speed越小,速度越快
        {
            if(speed>MAX) speed-=1;
        }
        else if(key_num==3)            //减速,延时speed越大,速度越慢
        {
            if(speed<MIN) speed+=1;
        }
        Nixie(1,6-speed);            //显示数值越大,转速越快
        stepmotor_send_pulse(step++,dir);    
        if(step>8) step=0;
        delayms(speed);
    }
}

 5.2 步进电机控制函数

#include <REGX52.H>

//定义ULN2003控制步进电机管脚
sbit IN_D=P1^0;
sbit IN_C=P1^1;
sbit IN_B=P1^2;
sbit IN_A=P1^3;

/**
  * @brief   输出一个数据给ULN2003从而实现向步进电机发送一个脉冲
  * @param   step 指定步进序号,可选值0~7
  * @param   dir:方向选择,1:顺时针,0:逆时针
  * @retval  无
  */
void stepmotor_send_pulse(unsigned char step,dir)
{
    unsigned char temp;
    if(dir==0) temp=7-step;    //如果为逆时针旋转,调换节拍信号
    else temp=step;
    switch(temp)    //8个节拍控制:A->AB->B->BC->C->CD->D->DA
    {
        case 0: IN_A=0;IN_B=0;IN_C=0;IN_D=1;break;
        case 1: IN_A=0;IN_B=0;IN_C=1;IN_D=1;break;
        case 2: IN_A=0;IN_B=0;IN_C=1;IN_D=0;break;
        case 3: IN_A=0;IN_B=1;IN_C=1;IN_D=0;break;
                    
        case 4: IN_A=0;IN_B=1;IN_C=0;IN_D=0;break;
        case 5: IN_A=1;IN_B=1;IN_C=0;IN_D=0;break;
        case 6: IN_A=1;IN_B=0;IN_C=0;IN_D=0;break;
        case 7: IN_A=1;IN_B=0;IN_C=0;IN_D=1;break;
        default:IN_A=0;IN_B=0;IN_C=0;IN_D=0;break;//停止相序    
    }
}
#ifndef _stepmotor_h_
#define _stepmotor_h_

void stepmotor_send_pulse(unsigned char step,dir);

#endif

5.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

5.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

5.5 延时函数

#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

6 参考资料

posted @ 2023-01-14 11:08  豌豆茶  阅读(865)  评论(0编辑  收藏  举报