产品概述

单片机 break 51单片机自动壁障小车设计,附原理图程序全套制作资料

小编 2025-06-07 产品概述 23 0

51单片机自动壁障小车设计,附原理图程序全套制作资料

大家好,欢迎关注电气技术微课堂!

在科学探索及紧急抢险中经常要对一些危险或人类不能直接到达的地域进行探测,这就需要用机器人来完成。而机器人在复杂地形行进时自动避障是一项必不可少也是最基本的功能。避障功能在日常生活中也是比较常见的,像是风靡一时的自动清扫机器人,只需放在地上一会就可以将你的屋子打扫干净,这里面的最基本功能也是避障,当它检测到前方有障碍就会绕开。这样就可以躲避家具将你的地板清理干净了。因此,自动避障系统的研发就应运而生。

MCS-51《单片机原理及接口技术》是中职院校电气自动化专业开设的 一门必修课程,该课程主要是通过对单片机的内部结构、相关外围电路及编程语言的学习,使学生掌握用单片机进行开发设计一些实用电子电路的能力,自动避障小车就是基于这一系统开发而成的。自动避障小车可以作为地域探索机器人和紧急抢险机器人的运动系统,让机器人在行进中自动避过障碍物。

一、本设计任务和主要内容

本设计是对以单片机STC89C52RC为核心的系统根据感测模块传输的前方路面信息,控制小车行驶走向的软、硬件设计开发。系统要能够做到准确及时监测前方路面信息并传输给主控模块,做到根据前方路面信息及时调整小车的走向,做到显示小车的走向和小车已经行驶过的路程。

壁障小车的主要功能是:

① 感测模块实时监测路面情况并及时将障碍物的位置传输给单片机;

② 单片机核心模块根据感测模块给予的信息控制小车两电机转动;

③ 电机驱动模块驱动两电机转动,实现转向与行走。

二、系统主要硬件电路设计

根据设计要求,我们的自动避障小车主要由五个模块构成:车体框架、电源及稳压模块、主控模块、探测模块、电机驱动模块组成。 各模块分述如下:

图1 系统模块组成框图

2.1 小车避障原理分析

小车车头处装有三个红外探头,中间一个光电开关对向正前方,两侧的红外探头向两边各分开30度,(如图2所示)。小车在行进过程中由红外探头向前方发射出红外线,当红外线遇到障碍物时发生漫反射,反射光被光电开关接收。小车根据三个探头接受信号的情况来判断前方障碍物的分布并做出相应的动作。

图2 自动避障小车车体及避障原理图

红外探头选用的是E12-D15NK型红外避障传感器,这是一种集发射与接收于一体的光电传感器,发射光经过调制后发出,接收头对反射光进行解调输出。有效的避免了可见光的干扰。分别探测正前方,前右侧,前左侧障碍物信息,在特殊地形(如障碍物密集地形)可将正前方的光电开关移置后方进行探测。E12-D15NK光电开关平均有效探测距离0~30cm可调,且抗外界背景光干扰能力强,可在日光下正常工作(理论上应避免日光和强光源的直接照射)。我们小车换档调速后的最大制动距离不超过30cm,一般在10~20cm左右,因而探测距离满足我们的小车需求示意图如下:

图4 红外避障传感器原理图

电气特性:

红色:VCC;黑色:GND;黄色:信号输出;白色:和红线一起外接电位器。

工作电压:5VDC

工作电流:10-15mA

驱动电流:100mA

感应距离:1-15CM

机械特性:

颜色:橙黄色

直径:12MM

长度:35MM

引线长度:25CM(不含接头)

2.2电源模块

方案一: 采用交流电经直流稳压处理后供电 采用交流电提供直流稳压电源,电流驱动能力及电压稳定性最好,且负载对电源影响也最小。但由于需要电线对小车供电,极大影响了壁障小车行动的灵活性及地形的适应能力。而且壁障小车极易把拖在地上的电线识别为障碍物,人为增加了不必要的障碍。故我放弃了这一方案。

方案二: 采用蓄电池供电 蓄电池具有较强的电流驱动能力和较好的电压稳定性能,且成本低廉。可采用蓄电池经7812芯片稳压后给电机供电,再经过降压接7805芯片给单片机及其他逻辑单元供电。但蓄电池体积相对庞大,且重量过大,造成电机负载过大,不适合我们采用的小车车架(玩具电动车车架)。故我放弃了这一方案。

