智能小车的自动寻迹实验
【实验目的】
熟悉光敏电阻的性质
熟悉ICCAVR 编译环境
进一步熟悉单片机各端口的特性和作用
能够编写程序,利用光敏电阻的性质对小车进行控制
【实验器材】
小车一辆 导线五根 下载线一根
【实验原理】
(一)光敏电阻
当光照射在物体上,物体内部的原子释放出电子并不逸出物体表面,而仍留在内部,使
物体的电阻率1/R 发生变化的效应称为光电导效应。光敏电阻是一种光电导效应半导体器
件。由于光敏电阻没有极性,工作是可加直流偏压或交流电压。当无光照时,光敏电阻的阻
值(暗电阻)很大,电路中电流很小。当它受到一定波长范围的光照射时,其阻值(亮电阻)
急剧减小,电路中电流迅速增加,用电流表可以测量出电流。
本实验所采用的光敏电阻是硫化镉光敏电阻,下图是硫化镉光敏电阻的光照特
光敏电阻的检测
1. 用黑纸片将光敏电阻的透光窗口遮住,此时万用表的指针基本保持不动,阻值接近无穷
大。此值越大说明光敏电阻性能越好。若此值很小或接近为零,说明光敏电阻已烧穿损
坏,不能再继续使用。
2. 用一光源对准光敏电阻的透光窗口,此时万用表的指针应有较大幅度的摆动,阻值明显
减小。此值越小说明光敏电阻性能越好。若此值很大甚至无穷大,表明光敏电阻内部开
路损坏,也不能再继续使用。
3. 将光敏电阻透光窗口对准入射光线,用小黑纸片在光敏电阻的遮光窗上部晃动,使其间
断受光,此时万用表指针应随黑纸片的晃动而左右摆动。如果万用表指针始终停在某一
位置不随纸片晃动而摆动,说明光敏电阻的光敏材料已经损坏。
(二)Atmega8515的端口特性
由于本实验主要用到I/O输入输出的PA端口,因此主要介绍PA端口的特性。端口
A(PA7..PA0)端口A为8位双向I/O口,具有可编程的内部上拉电阻。其输出缓冲器具有对称
的驱动特性,可以输出和吸收大电流。作为输入使用时,若内部上拉电阻使能,端口被外
部电路拉低时将输出电流。在复位过程中,即使系统时钟还未起振,端口A处于高阻状态。
作为通用数字I/O使用时,所有AVRI/O端口都具有真正的读-修改-写功能。这意味着用
SBI或CBI指令改变某些管脚的方向(或者是端口电平、禁止/使能上拉电阻)时不会无意地改
变其他管脚的方向(或者是端口电平、禁止/使能上拉电阻)。输出缓冲器具有对称的驱动能
力,可以输出或吸收大电流,直接驱动LED。所有的端口引脚都具有与电压无关的上拉电阻。
并有保护二极管与VCC和地相连。
每个端口都有三个I/O存储器地址:数据寄存器–PORTx、数据方向寄存器–DDRx和端
口输入引脚–PINx。数据寄存器和数据方向寄存器为读/写寄存器,而端口输入引脚为只读
寄存器。当寄存器SFIOR 的上拉禁止位PUD置位时所有端口的全部引脚的上拉电阻都被禁
止。不论如何配置DDxn,都可以通过读取PINxn寄存器来获得引脚电平。PINxn寄存器的各
个位与其前面的锁存器组成了一个同步器。这样就可以避免在内部时钟状态发生改变的短
时间范围内由于引脚电平变化而造成的信号不稳定。
本实验主要应用PA端口的输入引脚PINA。因此当我们把与光敏电阻的输出电压相连的
五个数据线连接到PA端口时可以通过读取寄存器PINAx来获得光探测装置输出的电平,在
AVR中PA端口的反转电压是2.1V为高电平。即当外部输入电压高于2.1V时,PINAx读取的输
入逻辑电平值为“1” ,当外部输入电压低于2.1V时,PINAx读取的输入逻辑电平值为“0”。
根据PINA寄存器放置的五个数据来判断小车的走向。
(三)本实验实现原理
当电路接通电源时,由小车主板的稳压电源电路稳定输出5 伏电压为小车下部的光探测
电路提供电源使二极管发光,当路面是白色时,二极管发出的光大部分被反射,光敏电阻就
接收到比较强的光照射,阻值变小,流过光敏电阻的电流变大。由于电阻的分压作用,使得
光敏电阻的输出电压较小,约为1.5V 左右。当路面是黑色时,由于黑色对光有吸收作用,
使得二极管发出的光大部分被吸收,只有小部分被反射,光敏电阻接收到的光照就比较小,
阻值变大,流过光敏电阻的电流变小,光敏电阻的输出电压变大,约为2.5V 左右。共有五个
光敏电阻也就是有五个数据输出。这五个信号通过数据线与单片机的PA 口相连,最左边的
电阻连接PA 口的最低位PA0,依次类推,一直连到PA4 口。
【实验步骤】
(1) 连接好电路,把导线,下载线连接好,打开电源
(2) 进入ICCAVR 编译环境,编写并调试程序直至没有错误,编译环境简介请参见
附录一
(3) 下载,烧录进单片机,看实验结果
(4) 反复修改调试程序,逐渐增强其功能
(5) 写好实验报告,实验心得体会
【实验电路】
小车的硬件连接图
小车轮子的驱动详见实验一
【程序示例】
由于在实验中黑线的宽度不同,寻迹中所用到的光敏电阻的部位也不同。下面程序的
例子是黑线的宽度只能覆盖一个光敏电阻时对小车的驱动程序
#include
#include
unsigned char t;
//******************系统自动生成的初始化程序**********************
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00;
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0xFF;
PORTE = 0x00;
DDRE = 0x04;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
MCUCR = 0x00;
EMCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00;
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
//****************小车前进的子程序*********************
void runforth(void)
{
PORTE=0x04;
PORTD=0x70;
}
//*****************小车左转的子程序*********************
void zuozhuan(void)
{
PORTE=0x00;
PORTD=0X70;
}
//****************小车右转的子程序*********************
void youzhuan(void)
{
PORTE=0x04;
PORTD=0x50;
}
//***************小车停止不动的子程序****************
void stop(void)
{
PORTE=0x00;
PORTD=0x00;
}
//****************主程序***************************
void main(void)
{
while(1)//设置一个死循环,不断读取PA口的输入逻辑电平
{
init_devices();//调用初始化函数
t=PINA&0x1f; //屏蔽掉PA口的高三位数据位
if(t==0x00)
{stop();}
else
{
switch(t)
{ case 0x01:zuozhuan();break;
case 0x07:zuozhuan();break;
case 0x02:zuozhuan();break;
case 0x03:zuozhuan();break;
case 0x04:runforth();break;
case 0x0e:runforth();break;
case 0x06:zuozhuan();break;
case 0x08:youzhuan();break;
case 0x10:youzhuan();break;
case 0x0c:youzhuan();break;
case 0x18:youzhuan();break;
case 0x1c:youzhuan();break;
}
}
}
}
评论
查看更多