51单片机双线循迹小车(四路红外传感器)

本文介绍了如何使用51单片机设计一辆能沿着赛道边线行驶的小车。通过4个灰度传感器检测赛道边界,结合权值调整算法进行差速转弯。代码中定义了红外传感器的权值、PWM引脚和阈值,并在主函数中实现了循迹算法。定时器中断函数用于生成PWM波,控制小车的转向和速度。
摘要由CSDN通过智能技术生成

使用51单片机完成一辆巡边线循迹的小车

小车赛道

在这里插入图片描述

小车车模

在这里插入图片描述

传感器

	使用4个灰度传感器。

小车循迹代码

#include <REG52.h> //51头文件
#define N  10000   //PWM峰值 F = 1 / N 频率
#define speed_car 2000 //小车直行运行速度

//数据类型定义
//无符号数据类型的定义
typedef unsigned char uint8_t;
typedef unsigned int uint16_t;
typedef unsigned long int uint32_t;
//有符号数据类型的定义
typedef char int8_t;
typedef int int16_t;
typedef long int int32_t;

//小红外传感器权值 ,Kd1为外侧红外的权值,Kd2为内侧红外传感器的权值
uint16_t Kd1 = 100, Kd2 = 300;

//四路红外引脚口
//左边
sbit Left_LED1 = P1^2;
sbit Left_LED2 = P1^0;
//右边
sbit Right_LED1 = P1^3;
sbit Right_LED2 = P1^1;

//两路PWM引脚端
sbit PWM_Left = P1^4;
sbit PWM_Right = P1^7;
//负端 为1时电机反转
sbit PWM_Left_GND = P1^5;
sbit PWM_Right_GND = P1^6;

//左右两路PWM值 为正时电机正转,为负时电机反转
int16_t PWM_Left_Data = 0,PWM_Right_Data = 0;

//定时器计数器
uint16_t T_count = 0;

//主函数
void main()
{
	//红外传感器阈值
	uint16_t Left_sum = 0 , Right_sum = 0;
	//打开定时器0
	TMOD = 0X02;//定时器0  工作方式2 八位重装载计数器
	TH0 = 255;   //定时器初值	 每1ns计数一次
	TL0 = 255;
	TR0 = 1;//打开定时器0
	ET0 = 1;//打开定时器0允许位
	EA = 1;//打开总终端

   //死循环
	while(1)
	{
		//读取红外数据	当扫描到黑线时赋值为1  当没有黑线时为零
		//Kd1为外侧红外的权值,Kd2为内侧红外传感器的权值
		Left_sum = (Left_LED1)	* Kd1 + (Left_LED2) * Kd2 ;
		Right_sum = (Right_LED1) * Kd1 + (Right_LED2) * Kd2 ;

		//当红外传感器只有其中一边检测到黑线时 小车沿边沿循迹
		//差速转弯
		PWM_Left_Data = speed_car  + Left_sum - Right_sum   ;
		PWM_Right_Data = speed_car + Right_sum - Left_sum  ;

		//PWM限幅
		//上限
		PWM_Left_Data = (PWM_Left_Data > N) ? N : PWM_Left_Data;
		PWM_Right_Data = (PWM_Right_Data > N ) ? N : PWM_Right_Data;
		//下限
		PWM_Left_Data = (PWM_Left_Data < -N) ? -N : PWM_Left_Data;
		PWM_Right_Data = (PWM_Right_Data < -N ) ? -N : PWM_Right_Data;
		

		
	}
}

//定时器中断函数
void Timer0() interrupt 1
{
	TH0 = 255;   //定时器初值	 每1ns计数一次
	TL0 = 255;
	//定时器循环计数
	T_count = (T_count < N ) ? (++T_count  ) : 0;
	//发生PWM波
	//正端
	PWM_Left = ((PWM_Left_Data >= 0) && ( T_count < PWM_Left_Data )) ? 1 : 0;
	PWM_Right = ((PWM_Right_Data >= 0) && (T_count < PWM_Right_Data)) ? 1 : 0;	
	//负端
	PWM_Left_GND = ((PWM_Left_Data < 0) && (T_count < -PWM_Left_Data)) ? 1 : 0;
	PWM_Right_GND = ((PWM_Right_Data < 0) && (T_count < -PWM_Right_Data)) ? 1 : 0;	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鱼子爱吃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值