51单片机课程设计做了辆蓝牙小车,下面是对课程设计内容的一些总结
硬件模块
L298N
具体如图所示:
工作原理
简介:可以直接驱动两路 3-16V 直流电机,并提供了 5V 输出接口(输入最低只要 6V),可以给 5V 单片机电路系统供电。 输入电压最好是7v以上,输入电压低了会导致一系列问题,在后面有具体实践总结 具体应用:可以方便的控制直流电机速度和方向,也可以控制 2 相步进电机,5 线 4 相步进电机。
管脚应用可以参考如图所示: ①板载5V输出使能: 如果跳线帽接上,则5v端子可以输出电压,若跳线帽没有街上,则12v输入端子没有作用,只能5v输入口输入(如果不接上直接废了,5v输入基本不能使电机模块正常工作) ②AB通道使能: 端子接在上面表示AB通道一直保持高电平,处于使能状态,并且电压和5v输入端口电压相同;若处于没有使能状态,直接影响到输入端,让其无法工作! ③单片机IO控制输入 + 马达AB输出 : 顾名思义,四个IO输入端口和单片机四个IO口相连,然后通过电机驱动模块(双H桥电路)马达AB输出,以获得更大的驱动直流减速电机的能力,带动电机转动! B站直接搜L298N电机驱动模块,有视频详情介绍
问题以及解决方案
下面是一些使用L298N驱动电机的一些问题以及解决方法总结 问题:1.直流减速电机不能正常转动,一个轮子只能单方向转动 2.使能端口帽摘下来后,pwm信号输入问题 3.供电问题 解决:1.起初用4节南孚电池供电,用万用表测电压小于4.8v(电池快没啥电了),更换四节电池后用万用表测得4.9v+,上面出现的问题解决了 2.输入端电压小于7v(用得四节南孚电池6v不到供电),使能电压和5v输入端子的电压相同,经测量5v端口电压只有3.8v左右,故使能电压就只有3.8v左右了,对PWM输出使能有一定影响 3.L298N电机驱动中有稳压降压模块,如果供电足够大(大于7v),那么稳压降压模块会发挥作用,使得5v输入端子、使能端子、马达电机都能有稳定的5v高电平输出。
红外对管
工作原理
具体如图所示: 一些注意事项如下: ①VCC:外接3.3-5v(可以直接接L298N的5v端) GND:外接GND ; OUT:外接开发板或者单片机的IO口(有遮挡输出低电平,无遮挡输出高电平) ②距离较远/未感应到障碍物:输出指示灯灭,OUT引脚输出高电平 距离较近,感应到障碍物时,输出指示灯亮,OUT输出低电平 距离较近,感应到黑色物体时候,黑管接收不到,输出指示灯灭,OUT引脚输出高电平 ③检测距离2~30mm,可以通过电位器进行调节;顺时针调节,检测距离增加;逆时针调节,检测距离减少
HC-05 蓝牙模块
模块介绍
主要用于短距离的数据无线传输领域。可以方便的和 PC 机的蓝牙设备相连,也可以两个模块之间的数据互通。避免繁琐的线缆连接,能直接替代串口线。
工作原理
如图所示,核心模块使用蓝牙模块从模块,引出接口包括VCC,GND,TXD,RXD(TX、RX和串口通讯有关) 具体使用事项: ①led 指示蓝牙连接状态,闪烁表示没有蓝牙连接,需要进行配对;常亮表示蓝牙已连接并打开了端口 ②配对以后当全双工串口使用,无需了解任何蓝牙协议,但仅支持 8 位数据位、1 位停止位、无奇偶校验的通信格式。 ③在未建立蓝牙连接时支持通过 AT 指令设置波特率、名称、配对密码,设置的参数掉电保存。蓝牙连接以后自动切换到透传模式
④蓝牙的使用
AT指令
HC-05进入 AT 命令: 按住按键或EN脚拉高,此时灯是慢闪, HC-05进入AT命令模式,默认波特率是38400(原始模式),原始模式下一直处于AT命令模式状态。 ①测试通讯 发送:AT(返回 OK,一秒左右发一次) 返回:OK ②改蓝牙串口通讯波特率 发送:AT+BAUDx 其中x代表0-C
字符x | 波特率(bauds) |
---|
1 | 1200 | 2 | 2400 | 3 | 4800 | 4 | 9600(常用) | 5 | 19200 | 6 | 38400 | 7 | 57600 | 8 | 115200(常用) | 9 | 230400 | A | 460800 | B | 921600 | C | 1382400 |
返回:BAUD(波特率) ③改蓝牙名称 发送:AT+NAMEname 返回:OK 参数 name:所要设置的当前名称,即蓝牙被搜索到的名称。20 个 字符以内 ④改蓝牙配对密码 发送:AT+PSWDxxxx 返回:+PSWD=xxxx 例如 设置密码888888 AT+PSWD123456 返回密码 123456 ⑤更改模块的主从模式 发送:AT+ROLE=1(设置模块为主模式 Master) 返回:+ROLE=1 发送:AT+ROLE=0(设置模块为从模式 Slave) 返回:+ROLE=0
TT电机
下面为一些电机注意事项
不带编码器,不能测速,测速的话需要添加测速模块;性能也没有编码器电机好。 两个电阻片端子,通过导线和AB马达输出端子连接,输出电平相反,电机实现前后转动;输出电平均为0,电机停止转动;
硬件接线
具体参考简图所示:
软件部分
电机车轮
chelun.c
#include <REG52.H>
#include "CheLun.h"
#include <intrins.h>
sbit ENA = P1^0;
sbit Left_IN1 = P1^1;
sbit Left_IN2 = P1^2;
sbit Right_IN3 =P1^3;
sbit Right_IN4 =P1^4;
sbit ENB = P1^5;
unsigned char pwm_val_left;
unsigned char pwm_val_right;
unsigned char push_val_left;
unsigned char push_val_right;
unsigned char Left_Speed_Ratio =15;
unsigned char Right_Speed_Ratio =15 ;
bit Left_moto_flag = 1;
bit Right_moto_flag = 1;
void Delay1000ms()
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void pwm_out_left_moto()
{
if(Left_moto_flag)
{
if(pwm_val_left<=push_val_left)
ENA=1;
else
ENA=0;
if(pwm_val_left>20)
pwm_val_left=0;
}
else
ENA=0;
}
void pwm_out_right_moto()
{
if(Left_moto_flag)
{
if(pwm_val_right<=push_val_right)
ENB=1;
else
ENB=0;
if(pwm_val_right>20)
pwm_val_right=0;
}
else
ENB=0;
}
void Left_moto_Go() {Left_IN1 = 0,Left_IN2 = 1;}
void Left_moto_Back() {Left_IN1 = 1,Left_IN2 = 0;}
void Left_moto_Stop() {Left_IN1 = 1,Left_IN2 = 1;}
void Right_moto_Go() {Right_IN3 = 1,Right_IN4 = 0;}
void Right_moto_Back(){Right_IN3 = 0;Right_IN4 = 1;}
void Right_moto_Stop(){Right_IN3 = 1;Right_IN4 = 1;}
void GoStright()
{
push_val_left =Left_Speed_Ratio;
push_val_right =Right_Speed_Ratio;
Left_moto_Go();
Right_moto_Go();
}
void GoBack()
{
push_val_left =Left_Speed_Ratio;
push_val_right =Right_Speed_Ratio;
}
void TurnLeft()
{
push_val_right =10;
Right_moto_Go();
Left_moto_Stop();
}
void TurnRight()
{
push_val_left =10;
Right_moto_Stop();
Left_moto_Go();
}
void Stop()
{
Left_moto_Stop();
Right_moto_Stop();
}
void Rotate()
{
push_val_left =Left_Speed_Ratio;
push_val_right =Right_Speed_Ratio;
Left_moto_Back();
Right_moto_Go();
}
chelun.h
#ifndef _CHELUN_H_
#define _CHELUN_H_
void Delay1000ms();
void Left_moto_Go(void);
void Left_moto_Back(void);
void Left_moto_Stop(void);
void Right_moto_Go(void);
void Right_moto_Back(void);
void Right_moto_Stop(void);
void pwm_out_left_moto(void);
void pwm_out_right_moto(void);
void Rotate();
void Stop();
void TurnRight();
void TurnLeft();
void GoBack();
void GoStright();
#endif
红外对管
RED.c
#include <REG52.H>
#include "RED.H"
sbit RED_LEFT = P2^6;
sbit RED_RIGHT = P2^7;
sbit Left_led = P2^1;
sbit Right_led = P2^0;
void RED_test()
{
RED_RIGHT=1;
if(RED_RIGHT == 0)
{
LED1=1;
}
else
{
LED1=0;
}
}
void xj_Run()
{
if(Left_led == 0 && Right_led==1)
{
TurnLeft();
}
if(Left_led == 1 && Right_led==0)
{
TurnRight();
}
if(Left_led == 0 && Right_led==0)
{
GoStright();
}
}
RED.h
#ifndef _RED_H_
#define _RED_H_
void RED_test();
void xj_Run();
#endif
蓝牙模块
HR_SC.c
#include <REG52.H>
#include "HR_SC.H"
unsigned char flag;
void Init_UART()
{
TMOD &= 0X00;
TMOD |= 0X21;
SCON = 0X50;
PCON = 0X80;
TH1 = 0XFA;
TL1 = 0XFA;
ET1 = 0;
ES = 1;
EA = 1;
TR1 = 1;
}
void Init_Timer0()
{
TH0 = (65535-1000)/256;
TL0 = (65535-1000)%256;
ET0 = 1;
EA = 1;
TR0 = 1;
}
void SendByte(unsigned char temp)
{
SBUF = temp;
while(TI == 0);
TI = 0;
}
void HR_SC_INPUT()
{
flag = SBUF;
while(RI ==0);
RI = 0;
SendByte(flag);
}
HR_SC.h
#ifndef _HR_SC_H_
#define _HR_SC_H_
void Init_UART();
void HR_SC_INPUT();
void Init_Timer0();
void SendByte(unsigned char temp);
#endif
循迹小车
main.c
#include <REG52.H>
#include "CheLun.h"
#include "RED.h"
extern unsigned char pwm_val_left;
extern unsigned char pwm_val_right;
void Init_Timer0()
{
TMOD = 0X01;
TH0 = (65535-1000)/256;
TL0 = (65535-1000)%256;
ET0 = 1;
EA = 1;
TR0 = 1;
}
int main()
{
Init_Timer0();
while(1)
{
xj_Run();
}
}
void Timer0_ser () interrupt 1
{
TH0 = (65535-1000)/256;
TL0 = (65535-1000)%256;
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}
蓝牙小车
main.c
#include <REG52.H>
#include "HR_SC.H"
#include "RED.H"
#include "CHELUN.H"
sbit BEEP = P1^6;
extern unsigned char flag;
extern unsigned char Left_Speed_Ratio;
extern unsigned char Right_Speed_Ratio;
extern unsigned char pwm_val_left;
extern unsigned char pwm_val_right;
void Add_Speed_Ratio()
{
Left_Speed_Ratio++;
Right_Speed_Ratio++;
}
void Remine_Speed_Ratio()
{
Left_Speed_Ratio--;
Right_Speed_Ratio--;
}
void beep_ring()
{
BEEP = 0;
Delay1000ms();
BEEP = 1;
}
int main()
{
Init_UART();
Init_Timer0();
while(1)
{
switch (flag)
{
case 'A':Add_Speed_Ratio();break;
case 'B':Remine_Speed_Ratio();break;
case 'G':GoStright();break;
case 'K':GoBack();break;
case 'H':TurnLeft();break;
case 'J':TurnRight();break;
case 'I':beep_ring();Stop();break;
}
}
}
void UART_ser() interrupt 4
{
HR_SC_INPUT();
}
void Timer0_ser () interrupt 1
{
TH0 = (65535-1000)/256;
TL0 = (65535-1000)%256;
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}
总结
实现过程+问题
一.拼装车模: 对车子的总体构架有能有很好的理解
二.L298N电机驱动模块的测试+代码测试车轮运动情况: 了解到L298N的工作原理,测试电机运动情况可以增强代码调试能力,中间遇到过一些列不正常情况经过总结大部分都和供电有关(L298N供电最好用12v锂电池供电,我用的四节南孚电池只有6v左右,电机驱动模块不稳)建议用12v供电
三.红外对管模块的测试 实际情况下红外对管的识别度不是很好,很容易受到外界的干扰,用两个红外对管循迹有很大误差,循迹可以采用三路循迹模块或者更好好的方案! 在循迹转弯时候讲车速降低一点,不然车子容易跑飞,脱离循迹轨道,当然可以加入PID控制算法根据具体情况来控制车速(不建议51两轮小车,万向轮不好操作)
四.蓝牙模块的测试 蓝牙可以理解为一个手机上的串口调试助手,通过手机发送或接收指令, 而平时用的UART都是用ch340电平转化芯片来实现单片机和电脑串口的通讯!
|