方案三: 采用干电池组进行供电 采用四节干电池降压至5V后给单片机及其他逻辑单元供电,另取六节干电池为电机及光电开关供电。这样电机启动及制动时的短暂电压干扰不会影响到逻辑单元和单片机的工作。干电池用电池盒封装,体积和重量较小,同时玩具车底座可以安装四节干电池,正好可为单片机及其他逻辑单元供电。在稳压方面,起始时考虑使用7805芯片对6V的电池电压进行降压稳压。但考虑到这样使得7805芯片消耗大量能量,降低电池寿命;同时,由于STC89C51、光电开关、小车电机对于供电电压要求并不苛刻,故我们将6V电池电压接一个二极管降压后直接给单片机及其他逻辑单元供电。而电机和光电开关的电源不做稳压处理。这样只需在小车主板上加两个调速按钮,根据电池电量选择合适功率即可,甚至于可直接在软件里设置自动换挡。 综合考虑,我采用方案三。

2.3主控模块 3.1、STC89C52RC单片机最小系统

我采用的是STC公司的51内核单片机STC89C52RC,单片机最小系统及概述如下:STC89C52RC单片机介绍

STC89C52RC单片机是宏晶科技推出的新一代高速/低功耗/超强抗干扰的单片机,指令代码完全兼容传统8051单片机,12时钟/机器周期和6时钟/机器周期可以任意选择。

主要特性如下:

1. 增强型8051单片机,6时钟/机器周期和12时钟/机器周期可以任意选择,指令代码完全兼容传统8051.

2. 工作电压:5.5V~3.3V(5V单片机)/3.8V~2.0V(3V单片机)

3. 工作频率范围:0~40MHz,相当于普通8051的0~80MHz,实际工作频率可达48MHz

4. 用户应用程序空间为8K字节

5. 片上集成512字节RAM

6. 通用I/O口(32个),复位后为:P1/P2/P3/P4是准双向口/弱上拉,P0口是漏极开路输出,作为总线扩展用时,不用加上拉电阻,作为I/O口用时,需加上拉电阻。

7. ISP(在系统可编程)/IAP(在应用可编程),无需专用编程器,无需专用仿真器,可通过串口(RxD/P3.0,TxD/P3.1)直接下载用户程序,数秒即可完成一片

8. 具有EEPROM功能

9. 具有看门狗功能

10. 共3个16位定时器/计数器。即定时器T0、T1、T2

11. 外部中断4路,下降沿中断或低电平触发电路,Power Down模式可由外部中断低电平触发中断方式唤醒

12. 通用异步串行口(UART),还可用定时器软件实现多个UART

13. 工作温度范围:-40~+85℃(工业级)/0~75℃(商业级)

14. PDIP封装

在探测模块和单片机中断接口之间、独立按键与单片机中断接口之间,需要经过电平的逻辑处理进行连接。主要涉及到一个三输入或非门和一个二输入与门。这两个逻辑关系我们直接选用74HC系列的集成芯片实现。 由于三输入或非门在市场上很难购买到,我们采用了两个二输入或非门和一个二输入与门完成了三输入或非门。由于我们采用的74HC08(四二输入与门)、74HC02(四二输入或非门)均为四二输入的,各提供四个二输入与门和四个二输入或非门,我们用各用一片芯片即可实现所需逻辑功能。

2.4电机驱动模块

本系统采用了L298N芯片来驱动电机 ,L298N是一个具有高电压大电流的全桥驱动芯片,输出电压最高可达50V,可以直接通过电源来调节输出电压;可以直接用单片机的IO口提供信号,而且带有使能端,方便PWM调速,电路简单,性能稳定,使用比较方便。L298N芯片可以驱动两个二相电机,也可以驱动一个四相电机,正好符合我们小车两个二相电机的驱动要求。 综合考虑,我采用L298N芯片驱动小车电机。

最终方案如下: 使用干电池组对系统供电,改造玩具电动车作为小车底座,采用STC89C52RC作为主控芯片,采用E12-D15NK光电开关进行障碍物探测,使用L298N驱动直流电机。逻辑关系处理使用74HC系列芯片完成。

