基于51系列单片机的(循迹、避障、蓝牙)智能小车(2)源代码

主程序

main.c

/*************************************************************************************************
项目说明:
	本项目由粤嵌公司指导完成,能够实现循迹、避障、无线蓝牙遥控功能。循迹、避障均采用YL—70壁障传感
器,无线蓝牙遥控功能采用HC-05蓝牙模块。小车行走采用模拟PWM控制直流电机转速,行走稳定。

项目接线:
	1,左方直流电机-->P0^0、P0^1,右方直流电机-->P0^2、P0^3
	2,循迹中控板IN1-IN4-->P0^4-P0^7

项目实验功能:
	1,自主沿黑色电胶带循迹
	2,自主避障
	3,无线蓝牙遥控小车行走

*************************************************************************************************/
#include "motor.h"
#include "infrared.h"
#include "key.h"
#include "led.h"
#include "uart.h"
#include "delay.h"

unsigned char sendbuf[]={"AT+NAME=GEC_Liudehua\r\n"};
void main(void)
{
	TMOD |= 0x01;
	TH0=(65526-100)/256;
	TL0=(65526-100)%256;
	TR0 = 1;//启动定时器0
	ET0 = 1;//允许定时器0中断
	EA	= 1;//总中断允许
	
	uart_init();
	while(1)
	{
		if(key_status(KEY1) == KEY_DOWN) //循迹功能
		{
			led_ctrl(LED0,LED_ON);
			search_path();
		}
		else if(key_status(KEY2) == KEY_DOWN)//避障功能
		{
			led_ctrl(LED1,LED_ON);
			auto_avoid();
		}
		else if(key_status(KEY3) == KEY_DOWN)//蓝牙遥控功能
		{
			led_ctrl(LED2,LED_ON);
			remote_control();
		}
		else if(key_status(KEY4) == KEY_DOWN)//串口发送功能
		{
			uart_SendBytes(sendbuf,sizeof(sendbuf));
			delay_ms(200);
		}
	}
}

按键模块

key.h

#ifndef  __KEY_H__
#define  __KEY_H__

#include <reg52.h>
enum KEY_NUM{KEY1,KEY2,KEY3,KEY4};
enum KEY_STATUS{KEY_DOWN,KEY_UP,KEY_ERR};
/*
	@brief key_status: 判断指定的按键的状态
	@param key_num:    指定获取哪个按键的状态,可选择为KEY1,KEY2,KEY3,KEY4
	@retval:           KEY_DOWN 表示按键按下
	                   KEY_UP   表示按键松开
*/
extern int key_status(int key_num);
#endif


key.c

#include "key.h"

/*
	@brief key_status: 判断指定的按键的状态
	@param key_num:    指定获取哪个按键的状态,可选择为KEY1,KEY2,KEY3,KEY4
	@retval:           KEY_DOWN 表示按键按下
	                   KEY_UP   表示按键松开
*/
int key_status(int key_num)
{
	switch(key_num)
	{
		case KEY1: 
			return !!(P3&(1<<3));//!!的作用是把真变成 1
		case KEY2:
			return !!(P3&(1<<4));
		case KEY3:
			return !!(P3&(1<<6));
		case KEY4:
			return !!(P3&(1<<7));
		default:
			return KEY_ERR;
	}
}


LED模块

led.h

#ifndef __LED_H__
#define __LED_H__


#include <reg52.h>
#define LED P1
enum LED_NUM{LED0,LED1,LED2,LED3,LED4,LED5,LED6,LED7};//LED编号的枚举类型
enum LED_STATE{LED_ON,LED_OFF};//LED状态的枚举类型
/*
@brief led ctrl:	用来控制某盏LED灯的状态
@param led_num:		指定控制哪盏LED灯的状态,可选择为LEDO,LED1,LED2,...LED7
@param led _state:	指定LED灯的状态,可选择为LED_ON,LED_OFF
@retval:			None
*/
extern void led_ctrl(int led_num, int led_state);
#endif

