基于51单片机的直流电机控制.docx
- 文档编号:8513566
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:13
- 大小:170.36KB
基于51单片机的直流电机控制.docx
《基于51单片机的直流电机控制.docx》由会员分享,可在线阅读,更多相关《基于51单片机的直流电机控制.docx(13页珍藏版)》请在冰豆网上搜索。
基于51单片机的直流电机控制
基于51单片机的
直流电机控制
一、试验器件选择
1、控制芯片的作用主要是与L289相连接驱动直流电机,以及与八位数码管相连显示。
(1)、AT89C51是一种带4K自己FLASH存储器的低压、高性能CMOS8为微处理器。
单片机的可擦除只读存储器可以反复擦除1000次。
该器件采用ATMEL高密度非易失真存储制造技术制造,与工业标准的MCS-51指令集和输出关键相兼容。
由于将多功能8位CPU和闪存组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器。
AT89C51单片机为很多嵌入式控制系统提供了一种灵活性奥高且廉价的方案。
(2)、AT89C51引脚图如下:
2、电机驱动芯片
(1)、电机驱动芯片选择L298。
其主要功能是作为单片机与直流电机中间的过度链接,单片机输出的信号通过L298加载到直流电机上驱动直流电机运行。
其引脚图如下:
(2)、主要工作原理:
1、15脚分别是两个H桥的电流反馈脚,不用时可以直接接地;
2、3为一对输出端口,13、14为一对输出端口;
4为驱动电压输入,最小值必须比输入的低电平高2;
5、7一对输入端口,10、12一对输入端口,TTL电平兼容
6、11使能端,低电平禁止输出;
8、9分别为接地和逻辑电源
3、直流电机。
在protues中选择motor-encoder直流电机,引脚图如下:
上方左右的两个引脚在点击运转时输出频率相同的方波,但是在相位上相差90
,而且在正转和反转是相反,因此可以根据这两个引脚的输出情况判断点击的转向。
上方中间的引脚每当电机转一圈就输出一个正脉冲,可以据此册数点击的转速。
左右两个引脚是电机的电压输入端。
4、74HC74。
当D触发器的D和CLK输入端分别接电机上方的左右两个输出端口时可以根据D触发器的输出情况判断点击的转速。
5、八位数码管。
用以显示。
二、系统硬件设计连接
1、系统的器件连接图如下:
2、单片机与数码管通过P0口和P2口相连,其中P2口选择点亮哪一个数码管,P0口则控制被点亮的数码管显示的数据。
3、单片通过P1^0和P1^1和L298的第一对输入端IN1和IN2相连,然后又L298的第一对输出端OUT1和OUT2与直流电机相连,已达到控制直流电机的目的。
4、从P1^4到P1^7分别接一个Button按钮来实现PID控制,P3^6和P3^7分别接Button按钮实现对电机的加速与减速控制。
5、双刀双掷开关SW1课实现点击的正转与反转,单刀双掷开关SW2可实现点击的开启与停止。
三、系统程序设计及功能实现
1、程序流程图:
2、各部分实现程序:
(1)、普通延时:
#include
voiddelayms(unsignedcharx)
{
unsignedchari;
while(x--)
for(i=0;i<120;i++);
}
(2)、数码管显示:
#include
#include
#include
voiddisplay_lilun(doublenum)
{
charcodetable[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,//0~7对应数码
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//8~F对应数码
longintn=num;
P0=0;P2=0x7f;P0=table[n%1000/100];delayms
(2);//百位加小数点
P0=0;P2=0xbf;P0=table[n%100/10];delayms
(2);//十位
P0=0;P2=0xdf;P0=table[n%10];delayms
(2);//个位
P0=0;//关闭显示器
}
voiddisplay(doublenum,intdir)
{
charcodetable[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,//0~7对应数码
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//8~F对应数码
longintn=num*10;
P0=0;P2=0xf7;P0=table[n/1000];delayms
(2);//百位加小数点
P0=0;P2=0xfb;P0=table[n%1000/100];delayms
(2);//百位加小数点
P0=0;P2=0xfd;P0=table[n%100/10]+128;delayms
(2);//十位
P0=0;P2=0xfe;P0=table[n%10];delayms
(2);//个位
P0=0;//关闭显示器
if(dir==1)
{
P0=0;P2=0xef;P0=0x40;delayms
(2);
}
}
(3)、按键扫描:
#include
sbitjiashi=P1^3;//对各个按钮进行位定义
sbitjianshi=P1^4;
sbitjia=P1^5;
sbitjian=P1^6;
sbitenter=P1^7;
externintnum_key[5];//定义全局变量
voidkeyscan()
{
if(jiashi==0)
{
while(!
jiashi);
num_key[0]++;
}
if(jianshi==0)
{
while(!
jianshi);
num_key[1]++;
}
if(jia==0)
{
while(!
jia);
num_key[2]++;
}
if(jian==0)
{
while(!
jian);
num_key[3]++;
}
if(enter==0)
{
while(!
enter);
num_key[4]++;
}
}
(4)、PWM波输出:
#include
#include
#include
externintPWM;//赋初值
externintstart,sudu_lilun;
externdoubledis_count;
sbitS2=P3^6;//PWM值减少键
sbitS3=P3^7;//PWM值增加键
voidPWM_duty()
{
if(start>=1)
PWM=sudu_lilun;
do
{
if(PWM!
=0xff)
{
PWM++;
delayms(10);
}
}
while(S3==0);
do
{
if(PWM>=0x02)
{
PWM--;
delayms(10);
}
}
while(S2==0);
}
(5)、中断服务程序:
#include
externintPWM,count,count1,dir,count20ms_flag;
externdoubledis_count;
sbitPWM_OUT1=P1^1;
sbitPWM_OUT2=P1^0;
voidtimer0()interrupt1
{
longinti;
TR1=0;
dir=0;
TL0=0x00;
TH0=0xd8;//10ms
TL0=0xf0;
TH1=PWM;
TR1=1;
PWM_OUT1=0;//启动输出
PWM_OUT2=0;
if(i++==492)
{
count20ms_flag=1;
i=0;
dis_count=(double)(count+count1)/2;
count=0;
count1=0;
}
}
voidtimer1()interrupt3
{
TR1=0;
if(dir==0)
{
PWM_OUT1=1;//结束输出
PWM_OUT2=0;
}
else
{
PWM_OUT1=0;
PWM_OUT2=1;
}
}
voidEIRQ0(void)interrupt0
{
EX0=0;
count++;
EX0=1;
}
voidEIRQ1(void)interrupt2
{
EX1=0;
count1++;
EX1=1;
}
(6)、PID控制:
#include
#include
intP,I,D;
externintsudu_lilun;
typedefstructPID//定义结构体
{
intSetPoint;//目标
longSumError;//误差
doubleProportion;//比例系数
doubleIntegral;//积分系数
doubleDerivative;//微分系数
intLastError;
intPrevError;
}PID;
staticPIDsPID;
staticPID*sptr=&sPID;
voidIncPIDInit()
{
sptr->SumError=0;
sptr->LastError=0;//Error[-1]
sptr->PrevError=0;//Error[-2]
sptr->Proportion=0.5;//比例系数
sptr->Integral=0.3;//积分系数
sptr->Derivative=0.3;//微分系数
sptr->SetPoint=sudu_lilun;
}
intIncPIDCalc(intNextPoint)
{
registerintiError,iIncpid;//当前的误差值
iError=sptr->SetPoint-NextPoint;//计算增加量
iIncpid=sptr->Proportion*iError//E[k]项
-sptr->Integral*sptr->LastError//E[k-1]项
+sptr->Derivative*sptr->PrevError;//E[k-2]项
//存储当前误差以便后面计算
sptr->PrevError=sptr->LastError;
sptr->LastError=iError;
//返回增量值
return(iIncpid);
}
(7)、main函数:
#include
#include
#include
#include
#include
#include
#include
sbitP10=P1^2;//确定电机转向
intnum_key[5];
intPWM,PWM1,count,count1,dir,sudu_lilun,start,count20ms_flag;
doubledis_count;
intPWM_PID;
voidinit();
voidmain()
{
init();
while
(1)
{
PWM_duty();
if(P10==1)
dir=0;
else
dir=1;
keyscan();
sudu_lilun=num_key[0]*10-num_key[1]*10+num_key[2]-num_key[3];
display_lilun(sudu_lilun);
if(num_key[4]==1)
start=1;
display(dis_count,dir);
if(start>=1&&count20ms_flag==1)
{
count20ms_flag=0;
IncPIDInit();
PWM_PID=IncPIDCalc(dis_count);
PWM=PWM+PWM_PID*2;
}
}
}
voidinit()//定时器、外部中断初始化
{
TMOD=0x01;
TH0=0xd8;
TL0=0xf0;
IT0=1;
EX0=1;
IT1=1;
EX1=1;
TH1=PWM;
TL1=0xff;
EA=1;
ET0=1;
ET1=1;
TR0=1;
}
3、程序实现效果:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 51 单片机 直流电机 控制