2.5 总电路图

图5 总电路图设计

三、系统软件设计

3.1程序流程图

本系统设计流程图如下

图6 系统软件主流程图

3.2系统程序清单

#include <reg51.h>

#define uchar unsigned char

#define uintunsigned int

/********************

端口定义

*********************/

sbit IN1=P1^0; //P10与电机驱动IN1相连

sbit IN2=P1^1 //P11与电机驱动IN2相连

sbit IN3=P1^2; //P12与电机驱动IN3相连

sbit IN4=P1^3; //P13与电机驱动IN4相连

uchar INS=P2; //P2端口的^0、P2^1、P2^2分别与左、中、右红外模块输出信号线线相连

uint D=200;//定义延迟函数的参数

/************************

各个子函数定义

***********************/

void Go(void)

{

IN1=0;

IN2=0;

IN3=1;

IN4=0;

}

void Back(void)

{

IN1=0;

IN2=0;

IN3=0;

IN4=1;

}

void Go_left(void)

{

IN1=1;

IN2=0;

IN3=1;

IN4=0;

}

void Go_right(void)

{

IN1=0;

IN2=1;

IN3=1;

IN4=0;

}

void Stop(void)

{

IN1=IN2=IN3=IN4=0;

}

/***

void Back_left(void)

{

IN1=1;

IN2=0;

IN3=0;

IN4=1;

}

void Back_right(void)

{

IN1=0;

IN2=1;

IN3=0;

IN4=1;

}

***/

void Delay(uint n)

{

uint i,j;

i=j=n;

for(;i>0;i--)

for(;j>0;j--);

}

void Be_move(void)

{

uchar temp;

temp=INS&0x07;

switch(temp)

{

case 0x01:Go_right();Go();Delay(D);break;

case 0x02:

case 0x03:

case 0x07:Back();Delay(D);Go_right();Go();Delay(D);break;

case 0x06:Back();Delay(D);Go_left();Go();Delay(D);break;

case 0x04:Go_left();Go();Delay();break;

case 0x05:Go();Delay();break;

default:Stop();Delay();break;

}

}

void main()

{

uchar temp;

while(1)

{

temp=INS&0x07;

if(temp==0x00) Go();

else Be_move();

}

}

【51单片机】模块化编程的一般步骤和基础说明

51 单片机的模块化编程是将程序按照功能划分为不同的模块,每个模块具有相对独立的功能,分别放在不同的 .c 文件和 .h 文件中。

以下是进行 51 单片机模块化编程的一般步骤和基础说明:

1. 模块划分:确定程序中的各个功能模块,例如延时函数、数码管显示函数、LCD 显示函数等。每个模块应具有明确的功能和相对独立的代码。

2. 创建 .c 文件**:为每个模块创建一个对应的 .c 文件,用于实现该模块的具体功能。在 .c 文件中编写函数的定义和相关代码。

3. 创建 .h 文件(头文件)**:为每个 .c 文件创建一个同名的 .h 文件。头文件用于声明模块中可供外部调用的函数、变量等。头文件的内容通常使用预处理指令 #ifndef 、 #define 和 #endif 来防止重复包含,例如:

#ifndef __MODULE_H__

#define __MODULE_H__

// 函数声明、变量声明等

#endif

 

4. 在 .c 文件中实现功能**:在对应的 .c 文件中具体实现模块的功能,编写函数的代码逻辑。

5. 在头文件中声明函数和变量**:在 .h 文件中声明在 .c 文件中定义的函数、全局变量等,以便其他文件可以使用这些函数和变量。例如:

void function1(void);

int variable1;

 

6. 在主程序或其他需要使用该模块的文件中包含头文件**:使用 #include "module.h" 语句将所需模块的头文件包含到主程序或其他 .c 文件中,这样就可以调用头文件中声明的函数和使用相关变量。

7. 调用模块功能**:在主程序或其他模块中,根据需要调用相应模块的函数来实现具体功能。

通过模块化编程,可以提高代码的可读性、可维护性和可移植性。各个模块可以独立开发、测试和修改,而不会影响其他部分的代码。同时,也方便多人协作开发,以及在不同项目中复用已有的模块。

