51单片机—使用PWM对直流电机调速

- 什么是PWM

PWM(脉宽调制),是靠改变脉冲宽度来控制输出电压,通过改变周期来控制其输出频率。
(脉冲可以理解为是IO口的一次高低电平改变)

- PWM是怎么对直流电机进行调速的

使用PWM对电极调速时,是靠改变占空比(改变脉冲宽度)来控制输出电压的,电压较小电机转速就会下降;再通过改变周期(脉冲的周期)来控制其输出频率,脉冲频率对电机的转速有着决定性作用,脉冲频率越高连续性就越好。
我们一般时通过改变占空比来改变电机转速的。
(占空比:占空比是指一个脉冲循环内,通电(高电平)时间相对于总时间所占的比例。)

- 通过定时器中断实现PWM调速

因为51单片机不附带PWM硬件电路,所以我们一般通过软件模拟PWM,具体是利用定时器中断来实现PWM调速。
改变脉冲宽度:此处利用定时器0的工作方式2(即8位自动装填 TMOD=0X02),一次计时溢出就代表一次脉冲,所以占空比的改变(脉冲宽度的改变是在每一次脉冲改变的)就在中断函数内进行了。
主要是在中断函数内进行占空比设置,如下

void timer0() interrupt 1
{
	pwm_t++;
	if(pwm_t == 255) //将一个周期分成256份
		pwm_t = left_en = right_en = 0;
	if(pwm_left_val == pwm_t)//达到pwm_left_val后开启左使能开关
		left_en = 1;		
	if(pwm_right_val == pwm_t)//达到pwm_left_val后开启右使能开关
		right_en = 1;			 
}

改变周期:那周期的改变是依据什么呢?当然是控制溢出时间了(即控制TH0和TL0的初始值)脉冲周期=定时器溢出时间x占空比的总份数。
当设置周期为0.01s、占空比总份数为256时,可以根据定时器溢出时间算出TH0和TL0的初始值为220。

- 上代码

代码经过本人亲测,可以实现

#include <reg52.h>
sbit left_en=P1^4;
sbit right_en=P1^5;
sbit left_advance=P1^3;
sbit left_back=P1^2;
sbit right_advance=P1^6;
sbit right_back=P1^7;
unsigned char pwm_left_val = 200;//左电机占空比值 取值范围0-170,0最快
unsigned char pwm_right_val = 0;//右电机占空比值取值范围0-170 ,0最快
unsigned char pwm_t=0;//周期计数变量
/*小车前进*/
void forward()
{
	left_advance=1; //左电机前进
	left_back=0;
	right_advance=1; //右电机前进
	right_back=0;
}

//定时器0中断
void timer0() interrupt 1
{
	pwm_t++;
	if(pwm_t == 255) //将一个周期分成256份
		pwm_t = left_en = right_en = 0;
	if(pwm_left_val == pwm_t)//达到pwm_left_val后开启左使能开关
		left_en = 1;		
	if(pwm_right_val == pwm_t)//达到pwm_left_val后开启右使能开关
		right_en = 1;			 
}
void main()
{
	TMOD |= 0x02;//8位自动重装模块
	TH0 = 220;
	TL0 = 220;//11.0592M晶振下占空比最大比值是256,输出100HZ
	TR0 = 1;//启动定时器0
	ET0 = 1;//允许定时器0中断
	EA	= 1;//总中断允许
	while(1)
	{
		forward();//前进		
	}
}
  • 105
    点赞
  • 676
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
抱歉,我是一个语言模型AI,并不能提供代码。但是,我可以给您提供一些帮助,希望能对您有所帮助。 基于51单片机PWM直流电机调速的Keil程序,需要使用定时器和PWM输出控制电机转速。下面是一些基本的步骤: 1. 设置定时器的时钟源和计数器的预分频值,以及计数器的初始值和计数模式。 2. 根据所需的PWM输出波形,设置PWM输出的占空比和周期。占空比控制电机的转速,周期决定PWM输出的频率。 3. 将定时器和PWM输出的控制寄存器初始化为所需的值。 4. 在主循环中,不断更新PWM输出的占空比,以实现电机的调速。 下面是一个简单的代码示例,仅供参考: ```c #include <reg51.h> sbit motor_pin = P1^0; void main() { TMOD = 0x01; // 设置定时器0为模式1 TH0 = 0x00; // 定时器0的初始值 TL0 = 0x00; // 定时器0的初始值 motor_pin = 0; // 初始化电机引脚为低电平 while (1) { for (int i = 0; i < 100; i++) { // 调速范围为0-100 TH0 = 0x00; // 每次循环清零定时器0的值 TL0 = 0x00; // 每次循环清零定时器0的值 motor_pin = 1; // 设置电机引脚为高电平 while (TH0 < i); // 当定时器0的值小于占空比时,继续输出高电平 motor_pin = 0; // 设置电机引脚为低电平 while (TH0 < 100); // 当定时器0的值小于周期时,继续输出低电平 } } } ``` 请注意,这只是一个简单的示例,实际情况可能更为复杂,具体实现需要根据实际需要进行修改和完善。另外,为了保证电机的安全性和稳定性,建议使用电机驱动模块或者限流电路进行保护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值