如下為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();
}
}
}
|