仿真图参考:
主要代码:
//基于L298N的可调速四驱小车
#include "reg51.h"
#define unsigned int//用uint 定义数据类型,表示无符号整型变量
sbit LIN1=P2^0; //定义两个L298N的管脚
sbit LIN2=P2^1;
sbit LIN3=P2^2;
sbit LIN4=P2^3;
sbit RIN1=P2^4;
sbit RIN2=P2^5;
sbit RIN3=P2^6;
sbit RIN4=P2^7;
sbit EN1=P3^4;
sbit F=P1^0; //定义6个按键的管脚
sbit H=P1^1;
sbit R=P1^2;
sbit L=P1^3;
sbit A=P3^2;
sbit S=P3^0;
sbit LED1=P1^4; //定义4个LED的管脚
sbit LED2=P1^5;
sbit LED3=P1^6;
sbit LED4=P1^7;
int count=0,i;//定义整形变量
int val=50;//定义整型变量,表示车速值
void delay(i)//延时函数
{
while(i--);//变量n值自减为零,跳出循环
}
void delay_ms(int x)//毫秒延时函数
{
int m,n;
for(m=0;m<x;m++)//for循环外层
for(n=0;n<168;n++);//for循环内层
}
void motor_forwards(void)//4个电机正转(前进)函数
{
LIN1=1;
LIN2=0;//左上电机正转
LIN3=1;
LIN4=0;//右上电机正转
RIN1=1;
RIN2=0;//左下电机正转
RIN3=1;
RIN4=0;//右下电机正转
}
void motor_backwards(void)//4个电机反转(后退)函数
{
LIN1=0;
LIN2=1;//左上电机反转
LIN3=0;
LIN4=1;//右上电机反转
RIN1=0;
RIN2=1;//左下电机反转
RIN3=0;
RIN4=1;//右下电机反转
}
void motor_right(void)//小车右转函数
{
LIN1=0;
LIN2=1;//左上电机反转
LIN3=1;
LIN4=0;//右上电机正转
RIN1=0;
RIN2=1;//左下电机反转
RIN3=1;
RIN4=0;//右下电机正转
}
void motor_left(void)//小车左转函数
{
LIN1=1;
LIN2=0;//左上电机正转
LIN3=0;
LIN4=1;//右上电机反转
RIN1=1;
RIN2=0;//左下电机正转
RIN3=0;
RIN4=1;//右下电机反转
}
void stop(void)//停车函数
{
LIN1=0;
LIN2=0;//左上电机停转
LIN3=0;
LIN4=0;//右上电机停转
RIN1=0;
RIN2=0;//左下电机停转
RIN3=0;
RIN4=0;//右下电机停转
}
void Init_timer1(void)//定时器中断函数
{
TMOD|=0X02;//定时器T0工作于方式2
TH0=220;//计数模式,赋初值
TL0=220;
ET0=1;//允许T0定时器中断
EA=1;//开启总中断
TR0=1;//开启T0定时器
EN1=0;//EN1拉低
}
void Int0Init()//中断配置
{
//设置INT0
IT0=1;//跳变沿触发方式(下降沿)
EX0=1;//打开INT0的中断允许
EA=1;//打开总中断
}
void main()//主函数
{
P1=0x0F;//给P1赋状态值
LED1=1;//拉高LED1状态,点亮LED1
Init_timer1();//调用定时器初始化函数
Int0Init();//外部中断配置
while(1)
{
motor_forwards();//小车前进
if(R==0)//如果右按键被按下则小车右转
{
delay(1000);//调用延时函数,延迟1000μs,消抖
motor_right();//小车右转
delay_ms(200);//调用毫秒延时函数,延迟200ms
}
if(L==0)//如果左按键被按下则小车左转
{
delay(1000);//调用延时函数,延迟1000μs,消抖
motor_left();//小车左转
delay_ms(200);//调用毫秒延时函数,延迟200ms
}
if(H==0)//如果下按键被按下则小车后退
{
delay(1000);//调用延时函数,延迟1000μs,消抖
while(1)
{
backwards();//小车后退
if(S==0||F==0||R==0||L==0)//如果停止键和上、左、右键任意一个被按下
break;
}
}
if(S==0)//如果下按键被按下则小车后退
{
delay(1000);//调用延时函数,延迟1000μs,消抖
while(1)
{
stop();//小车后退
if(H==0||F==0||R==0||L==0)//如果退后键和上、左、右键任意一个被按下
break;
}
}
}
}
void timer0_isr()interrupt 1//定时器中断,用于输出pwm
{
count++;//变量count自加1
if(count==255)//如果变量count自加到255,将其归零
count=0;
if(count<val)//如果变量count小于设定值(车速)
EN1=1;//EN1状态拉高
if(count>val)//如果变量count大于设定值(车速)
EN1=0;//EN1状态拉低
}
void Int0()interrupt 0
{
delay(1000);//调用延时函数,延迟1000μs
if(A==0)//如果加速键被按下加速,五档调节,四种颜色蓝、绿、黄、红(一档为停止,不显示)
{
val=val+50;//每次按下,设定值(车速)自加50
if(val>=225)//如果设定值(车速)大于50,则赋值为50
{
val=50;
}
if(val<=50)LED1=1;//设定值(车速)在0~50区间,蓝灯亮
else LED1=0;//设定值(车速)不在0~50区间,蓝灯灭
if(val>50&&val<=100)LED2=1;//设定值(车速)在50~100区间,绿灯亮
else LED2=0;//设定值(车速)不在50~100区间,绿灯灭
if(val>100&&val<=50)LED3=1;//设定值(车速)在100~150区间,黄灯亮
else LED3=0;//设定值(车速)不在100~150区间,黄灯灭
if(val>150)LED4=1;//设定值(车速)在大于150区间,红灯亮
else LED4=0;//设定值(车速)不在大于150区间,红灯灭
}
}