资讯详情

单片机PWM控制直流电机驱动程序+仿真+报告

直流电机驱动信息包:

cdfbf3a4c18271960e3ceb75c837b2b1.png

模拟原理图如下(proteus本帖附件可下载仿真工程文件)

电子系统设计报告

课题名称 直流电机驱动

专 业 电子信息工程技术

目录

第1章 设计主题和要求

第2章 设计方案

2.1 设计方案

2.2 方案选择

2.3 系统框图

第3章 硬件设计

3.1 整体硬件设计

3.2 晶体振荡器电路

3.3 复位电路

3.4 按键输入电路

3.5 显示电路

3.6 电机驱动电路

3.7 电机模块

第4章 图形界面设计

4.1 图形界面设计

第5章 软件设计

5.1 程序流程图

第6章 制作与调试

6.1 硬件调试

6.2 程序调试

6.3 心得体会

参考文献

设计主题和要求

设计题目:直流电机驱动。

设计要求:设计直流电机驱动。

设计液晶屏(LCD1602)显示电路和独立键盘输入电路。

能准确显示电机状态和转速。

电机状态和转速可通过按钮控制。设计方案2.1设计方案

方案1:单片机四组并行口(P0、P1、P2、P3)复位时是高电平,所以在设计按键接口时可以设计为低电平有效。低电平时判断按钮按下,执行相关操作。

按下按钮会有抖动。如果计数按钮,会发现虽然只按一次,但计数不一致。这将导致错误的操作。因此,需要抖动按钮。按钮接口只执行简单的检测功能和特殊的功能寄存器,因此使用P1口。

采用显示模块LCD1602液晶屏,使用单片机的P0口。P0是特殊的,需要外部上拉电阻才能正常输出。考虑到模拟设计的简化,因此使用P0口作为LCD1602液晶屏是数据端口。

由于需要测量电机的速度和状态,P有一些特殊的寄存器可以使用,所以保留P三口。其他接口连接在去除。P三口以外的接口。

直流电机的转速与正电流的持续时间成正比PWM该方法产生脉冲,调整电机转速。如何产生,使用定时器T0产生中断。

测速则使用T定时器,外中断INT1组合测量。外部中断INT负跳变为开启T1计时器可以通过测量两个负脉冲的时间间隔来获得转速(电机旋转一圈发出一定时间的高电平)。

状态测量由外部中断0和1再次完成。状态测量只需测量一次,占用时间短,准确。

方案二:修改方案一的部分。为了准确响应关键部分,采用外部高电平的方法。

电机测速模块:仍不变。

通过内部编程完成状态测量,无需外部中断0、1的参与。

方案三:仍然修改方案一。为了保证按键部分的准确性,按键外部连接到高电平。

PWM使用数据选择器控制电机的正反转,降低编程难度。.2方案选择

方案1过于追求准确性,编程复杂,开启过多中断功能与其他方案相同,但需要特别注意大量标志位的开启,并注意时间顺序问题。对编程能力和协调性有较高的要求。

方案2准确地提高了按钮的准确性。通过仔细考虑,编程比开放和外部中断测量更容易。所有这些都很容易实现,但为了确保准确性,需要通过编程进行调整。

经过仔细考虑,使用数据选择器可能需要更多的时间来选择芯片和理解芯片

最后认为方案二更可行。.3系统框图

整个系统以单片机为核心,处理信息。键盘:有7个键盘,每个键盘都有不同的功能。当键盘输入信号流入单片机时,需要抖动的结果。

STC89C51:负责整个系统的信息处理。包括键盘的输入信号处理、根据键盘的信号发出电机驱动信号、对电机的速度和转向进行测量、测量完成将信息送给显示。

电机驱动芯片:与电机所需的驱动电流相比STC89C51直接输出电流多,电机控制不理想。反过来,它也会影响单片机的正常运行。因此,直流电机需要驱动芯片。

电机:电机为MOTOR-ENCODER,有五条线。其中两个用于输入电流驱动电机,其余三个用于电机的编码输出。中线输出的特点是电机旋转一圈输出正脉冲。边缘两根线输出的脉冲可调,脉冲相差90度,反映了电机的正反转。

显示:显示所用设备LCD1602显示器显示电机转速和正反转状态。硬件设计3.整体硬件设计

总硬件分为:晶体振荡器电路、复位电路、按键输入模块、显示电路、电机驱动电路、电机模块。如下图所示 3.1?1所示

图 3.1?13.晶体振荡器电路

晶振X1采用11.0592MHZ,电容C1、C2采用典型值22pF。如图 3.21.该电路的功能是为单片机提供11.0529MHZ的时钟。

图 3.2?13.3复位电路

电路图 3.如所示,复位电路电源为 5V、电容(极性电容)C3采用典型值10uF、电阻R7.820欧姆和按钮。该电路为单片机复位端口提供一定时间的高电平。当单片机出现异常时,单片机可以通过按钮复位。然后正常运行。EA/引脚不需要在这个电路中使用,只需连接即可。

图 3.3?13.按键输入电路

电路图如图 3.4?1显示。有六个按钮,分别有不同的功能。图中已标记了按钮的功能。图中的六个电阻值为1K欧姆,限流电阻和降压。电压没有统一标记 5V。其他按钮只有按下按钮1才能启动。

图 3.4?13.5显示电路

电路图如图 3.5.1所示。液晶显示模块数据口和单片机P0口连接,其他端口通过标签与P2.0、P2.1连接。P0口与液晶显示模块交换信息,P2.0、P2.一口读写液晶,使能控制。

图 3.5?13.6电机驱动电路

电路图如图 3.6?1所示。驱动芯片型号为L298具有很强的驱动能力。VCC为芯片供电 5V、VS电机驱动电压最高为45V。IN1、IN2接TTL电平和单片机的标签ON、OFF端口(电机控制流输出端口)连接,ON、OFF端口如图 3.4?1所示。ENA、ENB为芯片的使能端,电平时芯片工作。ENA控制端口IN1、IN2、OUT1、OUT2。低电平时端口无法工作,无法控制电机。OUT1、OUT2接直流电机输入端。图中接地的端口在图中用不到。

图 3.6?13.7电机模块

电路图如图 3.7?1所示。电机的输入端口为1、2。1为高电平时,电机正转2为高电平时,电机反转。1、2同为高或者低电平则不转,ENA低电平也不转。电机的A、B与单片机的A、B连接,用于电机状态的测量。IN1与单片机的IN1相连,用于测速。具体连接与标号在图中已标注。

图 3.7?1图形界面设计4.1图形界面设计4.1.1按键界面设计

如图 4.1?1所示

按键扫描模块中有6个按键,每个按键会调动相应的模块。并对数据处理。4.1.2LCD1602模块界面

界面设计如图 4.1?2所示:

显示模块会显示电机的相关信息(正转、反转、速度、可以加上电机是否加速的、减速的测试、以及显示),显示前将依据按键输入的信号进行运算,处理后送入液晶中。软件设计5.1程序流程图

主程序流程图如图 5.1?1所示。

制作与调试6.1硬件调试

在确定方案后,便开始搭建硬件。从难易程度来看,该课题是比较简单的所以硬件部分搭建容易,搭建完成即可。开始方案是选择方案一,需要使用多个中断,需要修改的仅仅是电路的连接。后面发现方案一过于复杂,改用方案二,对需要修改的连接电路增加标号即可。6.2程序调试

由于是自己写程序,经验不足、速度慢,容易出现问题。为了保证每一个环节到位,采用边写程序、边调试的方法。

最先开始的模块是显示模块。显示模块使用器件为LCD1602,在单片机的课程中学过做过关于这个器件的实验,对器件了解有一些,但不是很熟悉。对原来的程序没有进行封装,最开始出现数据送入位置错误,造成预期之外的结果。而后通过仔细查看课本上的资料,通过位置对照,修改后,液晶显示模块初步没有问题。

电机控制模块:对电机控制需要使用中断、在中断里面产生方波信号,并且方波的占空比可调,电机控制流输出通道选择也在这个模块。在这个模块完成前需要完成一部分键盘扫描函数的设计。当以上程序完成并运行后,通道选择和占空比都出现了问题。最开始是无论按什么键电机都不转,于是乎调整程序,首先发现单片机四组端口复位后输出为高电平,即表示电机停转,需要对电机输出端口初始化,都为低电平。然后进行控制。脉冲波形的占空比的调节,设立多个全局变量,设置上下限,这样波形占空比调节没有问题。电机输出信号通道选择,由于写程序经验不足,逻辑上出现了错误,导致想要外接数据选择器来调节信号输出,进而控制电机正反转。最后经过实验发现这个方法实现起来比较困难,思路没有。还是从中断里面进行调节好一些。最终实现了电机的调节。

电机转向测量模块:此模块完成后在多次的调试过程中发现使用while语句莫名奇妙对电极控制模块产生了影响。为了保证电机控制模块没有问题,对转向模块重新进行了设计,理论分析。但是由于时间问题,没能完成。

测速模块的调节:测速模块需要定时器1和外中断1完成。测速模块完成后需要与显示模块共同完成。由于此前在选择方案的时候,过分依赖中断和定时器,进行了较长时间的论证,电机控制模块的调试由于是个人编程思想和能力问题导致花费了大量的时间。测速模块虽然完成,但是没有时间调试。6.3心得体会

在一周的实训中,发现了很多的问题,也收获了很多。最开始是方案的确定很困难,方案的确定需要对单片机的各个资源非常了解。这从侧面反映了个人对单片机不熟悉,以及特点的不了解,最终方案的敲定花费了大量的时间,导致后面编程、其它问题的解决时间不足。

从定时器T0的编程中发现自身的写程序能力非常薄弱,程序的结构很乱,在一定程度上来说完全是想到什么就写什么,毫无章法。更没有将程序封装起来、留做下次便以稍加修改即可使用。

总之,在这次实训中让我看到了自己各个方面的不足,这些不足通过平时的锻炼是可以补起来的,反映出学习方法存在问题,需要加以改进。通过实训,对单片机的部分硬件有了进一步的了解、熟悉。单片机实训是一个比较综合的课程,结合了C语言、单片机常识、模拟电路、数字电路、硬件设计、软件的使用、软件设计。对培养独立解决问题的能力、自主学习能力、创新思维能力有较大影响。

单片机源程序如下:

#include

#include

#include

#define uchar unsigned char

#define uint unsigned int

sbit lcdrs=P2^0;       //寄存器选择,0:数据寄存器。1:为状态/命令寄存器

sbit lcden=P2^1;         //--LCD控制引脚

sbit speed=P3^2;                                        //测速端口

sbit ENA=P2^2;                                        //电机使能控制端

sbit key1=P1^0;         //启动按键

sbit key2=P1^1;                                        //正转按键

sbit key3=P1^2;                                        //反转按键

sbit key4=P1^3;                                        //加速按键

sbit key5=P1^4;                                        //减速按键

sbit key6=P1^5;                                        //停止按键

sbit Zheng=P1^6;                                                //正转输出端口

sbit Fan=P1^7;                                                //反转输出端口

uchar Timer0_flag=4;

uchar Timer0_BiaoZhi=0;//初始化占空比为1:3(高:低)

uchar gewei;

uchar shiwei;

uchar baiwei;

/******标志位设置*****/

uchar KEY1=0;//优先级标志

uchar KEY2=0;//加速标志

uchar INT1_FLAG=0;

uchar COUNTER_high=0;

uchar COUNTER_low=0;

uchar SUM=0;

uint TIMER1_COUNTER=0;

uint INT1_tingzhi=0;                //在要测速时置0

/****面板显示****/

uchar code lcd_desktop11[]="stop";//停止

uchar code lcd_desktop12[]="ford";//正转

uchar code lcd_desktop13[]="fanz";//反转

uchar code lcd_desktop21[]="speedup";//加速

uchar code lcd_desktop22[]="speeddn";//减速

uchar code num[]={'0','1','2','3','4','5','6','7','8','9'};//要显示的转速数字。

//-----lcd液晶屏头文件-----//

/**延时函数**/

void delayms(uchar xms)

{

uchar i,j;

for(i=xms;i>0;i--)

for(j=110;j>0;j--);

}

/****LCD写命令******/

void write_command(uchar com)//com写入命令

{

lcdrs=0;

P0=com;

delayms(2);

lcden=1;

delayms(2);

lcden=0;

}

/**************LCD写数据*********/

void write_data(uchar date)//数据为DATA

{

lcdrs=1;

P0=date;

delayms(2);

lcden=1;

delayms(2);

lcden=0;

}

/********LCD初始化****************/

void lcd_init()//显示模式设置

{

lcden=0;

write_command(0x38);

write_command(0x0c);

write_command(0x06);

write_command(0x01);

}

/**电机初始化函数**/

void motor_init(void)

{

ENA=0;                                //        停止

}

void ZhongDuanKaiQi(void)

{

EA=1;

ET0=1;        //计时器0允许中断。产生脉冲。

ET1=1;        //计时器1允许中断。对低电平进行计时。

//EX1=1;        //INT0允许中断。测速。由外部来启动。

IT1=1;        //低电平触发。

PX1=0;        //低级中断。

PT0=1;

PT1=0;

TMOD=0x12;//定时器工作方式控制

}

/***定时器T1初始化!!!等待外部脉冲的到来***/

void Timer1_init(void)

{

TH1=0;

TL1=0;                //等待外部脉的到来。INT1

}

/*****定时T0初始化*****/

void Timer0_init(void)

{

TH0=0;

TL0=0;

TR0=1;

}

/********测速模块,显示速度*******/

void speed_test(void)

