【51单片机】直流电机驱动(PWM)(江科大)

1.直流电机介绍

· 直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极,当电极正接时,电机正转,当电极反接时,电机反转
· 直流电机主要由永磁体(定子)、线圈(转子)和换向器组成
· 除直流电机外,常见的电机还有步进电机、舵机、无刷电机、空心杯电机等
在这里插入图片描述

2.电机驱动

电机的驱动无法直接使用IO口来进行驱动,所以用驱动电路来进行驱动,如大功率器件直接驱动,H桥驱动。本开发板直接用ULN2300来进行驱动,只需将电机的一端接VCC,另一端接OUT1就可。此时,在IN1输入1,则OUT1输出0,电机旋转;在IN1输入0,则OUT1输出1,电机不旋转
在这里插入图片描述
在这里插入图片描述

3.PWM介绍

· PWM(Pulse Width Modulation)即脉冲宽度调制,在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速、开关电源等领域
· PWM重要参数:
频率=1/Ts
占空比=ToN/Ts
精度=占空比变化步距

通过设置不同的占比来进行控制
通常一个周期的时间是相同的
在这里插入图片描述

4.LED呼吸灯

LED的IO口为0时,LED亮,为1时,LED灭;10口为1时,LED灯不会立刻熄灭,而是缓慢熄灭(具有惯性)

所以可以通过控制高电平和低电平的宽度即占空比来控制LED灯的亮度

通过逐步增加高电平宽度,减少低电平宽度,可使得LED灯越来越暗;反之,逐步增加低电平宽度,减少高电平宽度,可使得LED灯越来越亮

#include <REGX52.H>

sbit LED=P2^0;

void Delay(unsigned int t)
{
   
	while(t--);
}

void main()
{
   
	unsigned char Time,i;
	while(1)
	{
   
		for(Time=0;Time<100;Time++)		//改变亮灭时间,由暗到亮
		{
   
			for(i=0;i<20;i++)			//计次延时
			{
   
				LED=0;					//LED亮
				Delay(Time);			//延时Time
				LED=1;					//LED灭
				Delay(100-Time);		//延时100-Time
			}
		}
		for(Time=100;Time>0;Time--)		//改变亮灭时间,由亮到暗
		{
   
			for(i=0;i<20;i++)			//计次延时
			{
   
				LED=0;					//LED亮
				Delay(Time);			//延时Time
				LED=1;					//LED灭
				Delay(100-Time);		//延时100-Time
			}
		}
	}
}

此方案简单,但是需要占用主循环,不断翻转IO口延时,主循环无法做其他事情
优化
LED呼吸灯:定时器版

在实际使用中,都会用定时器来产生PWM,而本51单片机的芯片不具备这一功能,所以用软件来模拟这个功能

产生PWM方法:
在这里插入图片描述
在这里插入图片描述
通过自增的计数器来和预先设定的比较值来进行比较,计数器的值小于比较值时,输出0,反之输出1,也可以相反。

先将定时器修改为100us触发一次(电机的频率一般在10K到20KHz之间)

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

sbit LED = P2^0;

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

void main()
{
   
	Timer0Init();
	Compare = 5;
	
	while(1)
	{
   
		KeyNum = GetKeyNum();
		if(KeyNum == 1)
		{
   
			Speed++;
			Speed %= 4;
			if(Speed==0){
   Compare=0;}	//设置比较值,改变PWM占空比
			if(Speed==1){
   Compare=50;}
			if(Speed==2){
   Compare=75;}
			if(Speed==3){
   Compare=100;}
		}
		NixieShowNum(1,Speed);
	}
}

//定时器0的中断处理函数
void Timer0_Routine() interrupt 1
{
   
	TL0 = 0x9C;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	Counter++;
	Counter %= 100;
	if(Counter < Compare)
	{
   
		LED = 0;
	}
	else
	{
   
		LED = 1;
	}
}

5.直流电机调速

在原代码的基础上改个IO口就行(根据上述分析,Motor=1旋转)

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

sbit Motor=P1^0;

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

void main()
{
   
	Timer0_Init();
	while(1)
	{
   
		KeyNum=Key();
		if(KeyNum==1)
		{
   
			Speed++;
			Speed%=4;
			if(Speed==0){
   Compare=0;}	//设置比较值,改变PWM占空比
			if(Speed==1){
   Compare=50;}
			if(Speed==2){
   Compare=75;}
			if(Speed==3){
   Compare=100;}
		}
		Nixie(1,Speed);
	}
}

void Timer0_Routine() interrupt 1
{
   
	TL0 = 0x9C;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	Counter++;
	Counter%=100;	//计数值变化范围限制在0~99
	if(Counter<Compare)	//计数值小于比较值
	{
   
		Motor=1;		//输出1
	}
	else				//计数值大于比较值
	{
   
		Motor=0;		//输出0
	}
}

相关推荐

  1. 单片机直流电PWM级调速控制

    2024-02-16 20:26:01       60 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-16 20:26:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-16 20:26:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-16 20:26:01       82 阅读
  4. Python语言-面向对象

    2024-02-16 20:26:01       91 阅读

热门阅读

  1. Vue2源码梳理:render函数的实现

    2024-02-16 20:26:01       48 阅读
  2. CSS之BFC

    CSS之BFC

    2024-02-16 20:26:01      47 阅读
  3. Leetcode-709.转换成小写字母

    2024-02-16 20:26:01       54 阅读
  4. Attention Is All Your Need论文笔记

    2024-02-16 20:26:01       58 阅读
  5. C++虚函数

    2024-02-16 20:26:01       53 阅读
  6. gradient accumulate举例子解释

    2024-02-16 20:26:01       55 阅读
  7. 2024.2.6

    2024.2.6

    2024-02-16 20:26:01      52 阅读
  8. 10-通用类型、特质和生命周期

    2024-02-16 20:26:01       49 阅读