智能小車的自動尋跡實驗
【實驗目的】
熟悉光敏電阻的性質
熟悉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;
}
}
}
}
評論
查看更多