实验指导书 智能系统概论.docx
《实验指导书 智能系统概论.docx》由会员分享,可在线阅读,更多相关《实验指导书 智能系统概论.docx(46页珍藏版)》请在冰豆网上搜索。
实验指导书智能系统概论
实验一单灯闪烁控制
1、实验目的
1)熟悉C51系列单片机的引脚定义和分布;
2)掌握使用单片机端口控制LED闪烁的方法
3)掌握时序图的概念,while循环的引入和延时函数的使用;
2、实验设备
1)宝贝车1台
2)C51系列单片机1台
3)导线若干
4)LED灯2个
5)电阻2个
3、实验内容
1)了解C51单片机的输入/输出接口的主要作用
输入/输出(I/O)接口是单片机和外部设备之间信息交换和控制的桥梁。
它主要有以下几个作用:
1.实现和不同外部设备的速度匹配
不同的外设工作速度差别很大,而且一般来讲外设的响应速度远远小于CPU的运算速度。
所以接口电路就必须适应CPU和外设的速度上的这个矛盾。
2.改变数据传送的方式
I/O数据有并行和串行两种方式。
3.按照需要为CPU提供更多资源,如RAM和ROM
4.改变信号的性质和电平
CPU和外设之间的信号有几类:
数据型(程序代码和计算结果等)、状态型(反映外设的工作状态,如启动、忙、空闲等)和控制型(控制外设的工作状态,如外设的开和关、电机的转动和停止、速度的控制等)。
2)C51单片机接口
51系列单片机有4个8位的并行I/O口:
P0、P1、P2和P3。
既可作为普通的I/O口、也可用作特殊功能。
3)单灯闪烁控制电路的搭建与实现
4、实验步骤
单灯闪烁控制
LED电路搭建
●确保LED的短针脚(阴极、负极)通过电阻与P1_0相连
●确保LED的长针脚(阳极、正极)插入“VCC”接口
程序
例程:
HighLowLed.c
建立项目HighLowLed,输入并保存以下程序,查看运行结果。
(过程参考第一章)
#include
#include
intmain(void)
{
uart_Init();//初始化串口
printf("TheLEDconnectedtoP1_0isblinking!
\n");
while
(1)
{
P1_0=1;//P1_0输出高电平
delay_nms(500);//延时500ms
P1_0=0;//P1_0输出低电平
delay_nms(500);//延时500ms
}
}
单灯闪烁控制
头文件:
BoeBot.h
该头文件中定义了两个延时函数:
(1)delay_nms(unsignedintn);毫秒级延时
(2)delay_nus(unsignedintn);微秒级延时
unsignedint:
无符号整型
单灯闪烁控制
while语句
while语句是一种循环控制语句。
在实际问题中,常常需要进行大量的重复处理,循环结构可以使我们只写很少的语
句,而让计算机反复执行,从而完成大量类同的计算。
while语句是当型循环控制语句,一般形式为:
While(表达式)语句;
语句部分称为循环体,当需要执行多条语句时,应使用复合语句(使用“{}”)。
while语句的特点是:
先判断表达式值,后执行,若条件不成立,则跳出循环,执
行下面语句。
其它循环控制语句
do...while语句
for语句
单灯闪烁控制
时序图——反应高、低电压信号与时间的关系图
5、思考题
1)举例说明闪烁电路的实际应用?
2)分析实验过程中LED烧毁的原因?
实验二机器人伺服电机控制
1、实验目的
1)掌握机器人伺服电机的控制方法
2)能够独立完成伺服电机控制电路的搭建
3)掌握串口通信的使用方法
2、实验设备
1)宝贝车1台
2)C51系列单片机1台
3)导线若干
4)电机2个
5)电阻2个
3、实验内容介绍
1)伺服电机的安装
伺服电机实物图
伺服电机与教学底板的连线原理图和实际接线示意图
2)机器人伺服电机控制信号
零点标定信号——使电机停止转动
while
(1)
{
P1_0=1;//P1_0输出高电平
delay_nus(1500);//延时1.5ms
P1_0=0;//P1_0输出低电平
delay_nus(20000);//延时20ms
}
机器人伺服电机控制信号
测试伺服电机
while
(1)
{
P1_0=1;
delay_nus(1300);
P1_0=0;
delay_nus(20000);
}
1.3ms的控制脉冲序列使电机顺时针全速旋转
while
(1)
{
P1_0=1;
delay_nus(1700);
P1_0=0;
delay_nus(20000);
}
1.7ms的连续脉冲序列使电机逆时针全速旋转
实现计数并控制循环次数
4、基本语句的学习
for循环控制语句
在实际的机器人控制过程中,经常要求机器人运动一段给定的距离或者
一段固定的时间。
for语句是循环控制结构中使用最广泛的一种循环控制语句,特别适合已
知循环次数的情况。
它的一般形式为:
for(表达式1;表达式2;表达式3)语句
计数并控制循环次数
表达式1:
给控制变量赋初值;
表达式2:
循环控制条件;
表达式3:
给控制变量增量或减量;
语句:
循环体,当有多条语句时,必须使用复合语句(“{}”)。
for(表达式1;表达式2;表达式3)语句
语句执行过程:
首先计算表达式1,然后计算表达式2,若表达式2为真,则执行循环体;
否则,退出for循环,执行for循环后面的语句。
如果执行了循环体,则循环体每执行一次,都计算表达式3,然后重新计
算表达式2,依此循环,直至表达式2的值为假,退出循环。
计数并控制循环次数
使用for循环语句,控制电机运行:
for(counter=1;counter<=130;i++)
{
P1_1=1;delay_nus(1700);P1_1=0;
P1_0=1;delay_nus(1300);P1_0=0;
delay_nms(20);
}
自增和自减——“++”和“--”
运算符“++”是操作数加1,而“--”是操作数减1,即:
“x=x+1;”等同于“x++”;
“x=x-1;”等同于“x--;”
计数并控制循环次数
电机运行时间:
for(counter=1;counter<=130;i++)
{
P1_1=1;delay_nus(1700);P1_1=0;
P1_0=1;delay_nus(1300);P1_0=0;
delay_nms(20);
}
执行一次循环体,电机运行时间:
1.7ms(左电机,与P1_1相连)
+1.3ms(右电机,与P1_0相连)
+20ms(延时时间)
=23ms
总共运行时间:
130X0.023s=3s
计数并控制循环次数
例程:
BothServosThreeSeconds.c
for(counter=1;counter<=130;counter++)
{
P1_1=1;delay_nus(1700);P1_1=0;
P1_0=1;delay_nus(1300);P1_0=0;
delay_nms(20);
}
用以下两个for循环语句代替HighLowLed.c中的while循环语句。
for(counter=1;counter<=130;counter++)
{
P1_1=1;delay_nus(1300);P1_1=0;
P1_0=1;delay_nus(1700);P1_0=0;
delay_nms(20);
}
执行程序,观察机器人是否向一个方向运行3秒钟后又反射运行3秒钟。
用计算机控制机器人运动
在第一章中你已经知道C51单片机可以通过串口向计算机调试终端发送信息,
该任务将使用串口由你从计算机向单片机发送数据来控制机器人的运动。
scanf函数
scanf函数称为格式输入函数,即按用户指定的格式从键盘上把数据输入到指
定的变量之中。
它的一般形式为:
scanf(“格式控制字符串”,地址表列);
其中,格式控制字符串的作用与printf函数相同,但不能显示非格式字符串,
也就是不能显示提示字符串,即要求以%开关。
地址表列中给出各变量的地址。
地址是由地址运算符“&”后跟变量名组成的。
如&PulseNumber表示变量PulseNumber的地址,这个地址是编译系统在内存中给变
量分配的地址,用户不需要关心具体地址是多少。
例如:
scanf(“%d”,&PulseNumber);将把用户输入的整数赋给变量PulseNumber
用计算机控制机器人运动
5、思考问题
1)如何使用for循环语句控制机器人的运动;
2)如何通过串口输入数据控制机器人的运动;
实验三机器人巡航控制
1、实验目的
1)实现对单片机编程使机器人做一些基本的巡航动作:
向前,向后,左转,右转和原地旋转
2)独立编写程序使机器人由突然启动或停止变为逐步加速或减速运动
3)独立编写一些执行基本巡航动作的函数,每一个函数都能够被多次调用
2、实验设备
1)宝贝车1台
2)C51系列单片机1台
3)导线若干
4)电机2个
3、实验内容
1)机器人方向定义
机器人及其前进方向的定义
如果按照左图前进方向的定义,机器人向前走时:
从机器人的左边看,它向前走时轮子是逆时针旋转的;从右边看另一个轮子则是顺时针旋转的。
4、实验程序
基本巡航动作
机器人向前巡航:
RobotForwardThreeSeconds.c
基本巡航动作
其它巡航动作
将delay_nus函数的参数n以不同的值组合就可以使机器人以其它的方式运行
向后行走
P1_1=1;delay_nus(1300);P1_1=0;//左轮顺时针
P1_0=1;delay_nus(1700);P1_0=0;//右轮逆时针
delay_nms(20);
原地左转
P1_1=1;delay_nus(1300);P1_1=0;//左轮顺时针
P1_0=1;delay_nus(1300);P1_0=0;//右轮顺时针
delay_nms(20);
原地右转
P1_1=1;delay_nus(1700);P1_1=0;//左轮逆时针
P1_0=1;delay_nus(1700);P1_0=0;//右轮逆时针
delay_nms(20);
基本巡航动作
其它巡航动作——以某一轮子为支点旋转
从前面向左旋转
P1_1=1;delay_nus(1500);P1_1=0;//左轮静止
P1_0=1;delay_nus(1300);P1_0=0;//右轮顺时针
delay_nms(20);
从前面向右旋转
P1_1=1;delay_nus(1700);P1_1=0;//左轮逆时针
P1_0=1;delay_nus(1500);P1_0=0;//右轮静止
delay_nms(20);
从后面向左旋转
P1_1=1;delay_nus(1500);P1_1=0;//左轮静止
P1_0=1;delay_nus(1700);P1_0=0;//右轮逆时针
delay_nms(20);
从后面向右旋转
P1_1=1;delay_nus(1300);P1_1=0;//左轮顺时针
P1_0=1;delay_nus(1500);P1_0=0;//右轮静止
delay_nms(20);
匀加速/减速运动
现象:
机器人每次启动和停止时,动作太快,几乎倾倒。
原因:
运动学——物体从零加速到最大运动速度时,时间越短,所需加速度就
越大;牛顿定律——加速度越大,物体所爱的惯性力就越大。
解决方法:
采用匀加速/减速运动,让机器人速度渐渐增加/减小。
作用:
机器人运动更平稳,电机使用寿命更长。
for(pulseCount=10;pulseCount<=200;pulseCount=pulseCount+10)
{
P1_1=1;delay_nus(1500+pulseCount);P1_1=0;
P1_0=1;delay_nus(1500-pulseCount);P1_0=0;
delay_nms(20);
}
for(pulseCount=200;pulseCount>=0;pulseCount=pulseCount-10)
{
P1_1=1;delay_nus(1500+pulseCount);P1_1=0;
P1_0=1;delay_nus(1500-pulseCount);P1_0=0;
delay_nms(20);
}
用函数调用简化运动程序
机器人向前、向左、向右、向后运动——ForwardLeftRightBackward.c
#include
#include
intmain(void)
{
intcounter;
printf("ProgramRunning!
\n");
for(counter=1;counter<=65;counter++)//前进
{
P1_1=1;delay_nus(1700);P1_1=0;
P1_0=1;delay_nus(1300);P1_0=0;
delay_nms(20);
}
for(counter=1;counter<=26;counter++)//左转
{
P1_1=1;delay_nus(1300);P1_1=0;
P1_0=1;delay_nus(1300);P1_0=0;
delay_nms(20);
}
for(counter=1;counter<=26;counter++)//右转
{
P1_1=1;delay_nus(1700);P1_1=0;
P1_0=1;delay_nus(1700);P1_0=0;
delay_nms(20);
}
for(counter=1;counter<=65;counter++)//后退
{
P1_1=1;delay_nus(1300);P1_1=0;
P1_0=1;delay_nus(1700);P1_0=0;
delay_nms(20);
}
}
用函数调用简化运动程序
voidForward(void)
{
inti;
for(i=1;i<=65;i++)
{
P1_1=1;delay_nus(1700);P1_1=0;
P1_0=1;delay_nus(1300);P1_0=0;
delay_nms(20);
}
}
函数voidForward(void)
voidForward(intPulseCount,intVelocity)
//0{
inti;
for(i=1;i<=PulseCount;i++)
{
P1_1=1;delay_nus(1500+Velocity);P1_1=0;
P1_0=1;delay_nus(1500-Velocity);P1_0=0;
delay_nms(20);
}
}
用函数调用简化运动程序
函数voidLeft(intPulseCount,intVelocity)
voidLeft(intPulseCount,intVelocity)
{
inti;
for(i=1;i<=PulseCount;i++)
{
P1_1=1;delay_nus(1500-Velocity);P1_1=0;
P1_0=1;delay_nus(1500-Velocity);P1_0=0;
delay_nms(20);
}
}
函数voidRight(intPulseCount,intVelocity)
voidRight(intPulseCount,intVelocity)
{
inti;
for(i=1;i<=PulseCount;i++)
{
P1_1=1;delay_nus(1500+Velocity);P1_1=0;
P1_0=1;delay_nus(1500+Velocity);P1_0=0;
delay_nms(20);
}
}
用函数调用简化运动程序
函数voidBackward(intPulseCount,intVelocity)
voidBackward(intPulseCount,intVelocity)
{
inti;
for(i=1;i<=PulseCount;i++)
{
P1_1=1;delay_nus(1500-Velocity);P1_1=0;
P1_0=1;delay_nus(1500+Velocity);P1_0=0;
delay_nms(20);
}
}
主函数intmain(void)
intmain(void)
{
uart_Init();
printf("ProgramRunning!
\n");
Forward(65,200);
Left(26,200);
Right(26,200);
Backward(65,200);
}
用函数调用简化运动程序
从函数定义角度:
标准函数
用户自定义函数
从有无返回值角度:
有返回值函数
无返回值函数
从主调函数与被调函数数据传送角度:
无参函数
有参函数
intmain(void)
voidForward(intPulseCount,intVelocity)
printf(“…”)
用函数调用简化运动程序
只用一个函数简化程序
由于机器人由两个轮子驱动,实际上两个轮子的不同
速度组合控制着机器人的运动速度和方向,因此可以直接
用两个车轮的速度作为参数,就可以将所有的机器人运动
用一个函数来实现。
Forward(65,200);
Left(26,200);
Right(26,200);
Backward(65,200);
voidMove(intcounter,intPC1_pulseWide,intPC0_pulseWide)
{
inti;
for(i=1;i<=counter;i++)
{
P1_1=1;delay_nus(PC1_pulseWide);P1_1=0;
P1_0=1;delay_nus(PC0_pulseWide);P1_0=0;
delay_nms(20);
}
}
用函数调用简化运动程序
例程:
MovementsWithOneFuntion.c
#include
#include
voidMove(intcounter,intPC1_pulseWide,int
PC0_pulseWide)
{
inti;
for(i=1;i<=counter;i++)
{
P1_1=1;delay_nus(PC1_pulseWide);P1_1=0;
P1_0=1;delay_nus(PC0_pulseWide);P1_0=0;
delay_nms(20);
}
}
intmain(void)
{
uart_Init();
printf("ProgramRunning!
\n");
Move(65,1700,1300);
Move(26,1300,1300);
Move(26,1700,1700);
Move(65,1300,1700);
}
5、思考题
说明机器人在运动过程中的自转是如何实现的?
实验四机器人IRLED/探测电路
1、实验目的
1)掌握如何使用IRLED/探测电路检测距离(定时/计数器的使用)
2)学习如何使用定时器
2、实验设备
1)宝贝车1台
2)C51系列单片机1台
3)导线若干
4)电机2个
5)传感器2对
3、实验内容
用IRLED/探测电路检测距离
用红外传感器探测道路
探测灵敏度与频率关系
4、实验程序说明
定时/计数器
以前所用延时方法:
1.for()函数
2._nop_()函数
更精确延时:
定时/计数器
AT89S52的定时/计数器可以分为定时器模式和计数器模式。
这两种模式没有本质上的区别,均使用二进制的加一计数:
当计数器的值计满
回零时能自动产生中断的请求,以此来实现定时或者计数功能。
它们的不同之处在于定时器使用单片机的时钟来计数,而计数器使用的是外部
信号。
定时/计数器
定时/计数器的控制,两个特殊功能寄存器——TCON和TMOD
TCON控制寄存器
定时器控制寄存器,可进行位操作,低四位与定时器无关。
定时/计数器
TMOD模式寄存器
定时器模式寄存器,不能进行位操作,只能通过字节传送指令来设定各个状态。
定时/计数器
TMOD模式寄存器
每个定时/计数器都有一个16位的寄存器Tn(n=0或1)来控制计数长度,由
高8位THn和低8位TLn组成并用来设初值。
共四种定时模式。
定时/计数器
13位定时器模式(模式0)
定时器高字节(THx)与低字节(TLx)的低5位共同构成1个13位定时器。
低字节高3位未使用。
计数值随时钟脉冲增加,当计数值从FFH溢出回到00H时,TFx被置1。
16位定时器模式(模式1)
除工作在16位以外,与模式0没有什么不同。
定时/计数器
8位自动重载模式(模式2)
低字节(TLx)作为1个8位定时器工作,高字节用于保存重载数。
当计数值超过FFH回零时,不仅TFx被置1,同时THx载入TLx,定时器重新开始工作,如此循环。
定时/计数器
分立定时器模式(模式3)
定时器1在该模式下不工作。
定时/计数器
定时器初值计算
定时/计数值是在设置初值的基本上加法计数。
设程序要运行的数值为CC,初值为TC,计数最大值为2n,则:
TC=2n-CC
例如:
定时1ms要运行的数值CC=1ms/1us=1000,在