当前位置:   article > 正文

项目驱动的单片机应用设计(小车寻迹避障二合一)_直流电机的beep引脚什么作用

直流电机的beep引脚什么作用

一、项目总体方案概述

1. 项目功能描述:

  • 小车运动控制:通过驱动直流电机控制小车的前进、后退、左转、右转等运动。
  • 超声波避障:利用超声波模块测量距离,实现小车的避障功能。
  • LED指示灯:通过LED指示灯显示小车在追踪模式下的状态。

2. 主要硬件模块:

  • 单片机:使用51单片机,包含reg52.h头文件。
  • 超声波模块:通过TRIG和ECHO引脚控制超声波模块的发射和接收。
  • 电机驱动:使用QXA51.h中定义的引脚控制直流电机的驱动。
  • LED指示灯:使用P3^ 2和P3^3控制LED指示灯。

3. 关键函数和功能模块:

3.1 运动控制相关函数:

  • forward(): 控制小车前进。
  • left_run(): 控制小车左转。
  • right_run(): 控制小车右转。
  • left_rapidly(): 控制小车左侧快速转动。
  • backward(): 控制小车后退。
  • stop(): 控制小车停止。

3.2 超声波测距相关函数:

  • StartModule(): 触发超声波测距模块。
  • timer0() interrupt 1: 定时器0中断,用于测量超声波回波时间。
  • Conut(): 计算测得的距离。

3.3 避障相关函数:

  • Avoid(): 当检测到前方距离较近时,执行避障策略。

3.4 追踪模式相关函数:

  • tracking(): 根据左右红外线传感器的状态执行追踪策略。

4. 状态指示:

  • 使用left_led1right_led1两个引脚表示左右红外线传感器的状态。
  • beep引脚用于蜂鸣器的控制,用于避障时的提示音。

5. 代码结构:

  • 主程序在main.c中,引用了QXA51.h头文件。
  • QXA51.h定义了引脚的宏和电机驱动相关的函数。

6. 主程序循环:

  • 主程序进入一个无限循环,其中包含触发超声波测距、避障判断、追踪模式等功能。

7. 注意事项:

  • 代码中使用了定时器中断,需要根据具体的硬件配置进行调整。
  • 确保硬件连接正确,特别是超声波模块和电机驱动。

8.程序框图

调用
调用
调用
调用
调用
定义引脚宏
定义引脚宏
定义引脚宏
调用
调用
调用
调用
调用
调用
根据
主程序
QXA51.h
超声波测距函数
运动控制函数
避障函数
追踪模式函数
IN1, IN2, IN3, IN4, EN1, EN2
left_led1, right_led1, left_led2, right_led2
key_s2, key_s3, beep
StartModule()
timer0() interrupt 1
Conut()
forward()
left_run()
right_run()
left_rapidly()
backward()
stop()
Avoid()
tracking()
left_led1, right_led1

二、电路原理图

电路图

三、各功能模块介绍

1.单片机最小系统模块

硬件基础

  • 使用STC89C52单片机,具备丰富的外设接口和IO口,适合嵌入式应用。
  • 引入 #include <reg52.h> 导入相关寄存器定义,提供对硬件的底层控制。

串口通信

  • 使用 RXTX 引脚进行串口通信,通过串口实现与外部设备的数据交互。

定时器中断

  • 利用定时器0和定时器1中断,实现定时操作,例如定时器0用于外部控制的计时,定时器1用于PWM的生成。

2.超声波模块

超声波传感器

  • 使用超声波传感器进行距离测量,通过StartModule()启动模块,使用定时器进行测距。

数据处理

  • 通过 Conut() 函数对超声波传感器的测距数据进行处理,计算距离,并设置相应的标志。

避障策略

  • 利用 Avoid() 函数实现基本的避障策略,当检测到障碍物距离小于设定值时,触发蜂鸣器并执行避障动作。

3.电机驱动模块

PWM控制

  • 利用定时器1中断实现PWM控制,通过 EN1EN2 控制左右电机的PWM输出。
  • 调整 pwm_left_valpwm_right_val 来控制左右电机的占空比,实现精准的电机控制。

电机驱动

  • 利用定义在 QXA51.h 文件中的宏,实现前进、后退、左转、右转等基本运动控制。
  • 通过设置不同的电机引脚状态,控制电机的运动方向。

4.按键模块

按键检测

  • 利用 keyscan() 函数实现对按键的检测,当检测到按键按下时,触发相应的操作。

