校机甲大师比赛安装报告
一、所需材料
1.小车主体
亚克力板、车轮、四个6V直流电机
2.手动部分
蓝牙模块、51单片机最小系统板、蓝牙APP(BlueSPP)
3.自动部分
5路输出循迹模块
4.杜邦线(双公头、双母头、公母头)若干、驱动模块、5V降压模块、3.7V电池两节18650、充电器、舵机(机械臂,搞不定,没有完成)、开关
二、设计思路
这次比赛需要制作一台兼具自动循迹与手动控制夹取功能的机械臂,根据醒狮提供的材料有一下思路
1、电池供电给——驱动模块(12V,5V)、51最小系统板(5V)、蓝牙模块(5V)、舵机(5V)
2、准备两套程序——一套用来连接蓝牙,完成手动搬运比赛;一套自动完成自动搬运比赛。在中途换场时进行另外一套程序的烧录
3、在手动比赛中,手机APP连接蓝牙模块,向蓝牙发送字符串指令,小车按照蓝牙接收的指令执行相应的程序(用可以编辑按键的蓝牙串口APP额外添加若干个控制机械臂的指令,就可以完成对机械臂程序的调用),主要的指令有
- 前进
- 后退
- 左转
- 右转
- 机械臂夹取(机械臂对应的程序没有写出来)
- 机械臂松开
- 机械臂抬起
- 机械臂放下
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
//定义电机控制管脚
sbit MOTOA=P1^0;
sbit MOTOB=P1^1; //右侧电机
sbit MOTOC=P1^2;
sbit MOTOD=P1^3; //左侧电机
sbit STA=P2^5;
u8 DisPlayData[4];
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X76};
#define SMG_PORT P0
sbit LSA=P2^0;
sbit LSB=P2^1;
sbit LSC=P2^2;
sbit LSD=P2^3;
void delay10us(void) //误差 0us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
void delay_10us(u16 us)
{
while(us--);
}
void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
void Car_ForwardRun(void)//前进
{
MOTOA=1;
MOTOB=0;
MOTOC=1;
MOTOD=0;
}
void Car_BackwardRun(void)//后退
{
MOTOA=0;
MOTOB=1;
MOTOC=0;
MOTOD=1;
}
void Car_StopRun(void)//停止
{
MOTOA=0;
MOTOB=0;
MOTOC=0;
MOTOD=0;
}
void Car_LeftRun(void)//左转
{
MOTOA=1;
MOTOB=0;
MOTOC=0;
MOTOD=0;
}
void Car_RightRun(void)//右转
{
MOTOA=0;
MOTOB=0;
MOTOC=1;
MOTOD=0;
}
void DigDisplay(void)
{
u8 i;
for(i=0;i<4;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=1;LSC=1;LSD=1; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=1;LSD=1; break;//显示第1位
case(2):
LSA=1;LSB=1;LSC=0;LSD=1; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=1;LSD=0; break;//显示第3位
}
SMG_PORT=DisPlayData[i];//发送段码
delay_ms(1); //间隔一段时间扫描
SMG_PORT=0x00;//消隐
}
}
#define RELOAD_COUNT 0xFA //宏定义波特率发生器的载入值 9600
void UART_Init(void)
{
SCON=0X50; //设置为工作方式1
TMOD=0X20; //设置计数器工作方式2
PCON=0X80; //波特率加倍
TH1=RELOAD_COUNT; //计数器初始值设置
TL1=TH1;
ES=1; //打开接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}
void UART_SendByte(u8 dat)
{
ES=0; //关闭串口中断
TI=0; //清发送完毕中断请求标志位
SBUF=dat; //发送
while(TI==0); //等待发送完毕
TI=0; //清发送完毕中断请求标志位
ES=1; //允许串口中断
}
//定义蓝牙APP中控制按键的键值
#define BLUETOOTH_FORWARD 0x10
#define BLUETOOTH_BACKWARD 0x11
#define BLUETOOTH_LEFT 0x20
#define BLUETOOTH_RIGHT 0x21
#define BLUETOOTH_STOP 0x30
void BlueTooth_Init(void)
{
UART_Init();
}
void BlueTooth_SendData(u8 dat)
{
UART_SendByte(dat);
}
void Blue_DataPros(u8 dat)
{
DisPlayData[0] = smgduan[dat/16];
DisPlayData[1] = smgduan[dat%16];
}
#define USART_MAX_RECV_LEN 1
u8 USART_RX_BUF[USART_MAX_RECV_LEN];
void Uart() interrupt 4
{
if(RI)
{
USART_RX_BUF[0]=SBUF;
RI = 0;//清除接收中断标志位
}
}
//主函数
void main()
{
STA=0;
BlueTooth_Init();//初始化数据
while(1)
{
Blue_DataPros(USART_RX_BUF[0]);
DigDisplay();
switch(USART_RX_BUF[0])//选择汽车移动的方式
{
case BLUETOOTH_FORWARD: Car_ForwardRun();break;
case BLUETOOTH_BACKWARD: Car_BackwardRun();delay_10us(300);Car_StopRun();delay_10us(300);Car_BackwardRun();break;
case BLUETOOTH_LEFT: Car_LeftRun();break;
case BLUETOOTH_RIGHT: Car_RightRun();break;
case BLUETOOTH_STOP: Car_StopRun();break;
}
// BlueTooth_SendData(USART_RX_BUF[0]); //用于串口调试
}
}
4、自动部分:小车循迹,当红外线检测到无黑线时停止,检测到黑线时按照黑线的轨迹移动
C51 COMPILER V9.59.0.0 MAIN 05/22/2021 10:44:29 PAGE 1
C51 COMPILER V9.59.0.0, COMPILATION OF MODULE MAIN
OBJECT MODULE PLACED IN main.OBJ
COMPILER INVOKED BY: C:\Keil_v5\C51\BIN\C51.EXE main.c OPTIMIZE(8,SPEED) BROWSE DEBUG OBJECTEXTEND
line level source
1 //自己设计一条使用黑线带的弯道,将小车放置于黑线带上,开电运行。最新版4.0
2 //小车将按照这条黑线循迹运行。
3 //注意:小车以20%占空比速度运行,如果速度过大,由于检测装置的限制,小车可能会偏离轨道。
4
5 #include "reg52.h"
6
7 //重定义数据类型
8 typedef unsigned char u8;
9 typedef unsigned int u16;
10
11 //定义电机控制管脚
12 sbit MOTOA=P1^0;
13 sbit MOTOB=P1^1; //右侧电机
14 sbit MOTOC=P1^2;
15 sbit MOTOD=P1^3; //左侧电机
16
17 //定义红外感应控制管脚
18 sbit Left_In=P2^3; //左侧红外
19 sbit Right_In=P2^2; //右侧红外
20
21 u16 time_cnt=0; //定时器中断计数次数
22 u16 freq=100; //PWM输出频率100HZ
23 u8 duty_cycle=20; //占空比20%,对的是30-20
24
25 //小车运行方向宏定义
26 #define CAR_FORWARD_RUN 1 //向前
27 #define CAR_BACK_RUN 2 //向后
28 #define CAR_LEFT_RUN 3 //向左
29 #define CAR_RIGHT_RUN 4 //向右
30 u8 car_run_mode=0; //小车运行方向变量
31
32 //延时函数10*us(us)
33 void delay_10us(u16 us)
34 {
35 1 while(us--);
36 1 }
37
38 //ms延时函数ms
39 void delay_ms(u16 ms)
40 {
41 1 u16 i,j;
42 1 for(i=ms;i>0;i--)
43 1 for(j=110;j>0;j--);
44 1 }
45
46 //定时器0初始化函数
47 //定时时间:0.1ms
48 void Time0_Init(void)
49 {
50 1 TMOD|=0x01;
51 1 TH0 = 0XFF;
52 1 TL0 = 0X9C; //定时0.1ms
53 1 TR0 = 1;
54 1 ET0 = 1;
55 1 EA = 1;
C51 COMPILER V9.59.0.0 MAIN 05/22/2021 10:44:29 PAGE 2
56 1 }
57
58 //主函数
59 void main()
60 {
61 1 Time0_Init();
62 1
63 1 while(1)
64 1 {
65 2 }
66 1 }
67
68 //定时器0中断函数
69 void Time0_Isr() interrupt 1
70 {
71 1 TR0 = 0; //关闭定时器0
72 1 TH0 = 0XFF;
73 1 TL0 = 0X9C; //定时0.1ms
74 1 time_cnt++;
75 1 if(time_cnt>=freq)
76 1 time_cnt=0;
77 1 else if(time_cnt<=duty_cycle)
78 1 {
79 2 if((Left_In==0)&&(Right_In==0)) //左右侧红外传感器未检测到黑线--前进
80 2 {
81 3 MOTOA=1;//原始值 1 1 0 0
82 3 MOTOC=1;
83 3 MOTOB=1;
84 3 MOTOD=1;
85 3 }
86 2 else if((Left_In==1)&&(Right_In==0)) //左侧红外传感器检测到黑线--左转
87 2 {
88 3 MOTOA=1;
89 3 MOTOC=0;
90 3 MOTOB=0;
91 3 MOTOD=1;
92 3 }
93 2 else if((Left_In==0)&&(Right_In==1)) //右侧红外传感器检测到黑线--右转
94 2 {
95 3 MOTOA=0;
96 3 MOTOC=1;
97 3 MOTOB=1;
98 3 MOTOD=0;
99 3 }
100 2 else if((Left_In==1)&&(Right_In==1)) //左右侧红外传感器均检测到黑线--停止
101 2 {
102 3 MOTOA=1;
103 3 MOTOC=1;
104 3 MOTOB=0;
105 3 MOTOD=0;
106 3 }
107 2 }
108 1 // else
109 1 // {
110 1 // if((Left_In==0)&&(Right_In==0)) //左右侧红外传感器未检测到黑线--前进
111 1 // {
112 1 // MOTOA=0;
113 1 // MOTOC=0;
114 1 // }
115 1 // else if((Left_In==1)&&(Right_In==0)) //左侧红外传感器检测到黑线--左转
116 1 // {
117 1 // MOTOA=0;
C51 COMPILER V9.59.0.0 MAIN 05/22/2021 10:44:29 PAGE 3
118 1 // }
119 1 // else if((Left_In==0)&&(Right_In==1)) //右侧红外传感器检测到黑线--右转
120 1 // {
121 1 // MOTOC=0;
122 1 // }
123 1 // }
124 1 TR0 = 1; //开启定时器0
125 1 }
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 179 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 6 ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
三、组装小车时遇到的困难与解决方法
1、电池电压问题
根据醒狮提供的电池盒,那边是要我们用4接5号电池串联,每节1.5V,用6V电压来做电源为这个小车各个部分供电,但是这样的话用不了多久,考虑到后面调试小车的过程,所以决定购买18650锂电池2节作为电源,并且购买充电器(这样就有7.4-8.4V的电压,可以用比较久)
2、提供接线问题
醒狮提供的所有线都和杜邦线一样细,然而我们需要6V供电的4个电机,四个电机引出的8条线显然不可以用那种电线,所以我决定给四个电机接粗电线(电线是从家电协会的废旧电器上拆下来的)
3、电池槽电线问题
淘宝买的电池槽正负极引出线太细,作为电源,它的供电安全是系统正常运作的保障,所以在用万用表确定电池槽引出口没有绝缘后,我重新在出口焊接了两条粗电线,再用热熔胶把线在引出口固定好
4、各个模块供电问题
因为有相当部分的模块需要5V供电,所以购买了降压模块,并且要确定模块电压上限(4.5-23V)
5、接口数量问题
1.因为各个模块都需要共地才可以正常使用,要不然大家的电压不一样,就相当于各个模块并没有连在一起。所以需要许多GND端
2.因为供电有6V与5V,电源有7.4-8.4V,所以需要若干5V、降压前7.4-8.4V、降压后5V的端口
解决方法:将电源的正负极引出到排针上面,降压后的电压也引出到排针上面,这样端口不够的问题久解决了
6、开关问题
在一开始,我们进行调试都是靠插电池和拔电池实现的,我觉得十分麻烦,决定加一个开关,六脚锁存开关是在家电协会找到的。测试开关的通断就是在开关按下和没有按下时用万用表测中间公共端和两端引脚的通断情况
最后把开关、电源、降压模块、引出各种电压焊接在洞洞板上面
7、接线问题
由于醒狮提供了开源代码,所以可以根据里面定义的引脚来完成接线。但是在接线时,因为杜邦线容易损坏,所以在拔插10次之后,为了排除杜邦线问题,最好换一根线,并且尽量少用母母头的线,因为母头易损坏松动。
解决方法:如果可以尽量采用双公头的杜邦线,并且在接线一定没有错误后把接口焊死焊接完后一定要用万用表检查是否接通,尽量排除硬件问题
8、接线方法
9、程序烧录问题
- 注意冷启动
- 电脑是否提供了烧录的串口
- 芯片型号是否正确
- 烧录程序是否正确
10、蓝牙模块
11、循迹模块
循迹模块需要反复测试才可以
四、实物
五、其他注意事项
- 每隔一段时间要测电池两端电压是否足够供电
- 接线时要断电
- 焊接电机时一定要小心,不要虚焊
- 合理使用锡焊枪
- 才使用每一根杜邦线时都需要用万用表测量通断
- 蓝牙模块通电时因为占用了RXD与TXD口,程序是无法烧录的
- 接上蓝牙模块无法烧录程序原因
- 解决方法:蓝牙的VCC和GND不要接在51最小系统板上面,接在从锁存开关引出来的那些排针上面的VCC和GND上面,这样哪怕板子通电,只要锁存开关没有按下,蓝牙模块就不会有工作电压,不会影响程序的烧录。如果直接把VCC和GND接在51最小系统板引出的VCC和GND上面,烧录程序时就要把RXD和TXD引脚上面的接线拔掉,很麻烦,还容易损坏杜邦线
请教的人:自动化协会会长,技术部两位部长、17做毕设的师兄、软件组成员、工作室师兄们
原文所在: