【自学嵌入式:51单片机】直流电机驱动(PWM)和呼吸灯

所有自学嵌入式:51单片机系列的操作相关器件的代码都汇总到了:https://gitee.com/qin-ruiqian/Qin51

直流电机

image

直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极,当电机正接时,电机正转,当电极反接时,电机反转。直流电机主要由永磁体(定子)、线圈(转子)和换向器组成。除直流电机外,常见的电机还有步进电机、舵机、无刷电机、空心杯电机等。
步进电机机壳上分布一圈电磁铁,转子是一个永磁体,对不同角度的磁铁通电,以圆形的脉冲进行旋转,永磁体也按照脉冲进行旋转,可以精密控制。
image
上图是舵机,一个直流电机加一个控制器,有三根线,正负极和编码器控制线,通过调整控制线的脉冲调整舵机的角度。

电机驱动电路

image
电机直接接单片机I/O口会损坏I/O口,所以要通过一个驱动电路间接连接

  • 大功率器件直接驱动:驱动的电机只能朝着一个方向转,它不具备调换电机正反方向的功能,利用PNP三极管(MOS管)让更大电压的电路导通,需要加一个续流二极管,防止电流突变,电流突变,让二极管把电流释放掉。
  • H桥驱动:它可以控制电机正反转

PWM

PWM(Pulse Width Modulation)即脉冲宽度调制,在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速、开关电源等领域。通过让电机转1ms停1ms等操作让电机转的快或慢。

PWM重要参数

\[\text{频率}=\frac{1}{T_{S}} \]

\[\text{占空比}=\frac{T_{\text{ON}}}{T_{S}} \]

\[\text{精度}=\text{占空比变化步距} \]

其中\(T_{\text{ON}}\)是打开的时间,占空比变化步距,比如从1%,2%...占空比变化步距就是1%,如果是从1.1%,1.2%...占空比变化步距就是0.1%.
image
我们想要控制电机调速,就要不断控制电机电平变化的频率。

PWM呼吸灯

代码实现

main.c:

#include <REGX52.H>

sbit LED=P2^0;

//延迟1微秒
void Delayus(unsigned int t)
{
	while(t--);
}

void main()
{
	unsigned char Time = 0;
	unsigned char i = 0;
	while(1)
	{
		//亮度由低变高
		for(Time = 0; Time<100; Time++)
		{
			//让每一个亮度变化延缓20次
			for(i=0; i<20; i++)
			{
				LED = 0;
				Delayus(Time);
				LED = 1;
				Delayus(100 - Time);
			}
		}
		//亮度由高变低
		for(Time=100; Time>0; Time--)
		{
			//让每一个亮度变化延缓20次
			for(i=0; i<20; i++)
			{
				LED = 0;
				Delayus(Time);
				LED = 1;
				Delayus(100 - Time);
			}
		}
	}
}

时序分析

image
20次内周期是恒定的
image
外层循环控制着高低电平的间隔大小
一般用定时器来控制呼吸灯,更高端的单片机有硬件pwm模块

PWM调节LED灯亮度

代码实现

#include <REGX52.H>
#include "Key.h"
#include "Nixie.h"

sbit LED = P2^0;

unsigned char Counter, Compare; //Counter计数器,Compare比较值设置越大,低电平(亮的)时间越长
unsigned char KeyNum; //按键键码
unsigned char Speed; //呼吸灯速度

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

	while(xms--)
	{
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

//初始化定时器,100微秒为周期
void initTimer0(void)
{
	TMOD = 0x01; //只开启定时器0
	TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA = 1; //允许中断
	ET0 = 1; //允许定时器0中断
}

//每隔100微秒中断一次
void Timer0_Routine() interrupt 1
{
	TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	Counter++;
	Counter %= 100; //到100的时候自动变0
	//计数变量到比较值的时候自动灭(亮的时间最多100微秒)
	if(Counter < Compare)
	{
		LED = 0;
	}
	else
	{
		LED = 1;
	}
}

void main()
{
	initTimer0();
	Compare = 5; //比较值设置越大,低电平(亮的)时间越长
	while(1)
	{
		KeyNum = Key();
		if(KeyNum == 1)
		{
			Speed++;
			Speed%=4;
			//不同速度的比较值,也代表着LED灯不同的亮度
			if(Speed == 0)
			{
				Compare = 0;
			}
			if(Speed == 1)
			{
				Compare = 5;
			}
			if(Speed == 2)
			{
				Compare = 50;
			}
			if(Speed == 3)
			{
				Compare = 100;
			}
		}
		Nixie_Scan(1, Speed); //数码管显示当前速度
	}
}

PWM直流电机调速

产生PWM方法

image
通过改变比较值得数值,控制其占空比,比较直越大,其占空比就越小

代码实现

代码实现和PWM调节LED灯亮度一样,就是把LED口换成电机口,然后LED灯我的是0亮1灭,把0和1换个位置就行
image

#include <REGX52.H>
#include "Key.h"
#include "Nixie.h"

sbit Motor = P1^0;  //接电路中第一个端口,用out1输出

unsigned char Counter, Compare; //Counter计数器,Compare比较值设置越大,低电平(亮的)时间越长
unsigned char KeyNum; //按键键码
unsigned char Speed; //呼吸灯速度

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

	while(xms--)
	{
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

//初始化定时器,100微秒为周期
void initTimer0(void)
{
	TMOD = 0x01; //只开启定时器0
	TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	EA = 1; //允许中断
	ET0 = 1; //允许定时器0中断
}

//每隔100微秒中断一次
void Timer0_Routine() interrupt 1
{
	TL0 = 0xA4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	Counter++;
	Counter %= 100; //到100的时候自动变0
	//计数变量到比较值的时候自动变低电平
	//这样通过调节占空比来调节电机转速
	if(Counter < Compare)
	{
		Motor = 1;
	}
	else
	{
		Motor = 0;
	}
}

void main()
{
	initTimer0();
	Compare = 5; //比较值设置越大,高电平时间越长
	while(1)
	{
		KeyNum = Key();
		if(KeyNum == 1)
		{
			Speed++;
			Speed%=4;
			//不同速度的比较值,也代表着电机不同转速
			//比较值大一些,让电机转起来
			if(Speed == 0)
			{
				Compare = 0;
			}
			if(Speed == 1)
			{
				Compare = 50;
			}
			if(Speed == 2)
			{
				Compare = 75;
			}
			if(Speed == 3)
			{
				Compare = 100;
			}
		}
		Nixie_Scan(1, Speed); //数码管显示当前速度
	}
}
posted @ 2025-08-05 11:58  秦瑞迁  阅读(322)  评论(0)    收藏  举报