如下为STC89C52单片机制作智能小车,蓝牙遥控,红外循迹均可单独使用,两个功能整合在一起时候蓝牙遥控指令只有红外循迹可使用了,其他指令小车不执行对应动作,请问代码是哪里有问题,望指出,感谢!
1、怀疑蓝牙发1-6时候,电机驱动并未使能,所以相应动作未执行,不太确认是否是Timer0定时器未工作原因?
2、我用Timer0做电机驱动使能控制,Timer1做Uart,可T0的中断优先级比T1的要高,如何让两个同时用而不冲突呢?
3、另外,是否能在主函数给电机驱动定义变量,其他子函数,包括中断都能调用呢?如下代码有在主函数定义变量,同时在红外循迹中也定义了相同变量,如不定义,无法编译
以上问题,希望各位大神指点下思路。
主函数
#include <REGX52.H>
#include "UART.H"
#include "MotorDrive.H"
#include "Timer0.H"
#include "IR_Tracking.H"
sbit L298N_ENA=P1^4;
sbit L298N_ENB=P1^5;
sbit L298N_ENA1=P1^1;
sbit L298N_ENB1=P0^2;
extern unsigned char Compare,Compare1,Compare2,Compare3;
extern unsigned char Counter,Counter1,Counter2,Counter3;
void main()
{
UART_Init();
Timer0_Init();
// L298N_ENA=1;
// L298N_ENB=1;
// L298N_ENA1=1;
// L298N_ENB1=1;
while(1)
{
}
}
void Timer0_Routine() interrupt 1
{
TL0=0xA4; //设置定时初值
TH0=0xFF; //设置定时初值
Counter++;
Counter%=100; //计数值变化范围限制在0~99
Counter1++;
Counter1%=100; //计数值变化范围限制在0~99
Counter2++;
Counter2%=100; //计数值变化范围限制在0~99
Counter3++;
Counter3%=100; //计数值变化范围限制在0~99
if(Counter<Compare)
{
L298N_ENA=1;
}
else
{
L298N_ENA=0;
}
if(Counter1<Compare1)
{
L298N_ENB=1;
}
else
{
L298N_ENB=0;
}
if(Counter2<Compare2)
{
L298N_ENA1=1;
}
else
{
L298N_ENA1=0;
}
if(Counter3<Compare3)
{
L298N_ENB1=1;
}
else
{
L298N_ENB1=0;
}
}
void UART_Routine() interrupt 4 //串口中断
{
unsigned char Data;
if(RI==1) //允许单片机接收数据
{
Data=SBUF; //读取数据
UART_SendByte(SBUF); //将接收到的数据发回串口
RI=0; //接收标志位清0 软件复位
switch(Data)
{
case 0:StopIt(); break;
case 1:Forward(); break;
case 2:BackOff(); break;
case 3:TurnLeft(); break;
case 4:TurnRight(); break;
case 5:TurnLeftCircle(); break;
case 6:TurnRightCircle(); break;
case 7:IR_Tracking(); break;
}
}
}
UART
#include <REGX52.H>
/**
*@brief 串口初始化9600bps@11.0592MHz
*@param 无
*retval 无
**/
void UART_Init() //9600bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFD; //设定定时初值
TH1 = 0xFD; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
EA =1;
ES =1;
}
/**
*@brief 串口发送一个数据
*@param Byte
*retval 无
*/
void UART_SendByte(unsigned char Byte)
{
SBUF=Byte;
while(TI==0);
TI=0;
}
电机驱动
#include <REGX52.H>
sfr P4=0xe8;
sbit L298N_IN1 =P1^2;
sbit L298N_IN2 =P1^3; //IN1&1N2是右前轮
sbit L298N_IN3 =P1^6;
sbit L298N_IN4 =P1^7; //IN3&IN4是右后轮
sbit L298N_IN41 =P0^1;
sbit L298N_IN31 =P0^0; //IN31&IN41是左前轮
sbit L298N_IN21 =P4^2;
sbit L298N_IN11 =P1^0; //IN21&IN11是左后轮
void Forward() //前进
{
L298N_IN1=0;
L298N_IN2=1;
L298N_IN3=0;
L298N_IN4=1;
L298N_IN11=1;
L298N_IN21=0;
L298N_IN31=1;
L298N_IN41=0;
}
void BackOff() //后退
{
L298N_IN1=1;
L298N_IN2=0;
L298N_IN3=1;
L298N_IN4=0;
L298N_IN11=0;
L298N_IN21=1;
L298N_IN31=0;
L298N_IN41=1;
}
void TurnRight() //右转
{
L298N_IN11=1;
L298N_IN21=0;
L298N_IN31=1;
L298N_IN41=0;
}
void TurnRightCircle() //右转圈
{
L298N_IN1=1;
L298N_IN2=0;
L298N_IN3=1;
L298N_IN4=0;
L298N_IN11=1;
L298N_IN21=0;
L298N_IN31=1;
L298N_IN41=0;
}
void TurnLeft() //左转
{
L298N_IN1=0;
L298N_IN2=1;
L298N_IN3=0;
L298N_IN4=1;
}
void TurnLeftCircle() //左转圈
{
L298N_IN1=0;
L298N_IN2=1;
L298N_IN3=0;
L298N_IN4=1;
L298N_IN11=0;
L298N_IN21=1;
L298N_IN31=0;
L298N_IN41=1;
}
void StopIt() //停止
{
L298N_IN1=0;
L298N_IN2=0;
L298N_IN3=0;
L298N_IN4=0;
L298N_IN11=0;
L298N_IN21=0;
L298N_IN31=0;
L298N_IN41=0;
}
Timer0
#include <REGX52.H>
void Timer0_Init() //100微秒@11.0592MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0xA4; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
PT0=1;
}
红外循迹
#include <REGX52.H>
#include "MotorDrive.H"
sbit LM339_OUT1=P0^4; //IR_1
sbit LM339_OUT2=P0^5; //IR_2
sbit LM339_OUT3=P0^7; //IR_3
sbit LM339_OUT4=P0^6; //IR_4
unsigned char Compare,Compare1,Compare2,Compare3;
unsigned char Counter,Counter1,Counter2,Counter3;
void IR_Tracking()
{
while(1)
{
if(LM339_OUT2==0&&LM339_OUT3==0)
{
Compare=8;
Compare1=8;
Compare2=8;
Compare3=8;
Forward();
}
if(LM339_OUT2==1&&LM339_OUT3==1)
{
StopIt();
}
if(LM339_OUT2==1&&LM339_OUT3==0)
{
Compare=50;
Compare1=50;
TurnLeftCircle();
}
if(LM339_OUT2==0&&LM339_OUT3==1)
{
Compare2=50;
Compare3=50;
TurnRightCircle();
}
}
}
|