基于51单片机的电机(L298芯片,PWM调速,可加速、减速、正转、反转)

这篇具有很好参考价值的文章主要介绍了基于51单片机的电机(L298芯片,PWM调速,可加速、减速、正转、反转)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        电机是我们日常生活中比较常用的一个工具,我们经常需要使用电机来转动和拖动,完成一些任务。本次设计便用基于51单片机完成的电机转动与调速,使得电机可以正常启停、加速、减速以及正反转。

        文章末尾提供资源免费下载,包括proteus仿真文件与源码。

        51单片机的最大电压为5V,最大输出电流为10mA。可想而知,我们不可能依靠单片机引脚去驱动电机,因此我们需要借助电机驱动芯片来完成这项艰难的任务。L289芯片在protues中长这个样子:

                       基于51单片机的电机(L298芯片,PWM调速,可加速、减速、正转、反转)

        乍一看,这东西看着挺复杂,这么多引脚。其实,仔细研究过就会知道,这东西很简单。其他博主有很详细的介绍L298的引脚功能,这里就不讲,简单说下本次用到的。IN1和IN2是用来控制启停和正反转的,IN1为1,IN2为0就正转,反之则为反转,全为0或全1则制动,同时,这也是PWM输入入口,控制电机转速。ENA引脚为1,表示可以PWM调速。VCC为工作电压,5V,VS为驱动电压12V,OUT1和OUT2表示输出,连接电机正负极,1接正,2接负。此处为网上找到的资源,我测试过可以用,如有纰漏,欢迎指正。

下面介绍本次设计的主角,带编码器的直流电机。protues中,它长这个样子:

                                         基于51单片机的电机(L298芯片,PWM调速,可加速、减速、正转、反转)

左右两边的“手”便是它的正负极,我们将他两与L298的OUT1与OUT2相连。上面的三根头发,左右两边根据设定值,每圈发出固定数量的脉冲,我们根据脉冲数即可知道转了几圈。本次设计中,每圈输出24个脉冲。那么在哪里修改呢?双击电机,可以看到下图:

                              基于51单片机的电机(L298芯片,PWM调速,可加速、减速、正转、反转)

相信你看到了24了吧,该怎么改,你自己决定。那电机最中间的头发呢?据说是每圈一个脉冲,感兴趣的同学可以试试。电机最下面的绿色屏幕就是转速了,单位是r/min。

至于脉冲数的统计,这里提供两个思路,一个是计数器,一个是外部中断。我们可以将其中一个定时器做计数器,计算脉冲,另一个计时,计算转速。另外一种是通过外部中断统计脉冲数,定时器计时,获得转速。

至于PWM的生成方法,我们可以这么想。IO口有两种状态,1和0。我用定时器计100us,70us我r让一个IO口为1,30us为0,我不就得到了一串方波,周期100us。程序实现就是设置一个变量comper,作为比较量,另一个变量count_pwm为累加量,10us加1,大于comper为1,小于为0,ok,得到了可调PWM。

下面是具体实现,每段代码,每个变量都有详细注释,同时欢迎留言询问,源码0error,0warning。

(1)定时器部分(timer.c)定时器T0计时,T1产生PWM

#include <reg52.h>
/************************************
函数名:timer_Init
功能:定时器初始化,T0用作50ms定时,
	  T1用10us定时
形参:无
返回值:无
*************************************/
void timer_Init()
{
	TMOD = 0x11;
	TL0 = 0xB0;				//设置定时初始值50ms
	TH0 = 0x3C;				//设置定时初始值
	TL1 = 0xF6;				//设置定时初始值10us
	TH1 = 0xFF;				//设置定时初始值
	TF0 = 0;				//清除溢出标志
	TF1 = 1;
	ET0 = 1;				//定时中断允许
	ET1 = 1;
	EA = 1;					//总中断
	IT0 =1;					//外部中断
	EX0 =1;					//下降沿出发
	TR0 = 1;				//定时器开
	TR1 = 0;
}

 timer.h

#ifndef __TIMER_H
#define __TIMER_H
void timer_Init();
#endif

 (2)按键部分,控制电机启停、正反转、加速、减速

key.c