外部控制

  • 在主循环中通过串口接收数据,并在接收到数据后触发定时器0进行计时,实现对小车行为的外部控制。

5.红外循迹和红外避障模块

巡线

  • 通过两个红外传感器 left_led1right_led1 进行巡线,根据传感器反馈实现小车的路径跟随。

避障

  • 在巡线的基础上,通过检测红外避障传感器,实现在遇到障碍物时的避障策略。
  • 当检测到障碍物时,触发蜂鸣器声音、停车、后退、左转等动作,提高小车的智能避障能力。

6.模块化设计

QXA51.h 文件

  • 通过 QXA51.h 文件进行引脚和宏定义,实现了代码的模块化设计。
  • 将引脚和宏定义集中管理,提高了代码的可读性和可维护性,方便未来的扩展和修改。

这些模块共同组成了一个功能完整的小车控制系统,实现了巡线、避障、外部控制等功能,具备一定的智能性和灵活性。在实际应用中,可以根据具体需求进行适度的修改和扩展。

四、程序设计

main.c 文件

/*
* 【实验平台】: QX-MCS51 单片机开发板 & QX-A51智能小车
* 【外部晶振】: 11.0592mhz	
* 【主控芯片】: STC89C52
* 【编译环境】: Keil μVisio4
* ********************************【接线说明】********************************
             以下"A_"表示智能小车底板~~~"B_"表示开发板     
*开发板供电线  :A_J5-VCC~~~B_VCC或5V0    A_J6-GND~~~B_GND (一共使用2根杜邦线)
*电机控制线    :A_J10-P1.2至P1.7 对应接到B_P1.2至P1.7 (一共使用6根杜邦线)
*超声波模块反馈线:A_J2-P20~~~B_P20    A_J2-P21~~~B_P21 (一共使用2根杜邦线)
*避障寻迹反馈线:A_J11-P3.2至P3.5 对应接到B_P3.2至P3.5 (一共使用4根杜邦线)
******************************************************************************
* 【程序功能】:QX-A51智能小车寻迹避障二合一(在黑线寻迹的过程中如遇障碍物则自动掉头)		   			            			    
* 【使用说明】:接线无误后,烧写程序打开电源开、按下S2按键后蜂鸣器发出提示音1秒后启动小车
* 【注意事项】:避免小车撞向障碍物或小车轮子堵转。
				小车电压不能低于6V.
				此程序只做参考,实际运行效果需根据不同实验场地进行不同调试
**********************************************************************************/
#include <reg52.h>//51头文件
#include <intrins.h>   //包含nop等系统函数
#include <QXA51.h>//QX-A51智能小车配置文件


sbit RX = P2^0;//ECHO超声波模块回响端
sbit TX = P2^1;//TRIG超声波模块触发端

unsigned char pwm_left_val = 170;//左电机占空比值 取值范围0-170,0最快
unsigned char pwm_right_val = 170;//右电机占空比值取值范围0-170 ,0最快
unsigned char pwm_t;//周期
unsigned int  time = 0;//传输时间
unsigned long S = 0;//距离
bit      flag = 0;//超出测量范围标志位


void delay(unsigned int z)//毫秒级延时
{
	unsigned int x,y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0 ; y--);
}
void Delay10us(unsigned char i)    	//10us延时函数 启动超声波模块时使用
{ 
   unsigned char j; 
	do{ 
		j = 10; 
		do{ 
			_nop_(); 
		}while(--j); 
	}while(--i); 
}
/*小车前进*/
void forward()
{
	left_motor_go; //左电机前进
	right_motor_go; //右电机前进
}
/*小车左转*/
void left_run()
{
	left_motor_stops; //左电机停止
	right_motor_go; //右电机前进	
}
/*小车右转*/
void right_run()
{
	right_motor_stops;//右电机停止
	left_motor_go;    //左电机前进
}


/*PWM控制使能 小车原地左转*/
void left_rapidly()
{
	left_motor_back;
	right_motor_go;	
}

/*小车后退*/
void backward()
{
	left_motor_back; //左电机后退
	right_motor_back; //右电机后退	
}
/*小车停止*/
void stop()
{
	right_motor_stops;//右电机停止
	left_motor_stops; //左电机停止	
}


/*定时器1中断输出PWM信号*/
void timer1() interrupt 3
{
	pwm_t++;//周期计时加
	if(pwm_t == 255)
		pwm_t = EN1 = EN2 = 0;
	if(pwm_left_val == pwm_t)//左电机占空比	
		EN1 = 1;		
	if(pwm_right_val == pwm_t)//右电机占空比
		EN2 = 1;			 
}

