難點:1、串口定時器T1,和T0定時器優先級
2、pwm頻率與占空比的設置
按鍵控制
按鍵1——前進
按鍵2——后退
按鍵3——加速
按鍵4——減速
(板子上只有四個按鍵)
串口控制
‘1’——前進
‘2’——后退
‘3’——加速
‘4’——減速
‘5’——左轉
‘6’——右轉
源碼:
#include <reg52.h>
typedef unsigned char u8;
typedef unsigned int u16;
//L298N引腳定義
sbit ena = P0^0;
sbit in1 = P0^1;
sbit in2 = P0^2;
sbit in3 = P0^3;
sbit in4 = P0^4;
sbit enb = P0^5;
//按鍵
sbit key1 = P3^3; //模擬前進
sbit key2 = P3^4; //模擬后退
sbit key3 = P3^6; //模擬加速
sbit key4 = P3^7; //模擬減速
u16 MA = 0,MB = 0; //pwm控制用
u16 SpeedA = 20; //50%占空比
u16 SpeedB = 20;
u8 flag; //標志,1代表前進,0代表后退
u8 cmd; //串口接收的命令sbuf
void delay(u16 z); //聲明延時函數
//前進
void forward()
{
flag = 1; //代表前進狀態
in1=1; //l298n手冊
in2=0;
in3=1;
in4=0;
}
//后退
void fallback()
{
flag = 0; //代表后退狀態
in1=0;
in2=1;
in3=0;
in4=1;
}
//加速
void quick()
{
SpeedA += 1; //每次加1
if(SpeedA >= 40) //最大40
{
SpeedA = 40;
}
SpeedB += 1;
if(SpeedB >= 40)
{
SpeedB = 40;
}
}
//減速
void slow()
{
SpeedA -= 1; //每次減1
if(SpeedA <= 5)//最小5
{
SpeedA = 5;
}
SpeedB -= 1;
if(SpeedB <= 5)
{
SpeedB = 5;
}
}
//左轉
void move_left() //只有前進的時候可以左轉
{
if(flag == 1) //前進狀態
{
in1=1;
in2=0;
in3=0;
in4=0;
delay(50000);
forward();
}
}
//右轉
void move_right() //只有前進的時候可以右轉
{
if(flag == 1) //前進狀態
{
in1=0;
in2=0;
in3=1;
in4=0;
delay(50000);
forward();
}
}
//停止
void stop()
{
in1=0;
in2=0;
in3=0;
in4=0;
}
void delay(u16 z)
{
u16 x,y;
for(x=z;x>0;x--)
for(y=125;y>0;y--);
}
void SendOneByte(u8 c) //串口發送數據
{
SBUF = c;
while(!TI);
TI = 0;
}
void main()
{
//串口定時器 定時器T0
TMOD = 0x21; //T0定時器為工作方式一,T1定時器為工作方式二
PCON = 0x00; //串口初始化相關,波特率
SCON = 0x50; //串口初始化相關,串口工作方式一,允許接收
TH1 = 0xFD; //設置初值
TL1 = 0xFD; //設置初值
TR1 = 1; //開啟定時器T1
TH0 = 0xF4; //設置初值
TL0 = 0x48; //設置初值
TR0 = 1; //開啟定時器T0
ES = 1;//開放串口中斷
//PS = 1; //串口中斷優先
PT0 = 1; //定時器0中斷優先
ET0 = 1;//開放定時器T0中斷
EA = 1;//開放總中斷
//按鍵控制小車
while(1)
{
if(key1 == 0)
{
delay(10);
if(key1 == 0)
{
forward();
SendOneByte(1);
}
while(key1 == 0);
}
if(key2 == 0)
{
delay(10);
if(key2 == 0)
{
fallback();
SendOneByte(2);
}
while(key2 == 0);
}
if(key3 == 0)
{
delay(10);
if(key3 == 0)
{
quick();
SendOneByte(3);
}
while(key3 == 0);
}
if(key4 == 0)
{
delay(10);
if(key4 == 0)
{
slow();
SendOneByte(4);
}
while(key4 == 0);
}
}
}
void time0_int() interrupt 1 //T = 3ms * 40 = 120ms
{
TR0 = 0;
TH0 = 0xF4;
TL0 = 0x48; //3000; 3ms
MA++;
if(MA < SpeedA)
{
ena = 1;
}
else
ena = 0;
if(MA == 40)
{
MA = 0;
}
MB++;
if(MB < SpeedB)
{
enb = 1;
}
else
enb = 0;
if(MB == 40)
{
MB = 0;
}
TR0 = 1;
}
void UARTInterrupt(void) interrupt 4
{
if(RI)
{
RI = 0;
//add your code here!
cmd = SBUF;
SendOneByte(cmd);
//串口控制小車
switch (cmd)
{
case 1:
forward();
SendOneByte(1);
break;
case 2:
fallback();
SendOneByte(2);
break;
case 3:
quick();
SendOneByte(3);
break;
case 4:
slow();
SendOneByte(4);
break;
case 5:
move_left();
SendOneByte(5);
break;
case 6:
move_right();
SendOneByte(6);
break;
default:
SendOneByte(7);
break;
}
}
}
結束!
