赞
踩
forward()
: 控制小车前进。left_run()
: 控制小车左转。right_run()
: 控制小车右转。left_rapidly()
: 控制小车左侧快速转动。backward()
: 控制小车后退。stop()
: 控制小车停止。StartModule()
: 触发超声波测距模块。timer0() interrupt 1
: 定时器0中断,用于测量超声波回波时间。Conut()
: 计算测得的距离。Avoid()
: 当检测到前方距离较近时,执行避障策略。tracking()
: 根据左右红外线传感器的状态执行追踪策略。left_led1
和right_led1
两个引脚表示左右红外线传感器的状态。beep
引脚用于蜂鸣器的控制,用于避障时的提示音。main.c
中,引用了QXA51.h
头文件。QXA51.h
定义了引脚的宏和电机驱动相关的函数。#include <reg52.h>
导入相关寄存器定义,提供对硬件的底层控制。RX
和 TX
引脚进行串口通信,通过串口实现与外部设备的数据交互。StartModule()
启动模块,使用定时器进行测距。Conut()
函数对超声波传感器的测距数据进行处理,计算距离,并设置相应的标志。Avoid()
函数实现基本的避障策略,当检测到障碍物距离小于设定值时,触发蜂鸣器并执行避障动作。EN1
和 EN2
控制左右电机的PWM输出。pwm_left_val
和 pwm_right_val
来控制左右电机的占空比,实现精准的电机控制。QXA51.h
文件中的宏,实现前进、后退、左转、右转等基本运动控制。keyscan()
函数实现对按键的检测,当检测到按键按下时,触发相应的操作。left_led1
和 right_led1
进行巡线,根据传感器反馈实现小车的路径跟随。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(); //寻迹 } }
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
调试目标: 确保超声波测距模块能够准确测量前方障碍物的距离。
调试步骤:
结果分析: 经过调试,成功获取到超声波测距的准确数据,验证了超声波模块的正常工作。
调试目标: 保证红外线传感器能够准确感知地面状态,用于追踪模式。
调试步骤:
结果分析: 经过调试,成功实现了红外线传感器在追踪模式下的正常工作,LED指示灯的状态正确显示。
调试目标: 保证小车能够根据传感器数据实现运动控制,并在遇到障碍物时执行避障策略。
调试步骤:
结果分析: 经过调试,小车成功实现了根据传感器数据的运动控制和避障功能。蜂鸣器的提示正常,指示了避障策略的执行。
通过调试过程,我逐步解决了项目中的问题,确保了每个模块的正常工作。在调试过程中,通过观察串口输出、LED指示灯和蜂鸣器的状态,我更好地理解了代码的执行流程和传感器的工作原理。项目的成功实现不仅提高了我的嵌入式系统开发能力,也锻炼了我的问题解决和调试技能。在未来的项目中,我将更加注重代码的可维护性和可扩展性,以便更好地应对复杂的嵌入式系统开发任务。
项目中涉及到硬件(电机、传感器)和软件(C语言编程)的协同工作。通过理解硬件接口和相应的编程逻辑,我学到了如何在嵌入式系统中实现功能。
项目中使用了超声波传感器和红外线传感器,这使得小车能够感知周围环境并做出相应的决策。学到了如何使用传感器获取实时数据,以便做出智能决策。
了解如何设计和实现一个实时控制系统。在这个项目中,对定时器和中断的使用让我能够实现小车的实时响应和运动控制。
在开发过程中,我经历了不少的调试过程,从中学到了如何通过观察输出、逐步排查问题并优化代码。这锻炼了我的问题解决能力。
了解了项目管理的重要性,包括合理划分任务、时间规划、阶段性检查等。这使得整个项目的实施更为有序和高效。
总体而言,这个小车控制项目是一个很好的实践机会,使我更深入地理解了嵌入式系统的开发过程,并提高了我的问题解决和团队协作能力。这是一个具有挑战性但充满乐趣的学习过程。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。