智能寻迹(循迹)小车项目思路 + 代码

说是智能循迹小车,其实一点也不智能,仅仅是几个判断语句而已。更高级的可以使用PID算法控制小车双轮的转速,从而实现智能小车控制。

作为一个项目作业,完成后想删掉的,但是感觉有些可惜,故发布于博客上以便于其他人参考。

使用两个红外线接收器接受红外线探测到的黑色轨迹,实现转大小弯,直角(因为直角处轨迹宽度超过了探测器的宽度,所以有一些额外处理),但是无法通过锐角。
遇到转弯的时候就将直行的速度降低到最高速度的slow%,以防止小车冲出弯道。保持直行状态达到speedUp时间后,在fullGear-speedUp时间内将速度提升到最高,用来提升小车平均速度。每时每刻保存前一个转向状态,在传感器全为黑时执行保存的转向,以达到通过直角弯道的目的。

流程图如下
在这里插入图片描述

完整代码如下

#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char

// 电机部分
sbit P00 = P0^0;
sbit P01 = P0^1;
sbit P02 = P0^2;
sbit P03 = P0^3;
sbit P04 = P0^4; // 左电机使能
sbit P05 = P0^5; // 右电机使能
// 显像器部分
sbit P20 = P2^0;
sbit P21 = P2^1;
sbit P22 = P2^2;
sbit P23 = P2^3;
sbit P24 = P2^4;
sbit P25 = P2^5;
sbit P26 = P2^6;
sbit P27 = P2^7;
// 红外部分
sbit P33 = P3^3;
sbit P35 = P3^5; // 左边红外
sbit P36 = P3^6; // 右侧红外
uint num; // 计数器
uint pwmR;
uint pwmL;
// 其它参数
uint speedUp = 5000; // 开始加速的直行时间
uint fullGear = 8000; // 加速到满速的时间
uint slow = 60; // 遇到转弯时的直行速度
uint delayMs = 0; // 转弯延迟时间
unsigned long count = 0;
uchar status = 'F';
uchar pstatus = 'F';
int flag = 0; // 为0时代表全速,为1时代表转弯


void init();
void leftFdw();
void leftBack();
void rightFdw();
void rightBack();
void back();
void forward();
void turnLeft();
void turnRight();
void stop();
void closeLight();
void delayms(uint);
void printChar(uchar x);
void motorsWrite(int speedL, int speedR);

/*************************** 车轮控制基本程序 ***************************/
void leftFdw(){
	// 左轮前进
	P00 = 1;P01 = 0;
}

void leftBack(){
	// 左轮后退
	P00 = 0;P01 = 1;
}

void rightFdw(){
	// 右轮前进
	P02 = 1;P03 = 0;
}

void rightBack(){
	// 右轮后退
	P02 = 0;P03 = 1;
}

/*************************** 方向控制程序 ***************************/
void turnLeft(){
	// 左转
	status = 'L';
	printChar('L');
	motorsWrite(0, 90);
}

void turnRLeft(){
	// 左转
	status = 'L';
	printChar('L');
	motorsWrite(-70, 100);
}

void turnRight(){
	// 右转
	status = 'R';
	printChar('R');
	motorsWrite(90, 0);
}

void turnRRight(){
	// 右转
	status = 'R';
	printChar('R');
	motorsWrite(100, -70);
}

void forward(){
	// 前进
	status = 'F';
	printChar('F');
	if(flag){ // 转弯
		motorsWrite(slow,slow);
	} else { // 直线加速
		uint dSpeed = slow;
		motorsWrite(dSpeed,dSpeed);
	}
}

void back(){
	// 后退
	status = 'B';
	printChar('B');
	motorsWrite(-100,-100);
}

void stop(){
	// 停车
	status = 'S';
	printChar('S');
	motorsWrite(0,0);
}

/********************** 延时程序 **********************/
void delayms(unsigned int xms){
		unsigned int i,j;
		for(i=xms;i>0;i--)
			for(j=110;j>0;j--);
}

/********************** 数码管显示程序 **********************/
void closeLight(){
	P21 = 1;P22 = 1;P23 = 1;P24 = 1;P25 = 1;P26 = 1;P27 = 1;
}