/*判断S2是否被按下*/
void keyscan()
{
	for(;;)	//死循环
	{
		if(key_s2 == 0)// 实时检测S2按键是否被按下
		{
			delay(5); //软件消抖
			if(key_s2 == 0)//再检测S2是否被按下
			{
				while(!key_s2);//松手检测
				beep = 0;	//使能有源蜂鸣器
				delay(200);//200毫秒延时
				beep = 1;	//关闭有源蜂鸣器
				break;		//退出FOR死循环
			}
		}
	}	
}

/*定时器0中断*/
void timer0() interrupt 1	//T0中断用来计数器溢出,超过测距范围
{
	flag=1;							 //中断溢出标志			 
}
void  StartModule() 		         //启动超声波模块
{
	  TX=1;			                     //启动一次模块
      Delay10us(2);
	  TX=0;
}

/*计算超声波所测距离并显示*/
void Conut()
{
	time=TH0*256+TL0;
	TH0=0;
	TL0=0;
	
	S=(float)(time*1.085)*0.17;     //算出来是MM
	if((S>=7000)||flag==1) //超出测量范围
	{	 
		flag=0;

	}
}

//寻迹
void tracking()
{
		//为0 没有识别到黑线 为1识别到黑线
	if(left_led1 == 1 && right_led1 == 1)//左右寻迹探头识别到黑线
	{
		forward();//前进
	}
	else
	{
		if(left_led1 == 1 && right_led1 == 0)//小车右边出线,左转修正
		{
			left_run();//左转
		}
		if(left_led1 == 0 && right_led1 == 1)//小车左边出线,右转修正
		{
			right_run();//右转
		}
		if(left_led1 == 0 && right_led1 == 0)//左右寻迹探头都没识别到黑线
		{
			backward();//后退
		}		
	}	
}

/*超声波避障*/
void	Avoid()
{
	if(S < 400)//设置避障距离(单位毫米),掉头距离
	{
		beep = 0;//使能蜂鸣器
		stop();//停车
		delay(100);//停车时间
		left_rapidly();//原地左转
		delay(180);//左右角度,数值越大转向角度越大
		do{
			left_rapidly();//原地左转
			delay(10);//转向角度
			stop();	 //停车
			delay(1);//停车时间
			}while(left_led1 == 0 || right_led1 == 0); //回到黑线上则退出,否则继续原地转向寻找黑线
		beep = 1;//关闭蜂鸣器
	}
}
	