#include <reg52.h>
#include <intrins.h>            //nop所在头文件
#include "key.h"				//按键头文件
/***********************************
函数名:delay_key
功能:5ms延时,用于按键消抖,此处是
为了protues仿真速度,实际应为20ms
形参:无
返回值:无
***********************************/
void delay_key()
{
	unsigned char i, j;

	i = 6;
	j = 211;
	do
	{
		while (--j);
	} while (--i);
}
/***********************************
函数名:key_pron
功能:按键处理函数(k1:开始,k2:停止
k3:加速,k4:减速 ,k5:正转,k6:反转
形参:无
返回值:无
*************************************/
void key_pron()
{
	if(K1 == 0)            //开始
	{
		delay_key();		//消抖
		if(K1 == 0)
		{
			TR1=1;			//启动定时器
			ENA = 1;
			motor_flag = 0;
			IN2 = 0;
			comper = 50;//初始转速
			while(K1 == 0)  //松手检测
			{
				SMG_display();
			}
		}
	}
	
	if(K2 == 0)				//停止
	{
		delay_key();		//消抖
		if(K2 == 0)
		{
			TR1 = 0;		//停止定时器
			IN1 = 0;
			IN2 = 0;
			comper = 50;  //初始转速
			while(K2 == 0)	//松手检测
			{
				SMG_display();
			}
		}
	}
	
	if(K3 == 0)				//加速
	{
		delay_key();
		if(K3 == 0)
		{
			comper=comper-10;	//增加占空比
			if(comper<0)		//上限
				comper = 0;
			while(K3 == 0)
			{
				SMG_display();
			}
		}
	}
	
	if(K4 == 0)				//减速
	{
		delay_key();
		if(K4 == 0)
		{
			comper=comper+10;//减小占空比
			if(comper >100)//下限
				comper = 100;
			while(K4 == 0)
			{
				SMG_display();
			}
		}
	}
	
	if(K5 == 0)				//正转
	{
		delay_key();
		if(K5 == 0)
		{
			motor_flag = 0;   //正转标志
			ENA = 1;
			IN2 = 0;
			while(K5 == 0)
			{
				SMG_display();
			}
		}
	}
	
	if(K6 == 0)				//反转
	{
		delay_key();
		if(K6 == 0)
		{
			motor_flag = 1; //反转标志
			ENA = 1;
			IN1 = 0;
			while(K6 == 0)
			{
				SMG_display();
			}
		}
	}
}

key.h

#ifndef __KEY_H
#define __KEY_H
//按键
sbit K1 = P1^0;
sbit K2 = P1^1;
sbit K3 = P1^2;
sbit K4 = P1^3;
sbit K5 = P1^4;
sbit K6 = P1^5;

sbit ENA = P2^5;
sbit IN1 = P2^3;
sbit IN2 = P2^4;
extern bit motor_flag;
extern void SMG_display();
void delay_key();
void key_pron();
extern char comper;					//PWM占空比调节
#endif

(3)数码管显示部分,采取共阴四位数码管,保留一位小数

smg.c