{

//        TIMER1_COUNTER;

COUNTER_high=TH1;

COUNTER_low=TL1;

SUM=COUNTER_high*256+COUNTER_low+TIMER1_COUNTER*65536;//得到的是多少us。

SUM=SUM/1000;                                //化为毫秒。

SUM=1000/SUM;                                //圈每秒。

SUM=SUM*60;                                        //圈每分钟;三位数。

gewei=SUM%10;

shiwei=SUM/10%10;

baiwei=SUM/100;

write_command(0xc0);

write_data(baiwei);

write_command(0xc1);

write_data(shiwei);

write_command(0xc2);

write_data(gewei);

SUM=0;

TIMER1_COUNTER=0;

}

/********外中断1函数**********/

void INT1_QIDONG() interrupt 2

{

INT1_tingzhi++;

if(INT1_tingzhi==5)

{

INT1_tingzhi=5;EX1=0;//关闭中断。

}

if(INT1_tingzhi<=4)

{

INT1_FLAG++;

if(INT1_FLAG==2)

{

INT1_FLAG=0;TR1=0;speed_test();

}

else

{

Timer1_init();

TR1=1;

}

}

}

/******定时器T1计数*******/

void Timer1_QIDONG() interrupt 3

{

TIMER1_COUNTER++;

}

/**相位测量并输出!!!!!出现问题???**/

void xiangwei_test(void)

{

uchar i=0,j=0;

//while((P2^3==0)&&(P2^4==0));

//if((P2^3==0)&&(P2^4==0))

{

//delayms(5);

if(P2^3==1)

{

write_command(0x01);

write_command(0x80);for(i=0;i<=3;i++) write_data(lcd_desktop13[i]);//反转。

j++;//反转

}

if(P2^4==1)

{

write_command(0x01);

write_command(0x80);for(i=0;i<=3;i++) write_data(lcd_desktop12[i]);//正转。

j++;

}

}

}

/****T0中断发出信号并进行通道选择****/

void Timer0() interrupt 1

{

Timer0_flag--;

if((Timer0_BiaoZhi)>=(Timer0_flag))

{

if(KEY2==0)

{

Zheng=1;Fan=0;

}

else

{

Zheng=0;Fan=1;

}

}

else

{

Zheng=0;Fan=0;

}

if(Timer0_flag==0) Timer0_flag=5;

}

void Guan(void)

{

ET0=0;

EX1=0;

ET1=0;

}

void keyscan()                         //按键扫描函数

{

uint i=0;

if(key1==0)   //按键K1启动按钮。只有该位启动时,后面的几位才有效。启动T0计数开始发出脉冲。

{

delayms(10);

if(key1==0)

{

while(!key1);

KEY1=5;

Fan=0;

Zheng=0;

ENA=1;

KEY2=0;//初始化为正转。

Timer0_BiaoZhi=0;

Timer0_flag=4;

ZhongDuanKaiQi();//开启中断

Timer0_init();//                初始化并开始发出脉场外中断已经开启。

EX1=1;                                        //外中断开启;测速,显示速度。五次后结束关闭外中断1。出现问题!!!

write_command(0x80);

for(i=0;i

write_data(lcd_desktop12[i]);

}

}

if((key2==0)&&(KEY1=5)) //按键K2按下,(正转)只改变转向(标志位改变输出端口)

{

delayms(10);

if(key2==0)

{

while(!key2);

KEY2=0;                //正转标志,电机正向旋转。

//KEY2=(~1);

xiangwei_test();

KEY1=5;

}

}

if((key3==0)&&(KEY1=5)) //按键K3按下,(反转)只改变转向

{

delayms(10);

if(key3==0)

{

while(!key3);

KEY2=~0;                        //反转标志。

//KEY2=(~0);

xiangwei_test();

KEY1=5;

}

}

if((key4==0)&&(KEY1==5))        //按键K4按下,(加速)改变装入的数值?循环次数?执行if里面的语句,通过size++来改变幅值的频率

{

delayms(10);

if(key4==0)

{

while(!key4);

if(Timer0_BiaoZhi<4)

{

Timer0_BiaoZhi++;

}

else

{

Timer0_BiaoZhi=4;

}

EX1=1;

KEY1=5;

}

}

if((key5==0)&&(KEY1==5))         //按键K5按下,(减速)对其它标志位没有影响。

{

delayms(5);

if(key5==0)

{

while(!key5);

if(Timer0_BiaoZhi==0)

{

Timer0_BiaoZhi=0;

}

else

……………………

…………限于本文篇幅 余下代码请从51黑下载附件…………复制代码

所有资料51hei提供下载:

直流电机驱动.zip

(2.68 MB, 下载次数: 735)

2018-12-5 09:43 上传

点击文件名下载附件

标签: 9uf运转电容80uf450v运转电容

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台