stc89c51实现红外寻迹 ,超声波配合舵机定点测距的代码
时间: 2023-10-14 07:04:12 浏览: 78
c51单片机超声波测距源代码
5星 · 资源好评率100%
以下是STC89C51单片机实现红外寻迹,超声波配合舵机定点测距的代码示例:
```c
#include <reg52.h>
#define FOSC 11059200L //定义时钟频率
#define BAUD 9600 //定义波特率
#define TH1_VALUE 256 - FOSC / 12 / BAUD //定义计算初值
sbit Trig = P1^1; //定义超声波发射管脚
sbit Echo = P1^0; //定义超声波接收管脚
sbit infrared1 = P2^0; //定义红外传感器1
sbit infrared2 = P2^1; //定义红外传感器2
sbit infrared3 = P2^2; //定义红外传感器3
sbit infrared4 = P2^3; //定义红外传感器4
sbit infrared5 = P2^4; //定义红外传感器5
sbit infrared6 = P2^5; //定义红外传感器6
sbit infrared7 = P2^6; //定义红外传感器7
sbit infrared8 = P2^7; //定义红外传感器8
sbit left = P1^2; //定义左转向
sbit right = P1^3; //定义右转向
sbit stop = P1^4; //定义停车
sbit run = P1^5; //定义前进
unsigned char code infrared[8] = {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}; //红外传感器值
unsigned char flag = 0; //定义标志位
unsigned int distance = 0; //定义距离
void InitUart() //初始化串口
{
TMOD |= 0x20; //定时器1工作在模式2
TH1 = TH1_VALUE; //计算计数初值
TL1 = TH1; //初始化计数器
PCON |= 0x80; //波特率加倍
SCON = 0x50; //打开串口,工作在方式1
ES = 1; //打开串口中断
EA = 1; //打开总中断
TR1 = 1; //启动计数器1
}
void UartSend(unsigned char dat) //发送一个字符
{
SBUF = dat;
while(!TI);
TI = 0;
}
void UartSendString(unsigned char *str) //发送字符串
{
while(*str) UartSend(*str++);
}
void DelayUs(unsigned t) //微秒延时
{
while(t--);
}
void DelayMs(unsigned int t) //毫秒延时
{
while(t--)
{
DelayUs(1000);
}
}
void MeasureDistance() //测量距离
{
Trig = 1;
DelayUs(10);
Trig = 0;
while(!Echo); //等待接收到回波
TR1 = 1; //启动计数器1
while(Echo); //等待回波结束
TR1 = 0; //关闭计数器1
distance = (unsigned int)(TH1 << 8) | TL1; //计算距离
distance = distance / 58; //单位为厘米
}
void Steer(float angle) //舵机转动
{
unsigned int i;
unsigned int count = (unsigned int)(angle / 0.9 + 35); //计算脉冲宽度
for(i = 0; i < count; i++)
{
P1 = 0xFE; //引脚输出高电平
DelayUs(10); //延时10us
P1 = 0x00; //引脚输出低电平
DelayMs(20); //延时20ms
}
}
void main()
{
InitUart(); //初始化串口
run = 1; //启动前进
while(1)
{
MeasureDistance(); //测量距离
if(distance < 30) //距离小于30cm
{
stop = 0;
run = 0;
right = 1;
DelayMs(500);
MeasureDistance();
if(distance > 30)
{
right = 0;
run = 1;
}
else
{
left = 1;
DelayMs(1000);
right = 0;
left = 0;
run = 1;
}
}
if(infrared1 == infrared[0] && infrared2 == infrared[1] && infrared3 == infrared[2] && infrared4 == infrared[3] && infrared5 == infrared[4] && infrared6 == infrared[5] && infrared7 == infrared[6] && infrared8 == infrared[7]) //八个传感器均为黑线
{
stop = 1;
run = 0;
}
else if(infrared3 == infrared[2] && infrared4 == infrared[3]) //前方有黑线
{
stop = 1;
run = 0;
Steer(90); //调整舵机角度
DelayMs(1000);
MeasureDistance(); //重新测量距离
if(distance > 30) //距离大于30cm
{
Steer(0); //舵机回正
run = 1; //继续前进
}
else
{
Steer(-90); //舵机调整角度
DelayMs(1000);
MeasureDistance();
if(distance > 30)
{
Steer(0);
run = 1;
}
else
{
run = 0;
stop = 1;
}
}
}
else if(infrared4 == infrared[3]) //右侧有黑线
{
Steer(-45); //调整舵机角度
DelayMs(500);
MeasureDistance(); //重新测量距离
if(distance > 30) //距离大于30cm
{
Steer(0); //舵机回正
run = 1; //继续前进
}
else
{
Steer(90); //舵机调整角度
DelayMs(1000);
MeasureDistance();
if(distance > 30)
{
Steer(0);
run = 1;
}
else
{
run = 0;
stop = 1;
}
}
}
else if(infrared3 == infrared[2]) //左侧有黑线
{
Steer(45); //调整舵机角度
DelayMs(500);
MeasureDistance(); //重新测量距离
if(distance > 30) //距离大于30cm
{
Steer(0); //舵机回正
run = 1; //继续前进
}
else
{
Steer(-90); //舵机调整角度
DelayMs(1000);
MeasureDistance();
if(distance > 30)
{
Steer(0);
run = 1;
}
else
{
run = 0;
stop = 1;
}
}
}
else //其他情况
{
run = 1; //继续前进
stop = 0;
}
}
}
void Uart() interrupt 4 using 1 //串口中断服务函数
{
if(RI)
{
RI = 0;
}
if(TI)
{
TI = 0;
}
}
```
这段代码实现了超声波测距和舵机控制,以及红外寻迹功能,可以通过串口与上位机进行通信,方便调试和控制。其中,通过不同的红外传感器值来判断是否在黑线上,通过舵机转动角度来调整方向,通过超声波测距来避障。
阅读全文