51单片机学习笔记16 小型直流电机和五线四相电机控制
- 一、电机分类
- 二、小型直流电机控制
- 1. 简介
- 2. 驱动芯片ULN2003D
- 3. 代码实现
- dc_motor_utils.c
- main.c
- 三、五线四相步进电机控制
- 1. 步进电机工作原理
- 2. 构造
- 3. 极性区分
- 4. 驱动方式
- 5. 28BYJ-48步进电机
- (1)硬件电路
- (2)驱动控制
- (3)代码实现
- dc_motor_5_wire_4_phase_utils.h
- main.c
一、电机分类
电机可以按不同的标准进行分类,包括其工作原理、结构、用途等,如按工作原理分为直流电机、交流电机; 按结构分有刷电机、无刷电机等。
本文将介绍普通的小型直流电机、五线四相步进电机的控制。
二、小型直流电机控制
1. 简介
本文使用的小型直流电机常用于玩具,两根导线,改变电流强度时改变转速、改变电流方向时改变转向。
2. 驱动芯片ULN2003D
单片机IO口一般无法用来直接驱动直流电机,开发板上可以使用ULN2003D作为直流电机的驱动。该芯片基本规格前文已有介绍:
https://xundh.blog.csdn.net/article/details/128106835
引脚图:
电机接在VCC和OUT1引脚。
3. 代码实现
下面代码实现直流马达转5秒、停5秒,循环重复。
dc_motor_utils.c
#include "dc_motor_utils.h"
#include <reg52.h>
// DC Motor 引脚
sbit DC_motor = P1^0;
/**
* @brief DC Motor 启动
*/
void dc_motor_start(void){
DC_motor = 1;
}
/**
* @brief DC Motor 停止
*/
void dc_motor_stop(void){
DC_motor = 0;
}
main.c
#include "led_utils.h"
#include "dc_motor_utils.h"
#include "common_utils.h"
/**
* @brief 主函数
*/
void main()
{
// 关闭所有led
led_all_off();
while(1)
{
dc_motor_start();
delay_ms(1000*5);
dc_motor_stop();
delay_ms(1000*5);
}
}
三、五线四相步进电机控制
1. 步进电机工作原理
步进电机通过逐步地激活内部的线圈来实现精确的旋转运动。五线四相步进电机通过四个独立的线圈(相)来实现控制。当电流通过每个线圈时,它们会产生磁场,与电机内部的永磁体相互作用,从而驱动电机旋转。
2. 构造
五线四相步进电机通常包含两个磁极,每个磁极上有两个线圈,总共四个线圈。这四个线圈可以按照不同的顺序激活,以产生旋转运动。此外,步进电机通常还包含一个中心引脚(共阳或共阴),用于提供电源。
3. 极性区分
五线四相步进电机具有五根电路线,其中四根用于控制四个线圈(相),而另一根是共阳或共阴线,用于提供电源。
五线四相步进电机的线圈通常是两个两个连接在一起的,形成四个线圈,每个线圈都与一个相应的控制线相连。
4. 驱动方式
五线四相步进电机通常需要使用四个独立的控制信号来激活每个线圈,以实现步进运动。
5. 28BYJ-48步进电机
28BYJ-48步进电机通常由一个固定的外壳和一个转子组成。外壳内含有四个线圈,而转子上有一个永磁体。转子通过电流激活线圈的方式来旋转。
28BYJ-48基本参数:
- 电压: 5V
- 相数: 4
- 步进角度:5.625/64
- 减速比:1:64
减速比计算:
(1)硬件电路
与直流电机驱动使用相同硬件电路。
(2)驱动控制
驱动28BYJ-48步进电机需要按照正确的顺序激活线圈,并控制电流的方向来实现旋转。
8拍信号与运动节拍表如下:
导线颜色 | 第1步 | 第2步 | 第3步 | 第4步 | 第5步 | 第6步 | 第7步 | 第8步 |
---|---|---|---|---|---|---|---|---|
VCC 红 | 5V | 5V | 5V | 5V | 5V | 5V | 5V | 5V |
D 橙 | GND | GND | GND | |||||
C 黄 | GND | GND | GND | |||||
B 粉 | GND | GND | GND | |||||
A 蓝 | GND | GND | GND |
由于板载芯片可能有问题,我这里外接了ULN2003APC驱动步进电机。
(3)代码实现
下面代码实现步进电机的驱动运行,按key3转方向 ,按key5增加速度,增加到最大时速度降为最低。(其实增大速度就是减少延时)
dc_motor_5_wire_4_phase_utils.h
#include "dc_motor_5_wire_4_phase_utils.h"
#include "common_utils.h"
// 默认逆时针方向
static u8 dir=0;
// 默认最大速度旋转
static u8 speed=STEPMOTOR_MAXSPEED;
static u8 step=0;
// 1运行中 0停止运行
static u8 run_flag=0;
/**
* @brief 向步进电机发送一个脉冲
* @param step 指定步进序号,可选值0~7
* @param dir 方向选择,1:顺时针,0:逆时针
*/
void step_motor_28BYJ48_send_pulse(void){
u8 temp=step;
if(dir==0) //如果为逆时针旋转
temp=7-step;//调换节拍信号
switch(temp)//8个节拍控制:A->AB->B->BC->C->CD->D->DA
{
case 0: IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=0;break;
case 1: IN1_A=1;IN2_B=1;IN3_C=0;IN4_D=0;break;
case 2: IN1_A=0;IN2_B=1;IN3_C=0;IN4_D=0;break;
case 3: IN1_A=0;IN2_B=1;IN3_C=1;IN4_D=0;break;
case 4: IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=0;break;
case 5: IN1_A=0;IN2_B=0;IN3_C=1;IN4_D=1;break;
case 6: IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=1;break;
case 7: IN1_A=1;IN2_B=0;IN3_C=0;IN4_D=1;break;
default: IN1_A=0;IN2_B=0;IN3_C=0;IN4_D=0;break;//停止相序
}
}
/**
* @brief 设置步进电机速度
* @param s 速度值,可选值1~STEPMOTOR_MAXSPEED
*/
void step_motor_28BYJ48_set_speed(u8 s){
speed=s;
}
/**
* @brief 增加步进电机速度,加到最头0开始
*/
void step_motor_28BYJ48_increase_speed(void){
if(speed>STEPMOTOR_MAXSPEED)speed--;
else{
speed = STEPMOTOR_MINSPEED;
}
}
/**
* @brief 设置步进电机方向
* @param d 方向选择,1:顺时针,0:逆时针
*/
void step_motor_28BYJ48_set_dir(u8 d){
dir=d;
}
/**
* @brief 反转步进电机方向
*/
void step_motor_28BYJ48_revert_dir(void){
dir=!dir;
}
/**
* @brief 启动步进电机
*/
void step_motor_28BYJ48_start(void){
run_flag=1;
}
/**
* @brief 运行步进电机
*/
void step_motor_28BYJ48_run(void){
if(run_flag==0)return;
step_motor_28BYJ48_send_pulse();
step++;
if(step>7)step=0;
delay_ms(speed);
}
/**
* @brief 停止步进电机
*/
void step_motor_28BYJ48_stop(void){
run_flag=0;
}
main.c
/**
* @brief 按键3_4回调函数
*/
void key3_4Callback(int keyNum){
// key3 转方向
if(keyNum == 3){
step_motor_28BYJ48_revert_dir();
}else{
// key4 增加速度
step_motor_28BYJ48_increase_speed();
}
}
/**
* @brief 主函数
*/
void main()
{
step_motor_28BYJ48_set_speed(2);
// 顺时针旋转
step_motor_28BYJ48_set_dir(1);
// 启动步进电机
step_motor_28BYJ48_start();
key3_init();
key4_init();
setCallback(key3_4Callback);
while(1)
{
// 运行步进电机
step_motor_28BYJ48_run();
}
}
本文代码开源地址:
https://gitee.com/xundh/learn51