led.c

#include <reg52.h>

#define LED P1

enum LED_NUM{LED0,LED1,LED2,LED3,LED4,LED5,LED6,LED7};//LED编号的枚举类型
enum LED_STATE{LED_ON,LED_OFF};//LED状态的枚举类型
/*
  @brief ledctrl: 用来控制某盏LED灯的状态
  @param led_num: 指定控制哪盏LED灯的状态,可选择为LED0,LED1,LED2,....LED7
  @param led_state: 指定LED灯的状态,可选择为LED_ON,LED_OFF
  @retval:    None
*/
void led_ctrl(int led_num,int led_state)
{
	if(led_state == LED_ON)
	{
		LED	&=~ (1<<led_num);
	}
	else if(led_state == LED_OFF)
    {
		LED |= 1<<led_num;
	}
}

延时子程序

delay.h

#ifndef  __DELAY_H__
#define  __DELAY_H__

#include <reg52.h>
/*
	@brief: C51毫秒级延时函数
	@param n: 指定延时多少毫秒
	@retval: None 
*/
extern void delay_ms(unsigned int n);
#endif

delay.c

#include "delay.h"

/*
	@brief: C51毫秒级延时函数
	@param n: 指定延时多少毫秒
	@retval: None 
*/
void delay_ms(unsigned int n)
{
	unsigned char i;
	while(n--)
	{
		for(i=0;i<113;i++);
	}
}

剩余代码见下篇

版权声明:本文为CSDN博主「快乐学习的每一天」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_58562695/article/details/122439914

项目说明

本项目能够实现循迹、避障、无线蓝牙遥控功能。循迹、避障均采用YL—70壁障传感器,无线蓝牙遥控功能采用HC-05蓝牙模块。小车行走采用模拟PWM控制直流电机转速,行走稳定。

项目所需知识

一、 LED灯

由分析原理图可知
LED通过1K的排阻连接到VCC公共段
VCC ==> 1K电阻  ==> LED ==> P1.0
VCC ==> 1K电阻  ==> LED ==> P1.1
VCC ==> 1K电阻  ==> LED ==> P1.2
所以 P1.0~P1.7输出低电平LED点亮,输出高电平LED熄灭。
代码规范:
1) 对齐
2) 缩进
3) 有必要的注释

二、 LED流水灯

C51晶振为11.0592MHz时的毫秒级延时函数:
void delay_ms(unsigned int n)
{
	unsigned char i;
	while(n--)
	{
		for(i=0;i<113;i++);
	}
}
延时函数的分析:
	本开发板的晶振是11.0592MHz,该时钟频率进入C51内部时会12分频,即频率为
	11059200/12Hz。所以每执行一条指令的时间即机器周期为 12/11059200s。
	for(i=0;i<113;i++) ==> 有8条指令。
	所以for循环执行完毕的时间为 113*8*(12/11059200)s = 0.000980902s
	==> 与 0.001相差 0.00002s(十万分之2秒)	

三、模块化设计

企业做项目开发一般都是团队合作的方式,把一个大任务划分成许多小任务来完成。
嵌入式开发,一般把一个硬件模块作为一个模块来开发。
	SmartCar
		motor.c     motor.h
		infrared.c  infrared.h
		bluetooth.c bluetooth.h
		main.c
		
	这里的.c文件用来定义各个模块的功能函数,对应的.h文件用来把.c中定义的函数或者
	全局变量进行声明。
	
模块化设计的优势:
	1) 实现团队分工合作,大大提高了开发效率。
	2) 方便程序的调试以及后期的更新维护。
	3) 实现代码(模块)复用,减少程序冗余。
	4) 提高代码的可读性,实现无障碍交付。
	
	x & 0 ==> 0
	x & 1 ==> x
	x | 1 ==> 1
	x | 0 ==> x
	
	#include <reg52.h>
	#include "led.h"
	
	本质区别: <>在系统指定的标准库路径下搜索头文件(系统自带的头文件)
	          ""在工程目录下搜索头文件(自己写的头文件)

四、按键

由分析原理图可知,按键是共阴极解法,分别连接到P3.3,P3.4,P3.6,P3.7。
因此,按键按下的输入状态是低电平,松开按键,输入状态为高电平。

五、数码管

数码管就是用来显示数字的电子器件
每个“8”都是由8盏不同位置的LED灯构成。

段选: 决定了哪些位置上的灯亮,即显示什么内容。
位选: 段选的公共端称为位选,四位数码码可以显示四个数字,所以有4个位选。

共阳极数码管:  位选流入电流,段选流出电流
共阴极数码管:  段选流入电流,位选流出电流

我们开发板采用的是共阳极数码管。
段选连接到 P0.0~P0.7 ,低电平有效
位选通过三极管PNP再连接到 P1.0~P1.3, 也是低电平有效

视觉暂留原理:
	当随着时间的变化,位选和段选都在快速切换,那么我们人眼看到的讲师一个静态的效果。

六、电机驱动模块

工业上常见的电机有三类:
	直流电机: 通直流电就可以转动,电流越大转速越快,电流方向反转,电机转向反转。
	步进电机: 通过电脉冲信号,可以精确控制转动角度,角位移和线位移。
	舵机: 也称伺服机,可以精确控制转动角度,而且有一定的力量去维持某个角度(力矩)。
	
本项目采用的是2个直流电机,但是C51的IO口的输出电流只有15mA左右,不能直接驱动直流
电机。所以我们通过电机驱动模块,该电机驱动模块是一个有源器件,可以驱动两个直流电机。

	La   ==>  P0.0
	Lb   ==>  P0.1
	VCC  ==>  5V/3V3
	GND  ==>  GND
	Ra   ==>  P0.2
	Rb   ==>  P0.3
	
小车的运动控制分析:
	前进:
		La = 1;
		Lb = 0;
		Ra = 1;
		Rb = 0;
	后退:
		La = 0;
		Lb = 1;
		Ra = 0;
		Rb = 1;
	停止:
		La = 1;
		Lb = 1;
		Ra = 1;
		Rb = 1;
	原地左转:
		La = 0;
		Lb = 1;
		Ra = 1;
		Rb = 0;
	原地右转:
		La = 1;
		Lb = 0;
		Ra = 0;
		Rb = 1;
	前进左偏:
		左右轮都往前走,但是右轮比左轮快
	前进右偏:
		左右轮都往前走,但是左轮比右轮快

七、红外循迹模块

当模块检测到前方障碍物信号时,电路板上红色指示灯点亮,同时 OUT
端口持续输出低电平信号,该模块检测距离 2~60cm,检测角度 35°,检测距离可
以通过电位器进行调节,顺时针调电位器,检测距离增加;逆时针调电位器,检
测距离减少。	
	
	IN1 ==> P0.4  避障左
	IN2 ==> P0.5  循迹左
	IN3 ==> P0.6  循迹右
	IN4 ==> P0.7  避障右
	
循迹功能的实现:
	把探头朝向地面,把黑线夹在中间,根据探头的输入状态,来控制小车运动轨迹,
	来实现循迹功能。
	
避障功能的实现:	
	把探头安装在小车的左右两边,检测水平面有没有障碍物。

八、串口蓝牙模块(HC-05)

HC-05用来实现数据透传。有两种工作模式:
	1) AT命令模式: C51通过串口发送给HC-05的数据都当作AT指令。
		AT指令: 就是一些设计好了的字符串,用来配置或查询工作。
			"AT+NAME=GEC_Liudehua\r\n" 修改设备名称
			
	2) 自动连接模式:
		手机通过蓝牙协议发送给HC-05的数据,会原封不动的转发给C51
		C51通过串口发送给HC-05的数据,也会原封不动的转发给手机
	