例如,假设有一个数码管显示模块,包含数码管显示函数和相关的段码表。以下是示例代码:

数码管显示的 .c 文件( nixie.c ):

#include

#include "delay.h" // 包含延时函数的头文件,因为要使用其中的延时功能

// 数码管段码表

unsigned char NixieTable() = {

0x3F, 0x06, 0x5B, 0x4F,

0x66, 0x6D, 0x7D, 0x07,

0x7F, 0x6F

};

// 数码管显示子函数

void Nixie(unsigned char Location, Number) {

switch (Location) // 位码输出

{

case 1:

P2_4 = 1;

P2_3 = 1;

P2_2 = 1;

break;

case 2:

P2_4 = 1;

P2_3 = 1;

P2_2 = 0;

break;

// 省略其他 case 情况

}

P0 = NixieTable(Number); // 段码输出

delay(1); // 显示一段时间

P0 = 0x00; // 段码清 0,消影

}

 数码管显示的 .h 文件( nixie.h ):

#ifndef __NIXIE_H__

#define __NIXIE_H__

void Nixie(unsigned char Location, Number);

#endif

 在主程序( main.c )中使用该数码管显示模块时,只需包含 nixie.h 头文件,然后就可以调用 Nixie 函数来显示数字:

#include

#include "nixie.h" // 包含数码管显示模块的头文件

void main() {

while (1) {

Nixie(1, 6); // 在数码管的第 1 位置显示 6

}

}

 这样,通过模块化编程,将数码管显示的功能封装在一个模块中,使得主程序更加简洁清晰,易于理解和维护。如果需要修改数码管显示的相关代码,只需在 nixie.c 和 nixie.h 中进行修改,而不会影响到主程序的其他部分。同时,在其他项目中如果也需要使用数码管显示功能,只需将这两个文件添

相关问答

单片机 C语言的switch语句中的 break 这在哪?

如果代码段太长、想让自己看着清晰,是可以有的,效果上与没用大括号相同。但break要放在大括号外。这是我的一种理解,欢迎大牛们批评指正~在switch中,大括号可以...

为什么51 单片机 不能用 break 语句?

单片机是可以使用break语句的,在使用switch语句的时候是可以使用的。单片机是可以使用break语句的,在使用switch语句的时候是可以使用的。

单片机 怎样跳出while(1)无限循环?

可用break跳出循环,break语句可跳出任何的循环;因为你这个while(1)是死循环,所以得用break,除非你将1改成其它条件。可用break跳出循环,break语句可跳出任何...

单片机 for语句可以直接跳出吗?

在单片机编程中,for循环和其他类型的循环(如while循环)通常不会提供像传统高级语言中的break语句那样的直接跳出功能。如果你需要提前结束循环,你需要使...

51 单片机 循环语句有几种?

51单片机程序中,循环语句一般采用for、while和do...while来实现在循环中可以采用countune退出当次循环,继续执行下一次循环在循环中可以采用break退出循...

单片机 串口通信原理

我有一个8255的0-99的计时的,不知道对你有没有帮助;164串并转换程序,00~99循环显示;DCLK----PC0,DIN----PC1;FUNCTIONCODEMY_STACKSEGMEN...

用C语言写51 单片机 闹钟程序 - 156****1626 的回答 - 懂得

汇编做的可以不.有秒表.有闹钟.//*********************************************************//实现2113功能:本程序实现在P1口模拟一个...

请教STC51 单片机 switch语句问题?

该语句格式是:switch(变量名){case1:…break;case2…break;default…break;}该语句格式是:switch(变量名){case1:…brea...

利用C语言写 单片机 程序,怎么利用for或者while使LED灯闪几下...

设置循环条件或者用breakfor循环几次,然后跳出就可以了。4条回答:【推荐答案】voidmdelay(unsignedintdelaytime)//延时程序{unsignedintj=0;/...

单片机 动态显示的程序?

P0=smgduan[i];delay(100);这两句是显示字母的语句,把它们加入对应的case语句里,就可以指定哪一段数码管显示啥字母,比如:case(2):LSA=0;LSB=1;LSC.....

猜你喜欢