#include <reg52.h>
#include "seg.h"
unsigned char code SMG_NODOT[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//无小数点
unsigned char code SMG_DOT[10]= {0xbf,0x86,0xdb,0xcf,0x6e6,0xed,0xfd,0x87,0xff,0xef};//有小数点
/*************************************
函数名:SMG_Init
功能:数码管初始化函数
形参:pos:显示位 value:显示值
返回值:无
**************************************/
void SMG_Init(unsigned char pos,unsigned char value)
{
	unsigned char dat = 0x80;
	P3 = P3&(~(dat >> pos));
	P0=value;
	delay(2);
	P0 = 0x00;
	P3 = P3|0xf0;
}
/***********************************
函数名:SMG_display
功能:数码管显示函数
形参:无
返回值:无
************************************/
void SMG_display()
{
	SMG_Init(0,SMG_NODOT[speed/1000]);
	SMG_Init(1,SMG_NODOT[(speed%1000)/100]);
	SMG_Init(2,SMG_DOT[(speed%100)/10]);
	SMG_Init(3,SMG_NODOT[speed%10]);
}

smg.h

#ifndef __SEG_H
#define __SEG_H
extern void delay(unsigned char t);
extern unsigned int speed;
void SMG_Init(unsigned char pos,unsigned char value);
void SMG_display();
#endif

(4)主函数main.c

/**********************************************************
Author   :sakura
Time     :2023/4/22
Funcation:51单片机使用L298电机芯片驱动带编码器的电机,
		  通过编码器测量转速,同时使用LED数码管显示,
		  按键可使电机正反转并改变速度
***********************************************************/
//头文件
#include <reg52.h>				//51单片机头文件
#include <intrins.h>            //nop所在头文件
#include "main.h"				//主函数头文件
#include "timer.h"				//定时器头文件
#include "key.h"				//按键头文件
#include "seg.h"				//数码管头文件
/*************************************
函数名:main
功能:主函数入口
形参:无
返回值:无
**************************************/
void main()
{
	timer_Init();			//定时器初始化
	IN1 = 1;
	IN2 = 1;
	while(1)
	{
		SMG_display();		//数码管显示
		key_pron();			//按键扫描
	}
}
/***********************************
函数名:INT0_isr
功能:外部中断0入口,统计编码器脉冲
形参:无
返回值:无
************************************/
void INT0_isr() interrupt 0
{
	count_f++;//每秒脉冲数
}
/*****************************
函数名:timer0_isr
功能:定时器0中断入口,定时50ms
		每秒计算一次转速
形参:无
返回值:无
*****************************/
void timer0_isr() interrupt 1
{
	TL0 = 0xB0;				//设置定时初始值50ms
	TH0 = 0x3C;				//设置定时初始值
	count_50ms++;
	if(count_50ms == 20)
	{
		count_motor = count_f + count_motor;
		count_f = 0;
	}
	if(count_50ms == 40)
	{
		count_50ms = 0;
		count_motor = count_f + count_motor;
		speed_real = (count_motor * 0.0416666);//计算每秒圈数,每圈24个秒冲																//总脉冲/24 = 圈数
		speed = speed_real*300;//每秒转圈数(一位小数)
		count_f = 0;
		count_motor = 0;
	}
}
/*******************************
函数名:timer1_isr
功能:定时器1中断入口,定时10us,
	用于产生PWM波
形参:无
返回值:无
*******************************/
void timer1_isr() interrupt 3
{
	TL1 = 0xF6;				//设置定时初始值
	TH1 = 0xFF;				//设置定时初始值
	count_pwm ++;
	if(count_pwm == 100)
		count_pwm = 0;
	if(count_pwm>comper)
	{
		if(motor_flag == 0)  //正转对IN1输出PWM
			IN1 = 1;
		else				//反转对IN2输出PWM
			IN2 = 1;
	}
	else
	{
		if(motor_flag == 0)  
			IN1 = 0;
		else
			IN2 = 0;
	}
		
}

main.h

#ifndef __MAIN_H
#define __MAIN_H
#include <reg52.h>
#include <intrins.h>            		//nop所在头文件
//变量
unsigned char count_f = 0;				//编码器脉冲计数
unsigned char count_50ms = 0;			//50ms计数
char comper = 50;						//PWM占空比调节
float speed_real = 0;					//转速中间变量
unsigned int speed = 0;					//转速,r/min
unsigned char count_pwm = 0;			//pwm统计
bit motor_flag = 0;						//正反转标志
unsigned char count_motor = 0;			//滤波变量
//函数声明
void delay(unsigned char t);					//延时函数
/*************************************
函数名:delay
功能:t*10us延时
形参:t:延时次数
返回值:无
*************************************/
void delay(unsigned char t)
{
	unsigned char i;
	while(t--)
	{
		_nop_();
		i = 2;
		while (--i);
	}
}

#endif

以上就是全部代码了。仿真结果如下:

基于51单片机的电机(L298芯片,PWM调速,可加速、减速、正转、反转)

 实际转速81.4,数码管81.2,低速误差是很小的。至于其他比如正反转、加减速不好展示,欢迎大家下载资源测试,仅需您小小的一个赞。

链接:https://pan.baidu.com/s/1A_J6M07DGOFI9C_JDM_NPQ?pwd=ae1v 
提取码:ae1v

 文章来源地址https://www.toymoban.com/news/detail-464083.html

到了这里,关于基于51单片机的电机(L298芯片,PWM调速,可加速、减速、正转、反转)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于51单片机的直流电机转速显示+加速减速启停

    做了一个实战项目,这个实战项目主要是实现对直流电机转速的控制,可以实现电机加速,减速,报警、启停以及显示转速。在本电路的基础上也可以进行一些拓展改变电机正反转的状态,只需要外加一个按键和修改部分程序即可,在文章的最后会对拓展进行一个说明。基础

    2023年04月27日
    浏览(45)
  • 基于51单片机直流电机转速数码管显示控制系统

    一、系统方案 本文主要研究了利用MCS-51系列单片机控制PWM信号从而实现对直流电机转速进行控制的方法。本文中采用了三极管组成了PWM信号的驱动系统,并且对PWM信号的原理、产生方法以及如何通过软件编程对PWM信号占空比进行调节,从而控制其输入信号波形等均作了详细的

    2024年02月12日
    浏览(47)
  • 基于51单片机的PWM控制直流电机设计( proteus仿真+程序+报告+讲解视频)

    仿真图proteus 7.8及以上 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:S0031 基于51单片机的PWM控制直流电机设计 1.设计要求 采用51单片机作为核心控制器,控制直流电机的正转,反转,制动,停止。 2.功能要求 1)数码管显示当前转动方向和当前的PWM占空比0~100%。 2)电机

    2023年04月25日
    浏览(48)
  • Proteus基于51单片机通过PWM脉冲调制控制电机转速_按键与串口控制转速_电机转速可测

    临近期末,学校的单片机课程需要做课程设计,主要内容是基于51单片机的可调速电机,具体要求如下,在此记录一下具体的一个解题方案。 要求利用单片机输出PWM波形,通过改变占空比,改变电枢两端电压的平均值,从而改变电动机的转速 通过按键进行手动速度调整(速度

    2023年04月14日
    浏览(62)
  • 基于51单片机的FRID智能门禁系统(RFID,12864,AT24C02,步进电机......)

    目录 门禁系统 需要的器件 设计思路 流程图实现 技术实现 实物接线图 实物接线图  函数设计 部分主程序代码,截取片段 12864显示模块 步进电机模块以及蜂鸣器 FRID射频模块 AT24C02模块 功能实现及其源代码 完整文件         STC89C52,MFRC-522 RFID射频模块,AT24C02存储电路,

    2024年02月07日
    浏览(50)
  • 【【51单片机直流电机调速】】

    PWM的生成方法 先用户设定一个比较值,然后计数器定时自增。 当计数器比较值,输出0 当计数器比较值,输出1

    2024年02月15日
    浏览(46)
  • 51单片机-直流电机学习

    51单片机采用的是5V的直流电机 轴长:8mm 轴径:2mm 电压:1-6V 参考电流:0.35-0.4A 3V 转速:17000-18000 转每分钟 直流电机的结构应由 定子 和 转子 两大部分组成。 直流电机运行时静止不动的 部分称为定子 定子的主要作用是产生磁场,由机座、主磁极、 换向极、 端盖、 轴承和

    2024年02月09日
    浏览(42)
  • 【51单片机学习】PWM电机调速

    中断允许寄存器,详情可以看STC51单片机芯片手册第160页 TMOD、TCON详情可以看STC51单片机芯片手册第187页 51单片机中的定时器有三个,(C52比C51多了一个定时器3,但这些都统称为51单片机) 本次以 Timer0 为例进行介绍 定时器的作用: 1:用于计时系统,可实现软件计时,或者使程

    2023年04月18日
    浏览(79)
  • 通过51单片机实现直流电机调速

    随着各种工业生产设备和机械设备的广泛使用,直流电机调速技术的研究和应用越来越受到人们的重视,具有广泛的应用前景。本项目通过51单片机实现直流电机调速功能,为实际工程应用提供一个可靠和有效的调速方案。 如果需要下载项目工程,可以去这里: https://blog.c

    2024年02月14日
    浏览(42)
  • 51单片机对步进电机的控制

    首先打开proteus软件,导入元器件并连线。 接着了解一下步进电机:  步进电机的特点:  步进电机的驱动芯片:  l298步进电机驱动芯片各引脚的功能:  L298的逻辑功能表  四相步进电机的工作原理:  接下来就是proteus中导入步进电机的方法:  proteus中导入L298芯片的方法:

    2024年02月09日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包