西南交大电脑鼠课程设计.docx
《西南交大电脑鼠课程设计.docx》由会员分享,可在线阅读,更多相关《西南交大电脑鼠课程设计.docx(25页珍藏版)》请在冰豆网上搜索。
西南交大电脑鼠课程设计
电子技术课程设计报告
学院:
专业:
年级:
姓名:
学号:
指导老师:
第一章课程设计任务和总体设计
1.1课程设计任务
该课程设计以两人组队的形式,制作寻线型电脑鼠。
要求能够在8×8的迷宫中搜索路径并计算出最短路径。
其中迷宫由25mm宽的黑线组成。
电脑鼠第一次进入迷宫和返回迷宫时,可以循着黑线走到终点并记录迷宫信息,第二次进入迷宫时,根据第一次所记录的迷宫信息选择最短路径冲刺到终点。
1.2总体设计思路和步骤
寻线型电脑鼠不同于以前的走迷宫,是利用红外传感器进行路线探测并选择前进方向的小型智能机器人。
其设计步骤包括:
系统设计、利用AltiumDesigner软件绘制原理图和PCB图,电脑鼠硬件焊接组装、软件代码书写调试和总体调试。
硬件部分主要由传感器,单片机,电机驱动组成。
传感器采用红外传感器,由发射管和接收管组成,可探测黑线迷宫。
单片机采用IAP15W413AS芯片,用于编写和实现程序。
电机驱动由单片机产生的PWM以及L9110芯片进行驱动。
软件部分主要由产生PWM函数,搜寻路径法则,记录信息,测速盘组成。
此课程设计中电脑鼠按照左手法则进行路线搜索,根据测速盘的计数得到迷宫坐标并储存。
第一次排除迷宫中的死路,第二次便可沿迷宫中最短路径走出迷宫。
第二章硬件设计
2.1硬件设计步骤
硬件设计步骤如图1所示。
设计原理图、生成PCB板之后进行手动布线,再根据PCB板将原件、轮子、轴承、电机、齿轮等器件进行组装,调整传感器角度使之能够达到良好的接受效果。
最后进行电路测试,测试方式在软件设计部分说明。
2.2主控模块(单片机)
包括单片机(图2)和电脑下载部分(图3)。
单片机采用了STC15W4K32S4芯片,其原理图为:
图2
红外传感器
电机驱动
单片机
PCB板制作
原理图绘制
生成PCB图并布线
调整角度
元器件焊接
电机等组装
图1
管脚图:
图3
图4
2.3传感器模块
传感器模块运用了5对发光二极管(白)+红外光敏三极管(黑)的组合(如图7),成一条直线置于电脑鼠前端用于探测赛道。
其中左前与右前的探测器用于纠正电脑鼠直线行走时由于2个电机转动不一致导致的轨道偏离。
左、前和右方的三个探测器用于探测距离电脑鼠特定距离内的左右和前方有无线路。
用于提供红外信号的30kHz多的信号可以由STC15W4K32S4单片机的时钟输出口输出,占空比固定为50%。
当发射的光线集中于白色地区时,光线会被反射,黑色的接收管就会将其吸收;反之,发射光线集中的地方是黑色的时候,光线会被吸收而没有反射。
单个的传感器模块如图5
图5
发光二极管电路图如图6.
图6
实物图见图7.
图7
2.4电机驱动模块
电脑鼠的前进、拐弯和旋转等动作必须依靠两个电机的转动来控制。
具体为:
直行:
两个电机同方向转动;
转弯:
两个电机一个转一个不转或者一个正转一个反转。
要使电机转动,需要一定的电压,以电压控制电机的运转。
而为了获得一个较为合适的电压值,往往需要调节电阻。
通过不断重复地开、关操作,实现我们需要的“脉冲宽度调制”(简称pwm调制)。
当pwm信号与电机相连时,电机的旋转速度就可以根据我们的程序设定来工作。
电机正、反转以及刹车的控制是通过两个L9110芯片来控制的。
图8为L9110的应用电路图。
图8
图9为其原理图。
图9
除L9110之外,该模块还使用了74HC00芯片参与pwm控制。
原理图如图10
图10
2.5测速模块
电脑鼠设计使用直流电机,一方面通过对电机的转速加以运算可获得电脑鼠所在方位,记忆当前迷宫情况;一方面在编程时,了解电机转速对电脑鼠行走速度可以进行更好地控制,使其能够在尽量短的时间内遍历迷宫且走到终点。
采用红外发射二极管和红外光敏三极管组成一对对射管实现对两个电机转速进行测量,需要分别在两个电机的一端添加码盘。
其实物图如图11.
图11
2.6电源
电脑鼠的电源为5号铁锂电池和7号铁锂电池各一节,分别为单片机和电机供电,提供电压约为3.2V左右。
电源原理图如图12所示。
图12
至此,电脑鼠的硬件设计基本完成,完整的原理图、PCB图见附录。
焊接PCB板成品图如图13.
图13
第三章软件设计
3.1程序流程图(图14)
结束
图14
第四章最终结果
课程设计结果:
电脑鼠可完成寻线并到达终点,有时候也能顺利返回起点。
在焊接过程中,因为有光立方比赛的经验,焊接工作比较顺利,除了中途有一次不小心将一个芯片的两个引脚焊在了一起,然后我们及时的用仪器解决了这一问题。
而软件部分,虽然用的原代码是同学间分享流传的,但是也是通过自己的调试,修改才完成的。
另外,在学长的指导下,也对右手算法程序中左转优先级不高这一缺点进行了完善。
第五章总结及体会
这次课程设计让我受益匪浅,无论从知识上还是其他的各个方面。
上课的时候的学习从来没有见过真正的单片机,只是从理论的角度去理解枯燥乏味。
但在实习中见过甚至使用了单片机及其系统,能够理论联系实际的学习,开阔了眼界,提高了单片机知识的理解和水平。
在这次课程设计中又让我体会到了合作与团结的力量,当遇到不会或是设计不出来的地方,我们就会在QQ群里讨论或者是同学之间相互帮助。
团结就是力量,无论在现在的学习中还是在以后的工作中,团结都是至关重要的,有了团结会有更多的理念、更多的思维、更多的情感。
单片机是很重要的一门课程,老师曾说过,如果学好一门单片机,就凭这个技术这门手艺找一个好工作也不成问题。
尽管我们在课堂学到的内容很有限,但在以后的学习中单片机还需要好好的深入研究和学习,学好了单片机也就多了一项生存的本钱。
最后感谢老师、学长们对我们的精心指导和帮助,感谢同学们对我的帮助。
附录1:
原理图
附录2:
PCB图
附录3:
程序代码
#include"stdio.h"
#include"action.h"//电机驱动头文件
#include"bmp_pixel.h"
#include"NOKIA_5110.h"
#include"configuration.h"
u16gz1=0;
voidStop_On_Going()
{
Wheel_Control(LEFT,1,255);//1表示正向转,data越大,转速越小
Wheel_Control(RIGHT,1,255);
}
voidTurn_Right()//右转的具体实现
{
do
{
Wheel_Control(LEFT,1,32);
Wheel_Control(RIGHT,0,45);
}while(P1&0xf8==0xd8||P1&0xf8==0x98||P1&0xf8==0xc8);
}
voidGo_straight()//直走的具体实现
{
Wheel_Control(LEFT,1,42);
Wheel_Control(RIGHT,1,55);
}
voidTurn_Left()
{
do
{
Wheel_Control(LEFT,1,52);
Wheel_Control(RIGHT,1,65);
}while(Left_Detector==1);//在左转之前,先走一段距离,直到最左边的灯走出黑线(为实现直走>左转)
if(Middle_Detector==0)
{
Go_straight();
}
else
{
do
{
Wheel_Control(LEFT,0,32);//左齿轮反转,右齿轮正转
Wheel_Control(RIGHT,1,45);
}while(P1&0xf8==0xd8||P1&0xf8==0x98||P1&0xf8==0xc8);
}
}
voidTurn_back()//调头的具体实现xxx.
{
do
{
Wheel_Control(LEFT,0,42);
Wheel_Control(RIGHT,1,55);
}while(P1&0xf8==0xd8);
}
voidLeft_Adjust()//左偏->向右微调的具体实现
{do{
Wheel_Control(LEFT,0,72);//左轮子转速快一点就可以解决左偏问题
Wheel_Control(RIGHT,1,55);
}while(P1&0xf8==0xd8||P1&0xf8==0xc8||P1&0xf8==0xe8||P1&0xf8==0xf0);
}
voidRight_Adjust()//右偏向->左微调的具体实现
{do
{
Wheel_Control(LEFT,1,62);
Wheel_Control(RIGHT,0,75);
}while(P1&0xf8==0xd8||P1&0xf8==0x98||P1&0xf8==0xb8||P1&0xf8==0x78);
}
voidFind_gz();
voidmain()
{
u16mode=0;
u8sensor=0;
//功能模块初始化
//GPIO_config();//STC15W4K32S4PWM复用口由高阻初始化为双向口
EXTI_config();//外部中断测速
Timer_config();//定时器
PCA_config();//PWM
UART_config();//串口
ADC_config();//AD电压检测
//液晶屏初始化
LCD_init();
LCD_clear();
LCD_draw_bmp_pixel(15,0,BMP,48,56);
delay_ms(250);
delay_ms(250);
delay_ms(250);
delay_ms(250);
LCD_clear();
LCD_write_english_string(2,0,"WelcomeTo");
LCD_write_english_string(2,1,"SWJTU");
LCD_write_english_string(2,2,"DNSVER2.1");
LCD_write_english_string(2,3,"Nokia5110LCD");
LCD_write_chinese_string(1,4,12,6,0,2);
//waitforthestartkeydown
//while(Start_Key);
//延时启动(start按键按下,等待n秒后启动)
delay_ms(250);
delay_ms(250);
delay_ms(250);
delay_ms(250);
delay_ms(250);
//delay_ms(250);
//delay_ms(250);
//delay_ms(250);
//delay_ms(250);
//delay_ms(250);
//delay_ms(250);
//
LCD_clear();
//开总中断
SET_EA();
/*addyourprogramhere!
!
!
.....*/
while
(1)
{
P1=0xff;
sensor=P1&0xf8;
if(gz1==0)
{
switch(sensor)
{
case0x10:
///00010000
case0x08:
////00001000
case0x18:
mode=1;break;////00011000左转//算法体现,先从左遍历图
case0xa0:
//10100000
case0xd0:
//11010000
case0x88:
//10001000
case0xd8:
mode=2;break;////11011000直走
case0x80:
///10000000
case0x00:
////00000000
case0xc0:
mode=3;break;////11000000右转
case0xf8:
mode=4;break;////11111000掉头
case0xe0:
//01001000
case0x78:
//01111000
case0x38:
//00111000
case0xb8:
///10111000
case0x98:
mode=10;break;////10011000头右偏,后续调整
case0x90:
youzhuanyichangchuli
case0xe8:
///11101000
case0xc8:
//11001000
case0xf0:
mode=11;break;////11110000头偏左,后续调整
default:
mode=5;break;////其他情况,执行右转
}
switch(mode)
{
case1:
Turn_Left();break;
case2:
Go_straight();break;
case3:
Turn_Right();break;
case4:
Turn_back();break;
case5:
Find_gz();break;
case10:
Left_Adjust();break;
case11:
Right_Adjust();break;
default:
Go_straight();break;
}
}
}
}
voidFind_gz()
{
gz1=1;
do{
if(Left_Detector&Left_middle_Detector==0)
{
Wheel_Control(LEFT,0,72);
Wheel_Control(RIGHT,1,85);
}
elseif(Right_middle_Detector&Right_Detector==0)
{
Wheel_Control(LEFT,1,62);
Wheel_Control(RIGHT,0,75);
}
}while(P1&0xf8==0xd8);
gz1=0;
}
/*************功能说明**************
本文件为电机控制程序
******************************************/
#include"Action.h"
/************************************************************************************************************
*functionname:
voidWheel_Control(bitside,u8data_CCAPnH)
*param:
side=LEFTorRIGHTdir=WHEEL_FRONTorWHEEL_BACKdata_CCAPnH为输入CCAPnH的8bit数据
*returnvalue:
none
*description:
controltheleftorrightwheel'srunning
************************************************************************************************************/
voidWheel_Control(bitside,bitdir,u8data_CCAPnH)
{
if(dir==WHEEL_FRONT)//选择的轮子前进
{
if(side==RIGHT)
{
Motor_Right_Control=1;
PWMn_Update(PCA0,data_CCAPnH);
}
elseif(side==LEFT)
{
Motor_Left_Control=1;
PWMn_Update(PCA1,data_CCAPnH);
}
}
elseif(dir==WHEEL_BACK)
{
if(side==RIGHT)
{
Motor_Right_Control=0;
PWMn_Update(PCA0,data_CCAPnH);
}
elseif(side==LEFT)
{
Motor_Left_Control=0;
PWMn_Update(PCA1,data_CCAPnH);
}
}
}
/************************************************************************************************************
*functionname:
voidTurnRight()
*param:
none
*returnvalue:
none
*description:
控制电脑鼠向右转
************************************************************************************************************/
#ifIN_PLACE
voidTurnRight()
{
u8flg=1;
TX1_write2buff(0xDD);
left_count=right_count=0;
Wheel_Control(LEFT,WHEEL_FRONT,SPEED_INIT_LEFT);
Wheel_Control(RIGHT,WHEEL_FRONT,SPEED_INIT_RIGHT);
while(flg==1)
{
if(right_count==60|left_count==60)
{
Wheel_Control(LEFT,WHEEL_FRONT,SPEED_INIT_RIGHT);
Wheel_Control(RIGHT,WHEEL_BACK,SPEED_INIT_LEFT);
}
if(left_count==125|right_count==125)
{
Wheel_Control(LEFT,WHEEL_FRONT,0Xff);//左轮停止
Wheel_Control(RIGHT,WHEEL_BACK,0Xff);
left_count=0;
right_count=0;
flg=0;
}
}
}
#else
voidTurnRight()
{
u8flg=1;
left_count=right_count=0;
Wheel_Control(LEFT,WHEEL_FRONT,SPEED_INIT_LEFT);
Wheel_Control(RIGHT,WHEEL_FRONT,0XFF);
while(flg==1)
{
if(left_count==90|right_count==90)
{
Wheel_Control(LEFT,WHEEL_FRONT,0Xff);//左轮停止
left_count=0;
right_count=0;
flg=0;
}
}
}
#endif
/************************************************************************************************************
*functionname:
voidTurnRight()
*param:
none
*returnvalue:
none
*description:
控制电脑鼠向左转
************************************************************************************************************/
#ifIN_PLACE
voidTurnLeft()
{
u8flg=1;
TX1_write2buff(0xEE);
left_count=right_count=0;
Wheel_Control(RIGHT,WHEEL_FRONT,SPEED_INIT_RIGHT);
Wheel_Control(LEFT,WHEEL_FRONT,SPEED_INIT_LEFT);
while(flg==1)
{
if(right_count==60|left_count==60)
{
Wheel_Control(RIGHT,WHEEL_FRONT,SPEED_INIT_RIGHT);
Wheel_Control(LEFT,WHEEL_BACK,SPEED_INIT_LEFT);
}
if(right_count==125|left_count==125)
{
Wheel_Control(RIGHT,WHEEL_FRONT,0Xff);//右轮停止
Wheel_Control(LEFT,WHEEL_BACK,0Xff);
left_count=0;
right_count=0;
flg=0;
}
}
}
#else
voidTurnLeft()
{
u8flg=1;
left_count=right_count=0;
Wheel_Control(RIGHT,WHEEL_FRONT,SPEED_INIT_RIGHT);
Wheel_Control(LEFT,WHEE