×
单片机 > 单片机程序设计 > 详情

基于51单片机的L298N直流电机调速系统

发布时间:2023-06-28 发布时间:
|

本此设计选择STC89C52单片机作为主控芯片,选取带有光电编码器的直流电机作为被控对象,利用单片机的T0定时器产生PWM信号并送到直流电机。在Proteus仿真环境下搭建了L298N直流电机驱动电路、矩阵键盘扫描电路以及LCD12864显示电路。实现了直流电机的启动、加速、正转、反转、制动等功能。同时,采用PID控制算法可实现电机速度在特定的场合实现自动切换。

单片机源程序如下:

#include

#include

#include


#include "lcd.h"

#include "Key.h"

#include "Motor.h"

#include "LCD12864.h"

#include "KeyBoard.h"

#include "LCD12864.h"

#include "LcdShow.h"

#include "PID.h"


extern uchar State_Flag;

extern uchar Fwd_Flag;

extern uchar Rev_Flag;


unsigned int KeyValue;


unsigned int idata pwm_t;//周期

unsigned int idata Impluse,Time_Count,ImpluseR;

uchar idata Stop_Flag,Run_Flag,Curve_Flag;


uint idata Set_Speed; // 设定转速

unsigned char idata Sz_Flag,Sr_Flag; // 记录A相触发后 ,B相高低电平的标志

float idata L_Speed,R_Speed,ReaSpeed;


uint idata PWM_Out,R_Duty,L_Duty,Turn_now;

sbit LSB_L = P1^0; // LSB_L

sbit LSB_R = P1^1; // LSB_R


void TimerInit(void) //@11.0592MHz

{

TMOD=0x01; //定时器模式


TL0 = 0x18; //初值 1ms

TH0 = 0xFC; //初值

IT0 = 1; //设置下降沿触发 还是低电平触发 0低电平

IT1 = 1; //设置下降沿触发 还是低电平触发 0低电平

EA = 1;

EX0 = 1;

EX1 = 1;

ET0 = 1;

TR0 = 1;


}


void main()

{

LED = 0;

Stop_Flag = 0;

Lcd_Initial();

TimerInit();

Set_Speed = 0;

Lcd_Clear();

while(1)

{

KeyValue = Get_Keyvalue(); // 矩阵键盘扫描

if(KeyValue == 14) // 输入速度

{

Set_Speed = SpeedInput();

KeyValue = 16;

}

Key_Process();

if(Run_Flag)

{

Set_Speed = 80;

Run_Flag = 0;

}

if(State_Flag && ~Stop_Flag)

{

PWM_Out = PID_Calculate(Set_Speed,abs(ReaSpeed));

R_Duty = PWM_Out + Turn_now;

L_Duty = PWM_Out - Turn_now;

}

else

PWM_Out = 0; // 停止

Lcd_Show();

}

}


//定时器0中断

void timer0() interrupt 1

{

static int i;

TL0 = 0x18; //初值

TH0 = 0xFC; //初值

pwm_t++;

Time_Count++;;

if(pwm_t == 500) //500ms

{

pwm_t = 0;

if(Stop_Flag)

{

i++;

L_Duty = 0;

R_Duty = 0;

if(i<31)

{

LED = ~LED;

if(i == 30)

{

Stop_Flag = 0;

i = 0;

Set_Speed = 30;

}

}

}

}

if( pwm_t

MotorL_Control();

else

MotorL_Stop();

if( pwm_t

MotorR_Control();

else

MotorR_Stop();

/*---------M法 测速------------*/

if(Time_Count == 100 ) // 100ms

{

Control();

Time_Count = 0;

Impluse = 0;

ImpluseR = 0;

}

}



void int0() interrupt 0

{

Impluse++;

if(LSB_L == 1)

Sz_Flag = 1; // 正反转标志位 A相下降沿,B相高电平

else Sz_Flag = 0;

LSB_L = 1;

}



void int1() interrupt 2 // 外部中断1 用于测 右轮的速度

{

ImpluseR++;

if(LSB_R == 1)

Sr_Flag = 1; // 正反转标志位 A相下降沿,B相高电平

else Sr_Flag = 0;

LSB_R = 1;

}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM微处理器的液晶触摸屏接口设计