void printChar(uchar x){
	closeLight();
//	if(x == 'L'){
//		P22 = 0;P23 = 0;P24 = 0;
//	} else if(x == 'R'){
//		P22 = 0;P23 = 0;P27 = 0;
//	} else if(x == 'F'){
//		P21 = 0;P22 = 0;P23 = 0;P27 = 0;
//	} else if(x == 'B'){
//		P21 = 0;P22 = 0;P23 = 0;P24 = 0;P25 = 0;
//	} else if(x == 'S'){
//		P21 = 0;P24 = 0;P27 = 0;
//	}
}

/********************** 电机控制程序 **********************/
void motorsWrite(int speedL, int speedR){
	// 电机控制
	if(speedL > 100) speedL=100;
	if(speedR > 100) speedR=100;
	if(speedL < -100) speedL=-100;
	if(speedR < -100) speedR=-100;
	
	if(speedL < 0) {
		pwmL = -speedL;
		leftBack();
	} else {
		pwmL = speedL;
		leftFdw();
	}
	if(speedR < 0){
		pwmR = -speedR;
		rightBack();
	} else {
		pwmR = speedR;
		rightFdw();
	}
}

void init(){
	// PWM控制程序
	// 100us计时器
	TMOD = 0x01; // 定时器0模式1
	TH0 = 0x0FF; // 定时器0的高八位
	TL0 = 0x0A4;
	//TF0;// 如果定时器中断(溢出),则TF0=1;
	EA = 1;
	ET0 = 1;
	TR0 = 1; // 表示开启定时器0
}

void main(){
	init();
	while(1){
		if(P35 == 0 && P36 == 0){
			forward();
		} else if(P35 == 0 && P36 == 1){
			turnRight();
			flag = 1;
			pstatus = 'R';
		} else if(P35 == 1 && P36 == 0){
			turnLeft();
			flag = 1;
			pstatus = 'L';
		} else if(P35 == 1 && P36 == 1){
			if(pstatus == 'F'){
				forward();
			} else if(pstatus == 'R'){
				turnRRight();
				delayms(delayMs);
			} else if(pstatus == 'L'){
				turnRLeft();
				delayms(delayMs);
			}
		}
	}
}

void Timer0Interrupt(void) interrupt 1
{
	TH0 = 0x0FF;
	TL0 = 0x0A4;
	if(num <= pwmL)P04 = 1;
	else P04 = 0;
	if(num <= pwmR)P05 = 1;
	else P05 = 0;
	num++;
	if(num >= 100)num=0;
	
	if(status == 'F') {
		count++;
	} else {
		count = 0;
	}
	if(count == speedUp && status == 'F') {
		flag = 0;
	}
}
  • 152
    点赞
  • 1168
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
智能寻迹小车是基于STM32单片机的一种智能小车项目,其核心是使用PWM输出和I/O口引脚电平判断来实现控制。在STM32F103系列单片机控制智能小车中,有三种控制方式可选,包括遥控控制、避障和循迹。 其中,循迹控制方式使用了基于STM32单片机的CCD传感器,通过识别跑道图像来实现智能小车循迹功能。该循迹小车的源代码已经被压缩打包,程序完整且算法较优,曾获得过二等奖。它能够快速、有效地识别轨迹,在直道上加速,在弯道上减速,并采用PID调速来实现精确的控制。 因此,智能寻迹小车stm32是一种基于STM32单片机的智能小车项目,通过PWM输出和I/O口引脚电平判断来控制,可以实现遥控控制、避障和循迹功能。循迹功能使用了CCD传感器以及优化的算法,可以实现快速、精确的轨迹识别和控制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [基于stm32的智能小车(远程控制、避障、循迹)](https://blog.csdn.net/m0_59113542/article/details/123811441)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [基于stm32的智能小车(遥控控制、避障、循迹)](https://download.csdn.net/download/m0_59113542/86246787)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [基于STM32的CCD智能寻迹小车代码.zip_CCD寻迹小车_PID循迹_stm32 循迹 pid_压缩机 PID_寻迹 ](https://download.csdn.net/download/weixin_42662293/86173408)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值