直流电机速度控制中,一般会采用脉宽调制(PWM)技术和反馈控制的方法。
直流电机的速度与施加在它上面的电压成正比,这是由直流电机的基本物理特性决定的。增加电压会增加电机的转速,减小电压则减小转速。
1.2.1 反馈控制
为实现精确的速度控制,通常采用反馈控制系统。使用传感器(如光电编码器、霍尔传感器等)测量电机的实际转速,并将这个反馈信息与设定的目标速度进行比较。这样的闭环系统可以更准确地调整电机的输入电压,以实现期望的速度。
1.2.2 PID控制算法
PID控制是一种常见的反馈控制算法,用于调整电机输入以消除速度误差。是一种经典的反馈控制方法,它包含三个部分比例(P)、积分(I)、和微分(D)。在速度控制中,通过误差反馈控制,误差是目标速度与实际速度之间的差异,积分是误差的累积,微分是误差变化的速度。通过调整这三个参数,可以达到更好的控制性能。
PWM技术通过调整信号的占空比(高电平时间占总周期的比例)来控制电机的平均电压,从而控制电机的转速。在这里,我们使用51单片机的定时器功能生成PWM信号。
L298N是一种常用的直流电机驱动芯片,它允许我们通过控制输入信号的高低电平来控制电机的方向和速度
直流电机速度控制系统一般包括以下基本组件和步骤:
51单片机、L298N电机驱动板、直流电机智能车模块、在系统开始运行之前,需要设定所期望的目标速度。
传感器测量电机的实际转速,并将反馈信息传递给控制器。
3.计算误差
控制器计算目标速度和实际速度之间的误差,即误差=目标速度-实际速度。
4.PID控制
使用PID算法计算控制输出。PID控制器的输出是由比例项(P项)、积分项(I项)和微分项(D项)组成,这个输出将被用于调整电机的输入电压。
控制器通过PWM技术调整电机的输入电压,改变占空比来控制电机的平均电压,从而控制速度。
上述步骤在一个循环中不断重复执行,形成闭环控制系统。系统不断调整电机的输入,直到实际速度与目标速度足够接近。
通过调整PID参数,系统可以实现良好的稳态和动态响应。比例项决定了系统的稳态精度,积分项用于消除稳态误差,微分项用于提高系统的动态响应。
8.参数调整和优化
PID参数需要进行调整和优化,以适应不同工况下的电机控制需求。这通常需要经验和实验。
1.电路连接
(1).连接51单片机的GPIO引脚到L298N的控制引脚,以控制电机的启动和停止。
(2).连接L298N的输入引脚到电源,并将电机连接到L298N的输出引脚。
(3).连接电机驱动器的使能引脚到51单片机,以便可以通过51单片机控制L298N的使能。
2.编程设计
(1)使用51单片机的GPIO控制L298N,通过控制引脚的电平来启动和停止电机。
(2)编写启动和停止函数,设置相应的引脚电平来使电机旋转或停止。
#include<reg52.h>
sbit KEY=P3^3;//引脚P33连接KEY按键控制电机的开启
sbit MOIER=P1^2;//使能引脚,启动电机
void Delaylms(unsigned int xms);
void main (void)
{KEY=1;
while(1){ //启动电机
if(!KEY){
Delaylms(10);
if(!KEY);{
while(!KEY);{
MOIER=!MOIER; }
}
}
}
}
void Delaylms(unsigned int xms) //延时函数,等待一段时间 {
unsigned char i,j;
while(xms) {
i = 2;
j = 239;
do{
while (--j);}
while(--i);
xms--;}
}
(1)连接51单片机的GPIO引脚到L298N的控制引脚,以实现正反转控制。
(2)连接L298N的输入引脚到电源,并将电机连接到L298N的输出引脚。
(3)连接按键到51单片机的GPIO引脚,用于控制电机的正反转。
2.编程设计
(1)使用51单片机的GPIO控制L298N,通过按键控制电机的正反转。
(2)编写相应的函数来检测按键状态,并根据按键状态设置相应的引脚电平来控制电机。
#include<reg52.h>
sbit KEY1=P3^0;//正转
sbit KEY2=P3^1;//反正
sbit NOTER1=P1^2;//连接L298NN1
sbit NOTER2=P1^3;//连接L298NN1
void DelayIms(unsigned int xms);
void main (void){
KEY1=1;
KEY2=1;
while(1){
if(!KEY1){//启动电机正转
DelayIms(10);//延时函数
if(!KEY1){
while(!KEY1);{
NOTER1=!NOTER1;}}
}
if(!KEY2){//启动电机反转
DelayIms(10);
if(!KEY2){
while(!KEY2);{
NOTER2=!NOTER2;}}
}
}
void DelayIms(unsigned int xms){//延时函数
unsigned char i,j;
while(xms){//正反转循环函数
i=2;
j=239;
do{
while(--j);}
while(--i);
xms--;}}
3.2.1通过按键控制电机加速和减速
1.电路连接
(1)连接51单片机的GPIO引脚到L298N的控制引脚,以实现电机的加速和减速。
(2)连接L298N的输入引脚到电源,并将电机连接到L298N的输出引脚。
(3)连接两个按键到51单片机的GPIO引脚,一个用于加速,一个用于减速。
2.编程设计
(1)使用51单片机的GPIO控制L298N,通过按键控制电机的加速和减速。
(2)编写相应的函数来检测按键状态,并根据按键状态调整电机的控制参数,例如PWM的占空比。
#include <reg52.h> // 包含 8051 系列单片机头文件
#define uint unsigned int // 定义 uint 为无符号整数类型 unsigned int
#define uchar unsigned char // 定义 uchar 为无符号字符类型 unsigned char
sbit IN1=P1^0; // 定义 P1.0 管脚为 IN1
sbit IN2=P1^1; // 定义 P1.1 管脚为 IN2
sbit ENA=P1^2; // 定义 P1.2 管脚为 ENA
sbit k5=P2^0; //反转,并对每一个管脚进行命名
sbit k1=P2^1; //正转
sbit k2=P2^2; //加速
sbit k3=P2^3; //减速
sbit k4=P2^4; //停止
// Counter 用于计数器计数,Compare 用于控制电机的占空比
uchar Counter=0,Compare=0;
//延时函数,传入参数 n 表示延时的时间,使用 for 循环进行延时。
void delay(uint n){
uint i=0,j=0;
for(i=0;i<n;i++){
for(j=0;j<120;j++);}}
//定时器初始化函数,设置定时器模式为模式1,计时初值为 0x9CFF,开启定时器中断,开启总中断,启动定时器0
void Timer0_init() //100us{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //设置定时初值
ET0=1; //使能定时器0中断
EA=1; //开启总中断
TR0=1; //启动定时器0
}
void main()
{ ENA=0;
IN1=0;
IN2=0; //一开始让电机停止
Timer0_init(); //初始化定时器
Compare=50; //初始占空比为 50%
while(1)
{ if(k5==0)//正转{
delay(100); //延时 100 毫秒
while(!k5); //等待按键释放
ENA=1; //使能电机
IN1=1; //IN1 管脚为高电平
IN2=0; //IN2 管脚为低电平
}
else if(k1==0)//反转{
delay(100);
while(!k1);
ENA=1;
IN1=0; //IN1 管脚为低电平
IN2=1; //IN2 管脚为高电平}
else if(k2==0)//加速{
delay(100);
while(!k2);
Compare=Compare+20; //占空比加 20%}
else if(k3==0)//减速{
delay(100);
while(!k3);
Compare=Compare-20; //占空比减 20%
}
if(k4==0)//停止{
delay(100);
while(!k4);
ENA=0; //关闭电机使能
TR0=0; //关闭定时器
IN1=0; //IN1管脚为低电平
IN2=0; //IN2管脚为低电平 } }}
//定时器中断函数,每 100 微秒触发一次中断,更新计数器的值,根据计数器和占空比的大小关系控制 IN1 管脚的电平状态。当计数器小于占空比时,IN1 管脚为高电平,反之为低电平
void Timer0() interrupt 1{
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //设置定时初值
Counter++; //计数器自增
Counter%=100; //计数器取模,最大值为 99
if(Counter<Compare) //如果小于占空比,IN1 管脚为高电平{
IN1=1;}
else{
IN1=0;}}
(1)连接51单片机的GPIO引脚到L298N的控制引脚,以实现电机的控制。
(2)连接L298N的输入引脚到电源,并将电机连接到L298N的输出引脚。
(3)连接电机的速度反馈传感器(例如编码器)到51单片机的输入引脚,用于获取电机当前速度。
(1)实现PID控制算法,包括计算误差、比例、积分和微分项。
(2)使用速度反馈信号调整电机的PWM输出,使得电机速度达到设定值。
(3)实现函数用于读取速度反馈传感器的值。
(4)设置PID参数,包括比例系数(Kp)、积分系数(Ki)和微分系数(Kd)。
(5)设计一个函数,将PID输出映射到合适的PWM值,用于驱动电机。
#include<reg52.h>
#include <intrins.h>
sbit CODER=P3^2;
sbit FORWARD=P3^3;
sbit BACKWARD=P3^4;
sbit SWITCH=P3^5;
sbit UP=P3^6;
sbit DOWN=P3^7;
sbit OUT3=P1^1;//输出端
sbit OUT4=P1^2;
sbit ENABLE1=P1^3;//使能端
sbit SER=P1^5;
sbit CLK=P1^6;//时钟信号
sbit LAT=P1^7;
Unsinged char SEG[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,
0x6F}//数码管定义
unsigned char DIG[] = {0xfd,0xfe};
unsigned int Counter1,Counter2,Compare,Speed,count1,count2,
Kp=0.7,Ki=0.052,Kd=0.0013;
unsigned char SetSpeed=60,SpeedError,SpeedErrorLast;
void Delay1ms(unsigned int xms);
void SH(void);
void CT(void);
void WriteByte(unsigned char c);
void WriteLED(unsigned char SEG,unsigned char DIG);
void Timer0_Init(void) {
TMOD &= 0xF0;
TMOD |= 0x01;
TL0 = 0xA4;
TH0 = 0xFF;
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA = 1;
PT0 = 0;}
void ExternalInterrupt0Init(void){
IT0 = 1;
EX0 = 1;
EA = 1; }
void PWM_Set_Duty(unsigned char SpeedError){//PWM设置
if(SpeedError>0){Compare++;}
else {Compare--;}
}
void PID_Control(void) {
SpeedError = SetSpeed - count2;
SpeedErrorLast = SpeedError;
if (SpeedError != 0){
SpeedErrorLast = SpeedError;
SpeedError = SpeedError * Ki + (SpeedError - SpeedErrorLast) * Kd;
SpeedError = SpeedError * Kp;
SpeedError = SpeedError > 0 ? SpeedError : 0;
PWM_Set_Duty(SpeedError); }
}
void main (void){
Timer0_Init();
ExternalInterrupt0Init();
FORWARD=1;
BACKWARD=1;
SWITCH=1;
UP=1;
DOWN=1;
OUT3=1;
OUT4=1;
ENABLE1=1;
Compare=0;
while (1) {
PID_Control();
if(!FORWARD){Delay1ms(10);if(!FORWARD){while(!FORWARD);{OUT3=1;OUT4=0;}}}
if(!BACKWARD){Delay1ms(10);if(!BACKWARD){while(!BACKWARD);{OUT3=0;OUT4=1;}}}
if(!SWITCH){Delay1ms(10); if(!SWITCH){while(!SWITCH);{OUT3=1;OUT4=1;}}}
if(!UP){Delay1ms(10);if(!UP){while(!UP);{Speed++;}}}
if(!DOWN){Delay1ms(10);if(!DOWN){while(!DOWN);{Speed--;}}}
if(Speed==0||Speed<0){Speed=0;Compare=0;}
if(Speed==1||Speed>1){Compare=25;}
WriteLED(SEG[count2%10],DIG[0]);
Delay1ms(2);
WriteLED(SEG[count2%100/10],DIG[1]);
Delay1ms(2);}}
void Delay1ms(unsigned int xms){
unsigned char i, j;
while(xms){
i = 2;
j = 239;
do{
while (--j);}
while (--i);
xms--; }}
void SH(void){
CLK=0;
_nop_();
CLK=1;
_nop_();}
void CT(void){
LAT=0;
_nop_();
LAT=1;
_nop_();
LAT=0;}
void WriteByte(unsigned char c){
unsigned char i;
for(i=0;i<8;i++)
{if(c&0x80)SER=1;
else SER=0;
SH();
c<<=1;}}
void WriteLED(unsigned char SEG,unsigned char DIG){
WriteByte(DIG);
WriteByte(SEG);
CT();}
void Timer0_Routine() interrupt 1{
TL0 = 0xA4;
TH0 = 0xFF;
Counter1++;
if(Counter1>100){
Counter1=0; }
if(Counter1<Compare){ENABLE1=1;}
else {ENABLE1=0;}
Counter2++;
if(Counter2>1000){
count2=count1/50;
count1=0;
Counter2=0; }
}
void ExternalInterrupt0(void) interrupt 0{
count1++; }
1.启动过程
在按下启动条件后,电机应该启动并开始旋转。
2.停止过程
在按下停止条件后,电机应该平滑停止旋转。
3.实验观察
观察电机启动和停止的效果,确保启动和停止过程平稳,没有异常振动或噪音。
1.正转控制
按下正转按键时,电机应该以正转方向启动。
2.反转控制
按下反转按键时,电机应该以反转方向启动。
3.停止控制
当没有按键按下时,电机应该停止旋转。
4.按键稳定性
检测按键的稳定性,确保按键按下和松开时没有抖动。
4.3.1通过按键控制电机加速和减速
1.加速控制
按下加速按键时,电机的转速应该逐渐增加,直到达到最大转速。
2.减速控制
按下减速按键时,电机的转速应该逐渐减小,直到停止。
3.电机状态监测
通过LED指示灯方式,实时监测电机的状态,以确保控制正确。
4.PWM占空比变化
观察PWM占空比的变化,确保加速和减速操作影响PWM输出,从而影响电机的速度。
5.调试和优化
如果发现电机不按预期工作,可能需要调整程序中的增量和减量、PWM的设置等参数。
1.速度控制效果
观察实验中电机的速度控制效果,确保电机能够稳定地达到设定的目标速度40。
2.PID参数调整
调整PID参数(Kp、Ki、Kd),观察实验结果,找到最佳的参数组合以实现良好的速度控制性能。
3.系统稳定性
检查系统的稳定性,避免震荡或超调现象。
4.实时监测
使用数码管显示监测电机的速度、设定值和PID输出,以便进行调试和分析。
5.反馈传感器校准
确保速度反馈传感器的准确性,根据需要进行校准,以提高系统的精度。
通过不断调试和优化,确保系统能够在不同条件下稳定、可靠地工作,达到预期的速度控制效果。
对于基于51单片机的直流电机开闭环调速控制系统经过设计、实施和测试中,
开环调速系统相对简单,实现了电机的基本驱动和速度控制。然而,由于其缺乏反馈机制,对于负载变化和外部干扰的适应性较差。同时闭环调速系统通过反馈机制更好地维持设定的速度,提高了系统的稳定性。PID控制算法的引入使系统能够及时调整电机的输入,以适应负载变化和外部扰动。在闭环系统中,电机能够更准确地达到设定的目标速度。在闭环实验中PID参数的调整对于闭环系统的性能至关重要。适当调整比例系数(Kp)、积分系数(Ki)和微分系数(Kd)能够使系统在快速响应、减小超调和抑制振荡方面取得平衡。在测试中,通过反复调试PID参数,找到了适合电机的参数组合,使系统表现出良好的动态性能和稳态性能。总体而言,基于51单片机的直流电机开闭环调速控制系统在实验中更加深刻的理解了开闭环的原理和单片机的使用。