void main()
{
	unsigned int i;
	keyscan();//等待按键按下启动
	delay(1000);//延时1秒
	TMOD |= 0x20;//定时器1工作模式2,8位自动重装。用于产生PWM
	TMOD |= 0x01;//定时器0工作模块1,16位定时模式。T0用测ECH0脉冲长度
	TH1 = 220; //
	TL1 = 220; //100HZ T1
	TH0	= 0;
    TL0	= 0;//T0,16位定时计数用于记录ECHO高电平时间         
    ET1	= 1;//允许T1中断
	ET0 = 1;//允许T0中断
	TR1 = 1;//启动定时器1
	EA  = 1;//启动总中断
	while(1)
	{		
		 StartModule();	//启动模块测距
		 while(!RX);		//当RX(ECHO信号回响)为零时等待
		 TR0=1;			    //开启计数
		 while(RX);			//当RX为1计数并等待
		 TR0=0;				//关闭计数
	     Conut();			//计算距离
		 Avoid();			//避障
		 for(i=0; i<1800; i++)  //超声波每次测距间隔不低于65ms
			tracking();	//寻迹	
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223

QXA51.h 文件

#ifndef __QXA51_H__
#define __QXA51_H__

/*电机驱动IO定义*/
sbit IN1 = P1^2; //为1 左电机反转
sbit IN2 = P1^3; //为1 左电机正转
sbit IN3 = P1^6; //为1 右电机正转
sbit IN4 = P1^7; //为1 右电机反转
sbit EN1 = P1^4; //为1 左电机使能
sbit EN2 = P1^5; //为1 右电机使能
sbit left_led1 = P3^3;//左寻迹信号 为0 没有识别到黑线 为1识别到黑线
sbit right_led1 = P3^2;//右寻迹信号	为0 没有识别到黑线 为1识别到黑线
sbit left_led2 = P3^4;//左避障信号 为0 识别障碍物 为1没有识别到障碍物
sbit right_led2 = P3^5;//右避障信号	为0 识别障碍物 为1没有识别到障碍物


/*按键定义*/
sbit key_s2 = P3^0;
sbit key_s3 = P3^1;
sbit beep = P2^3;//蜂鸣器

#define left_motor_en		EN1 = 1	//左电机使能
#define right_motor_en		EN2 = 1	//右电机使能


#define left_motor_stops	IN1 = 0, IN2 = 0//左电机停止
#define right_motor_stops	IN3 = 0, IN4 = 0//右电机停止

#define left_motor_go		IN1 = 0, IN2 = 1//左电机正传
#define left_motor_back		IN1 = 1, IN2 = 0//左电机反转
#define right_motor_go		IN3 = 1, IN4 = 0//右电机正传
#define right_motor_back	IN3 = 0, IN4 = 1//右电机反转

#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

五、调试与结果分析

1. 超声波测距模块调试

调试目标: 确保超声波测距模块能够准确测量前方障碍物的距离。

调试步骤:

  1. 硬件连接检查: 首先检查超声波模块的引脚连接是否正确,确保TRIG和ECHO引脚正确连接。
  2. 代码验证: 确保超声波测距的代码逻辑正确,包括定时器中断、距离计算等部分。
  3. 串口输出: 在代码中添加串口输出语句,观察超声波模块返回的距离数据是否正确。

结果分析: 经过调试,成功获取到超声波测距的准确数据,验证了超声波模块的正常工作。

2. 红外线传感器调试

调试目标: 保证红外线传感器能够准确感知地面状态,用于追踪模式。

调试步骤:

  1. 传感器状态检查: 检查红外线传感器的引脚连接,并确保传感器在正常工作状态。
  2. 追踪模式代码: 确保追踪模式的代码正确调用红外线传感器,并根据传感器状态执行相应的动作。
  3. LED指示灯验证: 使用LED指示灯显示红外线传感器的状态,以便调试时观察传感器的工作情况。

结果分析: 经过调试,成功实现了红外线传感器在追踪模式下的正常工作,LED指示灯的状态正确显示。

3. 运动控制与避障调试

调试目标: 保证小车能够根据传感器数据实现运动控制,并在遇到障碍物时执行避障策略。

调试步骤:

  1. 运动控制代码: 检查运动控制相关的代码,确保根据传感器数据执行正确的运动控制。
  2. 避障逻辑验证: 调试避障函数,确保在检测到障碍物时执行避障策略。
  3. 蜂鸣器提示: 在避障时使用蜂鸣器进行提示,以观察避障逻辑的执行情况。

结果分析: 经过调试,小车成功实现了根据传感器数据的运动控制和避障功能。蜂鸣器的提示正常,指示了避障策略的执行。

总结与反思:

通过调试过程,我逐步解决了项目中的问题,确保了每个模块的正常工作。在调试过程中,通过观察串口输出、LED指示灯和蜂鸣器的状态,我更好地理解了代码的执行流程和传感器的工作原理。项目的成功实现不仅提高了我的嵌入式系统开发能力,也锻炼了我的问题解决和调试技能。在未来的项目中,我将更加注重代码的可维护性和可扩展性,以便更好地应对复杂的嵌入式系统开发任务。

六、心得体会

1.硬件与软件协同:

项目中涉及到硬件(电机、传感器)和软件(C语言编程)的协同工作。通过理解硬件接口和相应的编程逻辑,我学到了如何在嵌入式系统中实现功能。

2.传感器的应用:

项目中使用了超声波传感器和红外线传感器,这使得小车能够感知周围环境并做出相应的决策。学到了如何使用传感器获取实时数据,以便做出智能决策。

3.实时控制系统:

了解如何设计和实现一个实时控制系统。在这个项目中,对定时器和中断的使用让我能够实现小车的实时响应和运动控制。

4.调试与优化:

在开发过程中,我经历了不少的调试过程,从中学到了如何通过观察输出、逐步排查问题并优化代码。这锻炼了我的问题解决能力。

5.项目管理:

了解了项目管理的重要性,包括合理划分任务、时间规划、阶段性检查等。这使得整个项目的实施更为有序和高效。

总体而言,这个小车控制项目是一个很好的实践机会,使我更深入地理解了嵌入式系统的开发过程,并提高了我的问题解决和团队协作能力。这是一个具有挑战性但充满乐趣的学习过程。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/470802
推荐阅读
相关标签
  

闽ICP备14008679号