PIO8连接了一个LED灯: 如果没有手机跟HC-05通信,则1s闪两次,
					 有手机跟HC-05通信,则2s闪一次。
					 配对密码: 1234
PIO11连接了一个按键:
				按键按下状态则是 AT命令模式
				一旦松开,马上就是自动连接模式

项目视频演示

智能小车演示视频

版权声明:本文为CSDN博主「快乐学习的每一天」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_58562695/article/details/122439564

项目说明

本项目能够实现循迹、避障、无线蓝牙遥控功能。循迹、避障均采用YL—70壁障传感器,无线蓝牙遥控功能采用HC-05蓝牙模块。小车行走采用模拟PWM控制直流电机转速,行走稳定。

项目所需知识

一、 LED灯

由分析原理图可知
LED通过1K的排阻连接到VCC公共段
VCC ==> 1K电阻  ==> LED ==> P1.0
VCC ==> 1K电阻  ==> LED ==> P1.1
VCC ==> 1K电阻  ==> LED ==> P1.2
所以 P1.0~P1.7输出低电平LED点亮,输出高电平LED熄灭。
代码规范:
1) 对齐
2) 缩进
3) 有必要的注释

二、 LED流水灯

C51晶振为11.0592MHz时的毫秒级延时函数:
void delay_ms(unsigned int n)
{
	unsigned char i;
	while(n--)
	{
		for(i=0;i<113;i++);
	}
}
延时函数的分析:
	本开发板的晶振是11.0592MHz,该时钟频率进入C51内部时会12分频,即频率为
	11059200/12Hz。所以每执行一条指令的时间即机器周期为 12/11059200s。
	for(i=0;i<113;i++) ==> 有8条指令。
	所以for循环执行完毕的时间为 113*8*(12/11059200)s = 0.000980902s
	==> 与 0.001相差 0.00002s(十万分之2秒)	

三、模块化设计

企业做项目开发一般都是团队合作的方式,把一个大任务划分成许多小任务来完成。
嵌入式开发,一般把一个硬件模块作为一个模块来开发。
	SmartCar
		motor.c     motor.h
		infrared.c  infrared.h
		bluetooth.c bluetooth.h
		main.c
		
	这里的.c文件用来定义各个模块的功能函数,对应的.h文件用来把.c中定义的函数或者
	全局变量进行声明。
	
模块化设计的优势:
	1) 实现团队分工合作,大大提高了开发效率。
	2) 方便程序的调试以及后期的更新维护。
	3) 实现代码(模块)复用,减少程序冗余。
	4) 提高代码的可读性,实现无障碍交付。
	
	x & 0 ==> 0
	x & 1 ==> x
	x | 1 ==> 1
	x | 0 ==> x
	
	#include <reg52.h>
	#include "led.h"
	
	本质区别: <>在系统指定的标准库路径下搜索头文件(系统自带的头文件)
	          ""在工程目录下搜索头文件(自己写的头文件)

四、按键

由分析原理图可知,按键是共阴极解法,分别连接到P3.3,P3.4,P3.6,P3.7。
因此,按键按下的输入状态是低电平,松开按键,输入状态为高电平。

五、数码管

数码管就是用来显示数字的电子器件
每个“8”都是由8盏不同位置的LED灯构成。

段选: 决定了哪些位置上的灯亮,即显示什么内容。
位选: 段选的公共端称为位选,四位数码码可以显示四个数字,所以有4个位选。

共阳极数码管:  位选流入电流,段选流出电流
共阴极数码管:  段选流入电流,位选流出电流

我们开发板采用的是共阳极数码管。
段选连接到 P0.0~P0.7 ,低电平有效
位选通过三极管PNP再连接到 P1.0~P1.3, 也是低电平有效

视觉暂留原理:
	当随着时间的变化,位选和段选都在快速切换,那么我们人眼看到的讲师一个静态的效果。

六、电机驱动模块

工业上常见的电机有三类:
	直流电机: 通直流电就可以转动,电流越大转速越快,电流方向反转,电机转向反转。
	步进电机: 通过电脉冲信号,可以精确控制转动角度,角位移和线位移。
	舵机: 也称伺服机,可以精确控制转动角度,而且有一定的力量去维持某个角度(力矩)。
	
本项目采用的是2个直流电机,但是C51的IO口的输出电流只有15mA左右,不能直接驱动直流
电机。所以我们通过电机驱动模块,该电机驱动模块是一个有源器件,可以驱动两个直流电机。

	La   ==>  P0.0
	Lb   ==>  P0.1
	VCC  ==>  5V/3V3
	GND  ==>  GND
	Ra   ==>  P0.2
	Rb   ==>  P0.3
	
小车的运动控制分析:
	前进:
		La = 1;
		Lb = 0;
		Ra = 1;
		Rb = 0;
	后退:
		La = 0;
		Lb = 1;
		Ra = 0;
		Rb = 1;
	停止:
		La = 1;
		Lb = 1;
		Ra = 1;
		Rb = 1;
	原地左转:
		La = 0;
		Lb = 1;
		Ra = 1;
		Rb = 0;
	原地右转:
		La = 1;
		Lb = 0;
		Ra = 0;
		Rb = 1;
	前进左偏:
		左右轮都往前走,但是右轮比左轮快
	前进右偏:
		左右轮都往前走,但是左轮比右轮快

七、红外循迹模块

当模块检测到前方障碍物信号时,电路板上红色指示灯点亮,同时 OUT
端口持续输出低电平信号,该模块检测距离 2~60cm,检测角度 35°,检测距离可
以通过电位器进行调节,顺时针调电位器,检测距离增加;逆时针调电位器,检
测距离减少。	
	
	IN1 ==> P0.4  避障左
	IN2 ==> P0.5  循迹左
	IN3 ==> P0.6  循迹右
	IN4 ==> P0.7  避障右
	
循迹功能的实现:
	把探头朝向地面,把黑线夹在中间,根据探头的输入状态,来控制小车运动轨迹,
	来实现循迹功能。
	
避障功能的实现:	
	把探头安装在小车的左右两边,检测水平面有没有障碍物。

八、串口蓝牙模块(HC-05)

HC-05用来实现数据透传。有两种工作模式:
	1) AT命令模式: C51通过串口发送给HC-05的数据都当作AT指令。
		AT指令: 就是一些设计好了的字符串,用来配置或查询工作。
			"AT+NAME=GEC_Liudehua\r\n" 修改设备名称
			
	2) 自动连接模式:
		手机通过蓝牙协议发送给HC-05的数据,会原封不动的转发给C51
		C51通过串口发送给HC-05的数据,也会原封不动的转发给手机
	

PIO8连接了一个LED灯: 如果没有手机跟HC-05通信,则1s闪两次,
					 有手机跟HC-05通信,则2s闪一次。
					 配对密码: 1234
PIO11连接了一个按键:
				按键按下状态则是 AT命令模式
				一旦松开,马上就是自动连接模式

项目视频演示

智能小车演示视频

版权声明:本文为CSDN博主「快乐学习的每一天」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_58562695/article/details/122439564

生成海报
点赞 0

快乐学习的每一天

我还没有学会写个人说明!

暂无评论

相关推荐

CC2530 常用寄存器

一、端口初始化相关寄存器 代码示例:用按键1和按键2分别控制D4和D6灯 点我跳转 二、INT相关寄存器 代码示例:利用key1,key2来产生中断控制D3,D5灯,key1,key2为下降沿触

【单片机】Arduino进阶应用

前期教程 【单片机】Arduino(以UNO R3为例)—— 基本函数汇总【单片机】Arduino供电总结【嵌入式模块】舵机使用详解 前言 作为最容易入门的单片机之一,Arduino总是可以用非常简