計算機與智能小車的串口通信
【實驗目的】
學會使用串口調試軟件
熟悉ICCAVR 編譯環境
進一步熟悉單片機的原理及應用
能夠編寫程序實現計算機與單片機之間的串口通信
【實驗器材】
小車一輛 數據線一根 下載線一根
【實驗原理】
所謂“串行通信”就是指外設和計算機間使用一根數據信號線(另外需要地線,可能還需
要控制線),數據在一根數據信號線上一位一位地進行傳輸,每一位數據都占據一個固定的時
間長度。
計算機上的串行接口一般是DB9,它可以分為公口(針型)和母口(孔型),圖1 給出
了公口(針型)和母口(孔型)的圖示,由圖可知母口的2,3 腳剛好與公口相反,2 腳為
發送TXD。單片機則是通過UART(即Universal Asynchronous Receiver Transmitter 通
用異步收發器)來收發數據的, 它允許在串行鏈路上進行全雙工的通信。UART 主要有由數
據總線接口、控制邏輯、波特率發生器、發送部分和接收部分等組成。 包括微處理器接口,
發送緩沖器(TXB)、發送移位寄存器(TSR)、幀產生、奇偶校驗、并轉串、數據接收緩沖
器(RXB)、接收移位寄存器(RSR)、幀產生、奇偶校驗、串轉并。 圖2 是UART 的典型應
用,本實驗所用的芯片是Atmega8515,有興趣的同學可以查閱一下它的datasheet。
【實驗步驟】
(1) 連接好電路,把數據線,下載線連接好,打開電源
(2) 進入ICCAVR 編譯環境,調試程序直至沒有錯誤,編譯環境簡介請參見附錄一
(3) 下載,燒錄進單片機,在串口調試軟件上觀看實驗結果,關于串口調試軟件參
見附錄二
(4) 反復修改調試程序,逐漸增強其功能
(5) 寫好實驗報告,實驗心得體會
【程序示例】
(1)功能:計算機發送一個字節到單片機,單片機把接收到的字節的ASCII 碼加一后
再發送給計算機。程序運行結果如圖2-7 所示,輸入“abcdefg”時,輸出為“bcdefgh”.
1.用查詢方法實現
#include
#include
void port_init(void)
{ PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00;
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x02;
PORTE = 0x00;
DDRE = 0x00;
} //UART0 初始化// 波特率:
9600
void uart0_init(void)
{
UCSRB = 0x00;
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x19;
UBRRH = 0x00;
UCSRB = 0xD8;
}
#pragma interrupt_handler uart0_rx_isr:10
void uart0_rx_isr(void)
{ //uart has received a
character in UDR
}
#pragma interrupt_handler uart0_tx_isr:12
void uart0_tx_isr(void)
{ //character has been
transmitted
} //call this routine to initialize all
peripherals
void init_devices(void)
{
CLI(); //全局中斷關
port_init();
uart0_init();
MCUCR = 0x00;
EMCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00;
SEI(); //使能中斷 //初始化完成
}
//*************************發送子程序
******************************
void Transmit(unsigned char da)
{
while ( !( UCSRA & (1<
}
//**************************接收子程序
******************************
unsigned recvchar(void)
{
while ( !( UCSRA & 0x80) );
return UDR;
}
void main(void)
{
init_devices();
while (1)
Transmit(recvchar());
}
2.用中斷方式實現
初始化程序同上;
#pragma interrupt_handler uart0_rx_isr:10
void uart0_rx_isr(void)
{ pos=UDR;
UDR=pos+1; }
//uart 接收了一個字符產生中斷,并將接收到的字符
的ASCII 碼加一
//把加一以后的字符發送出去
#pragma interrupt_handler uart0_tx_isr:12
void uart0_tx_isr(void)
{
}
void main(void)
{
init_devices();
while (1)
;
}
(2)用串口通信實現人機交互菜單的程序
功能:實現了一個人機交互菜單,可以通過簡單的鍵盤輸入來控制小車動作
當輸入“A”并發送,屏幕上會顯示:“You have input a A”
當輸入“B”并發送,小車上的LED 會顯示“1111”
當輸入“C”并發送,小車會向前走一段然后停下
當輸入“D”并發送,小車會后退一段然后停下
#include
#include
#include
unsigned int a,i,j,l,time;
unsigned char pos;
unsigned char str1[]="Please input A,B,C or D : \n \n If you input
A,it will tell you you have input a 'A' ; \n \n If you input B,The
led will display '1111' ; \n \n If you input C,it will run forword ;
\n \n If you input D,it will run backword .\n \n";
unsigned char str2[]="You have input a A\n";
void port_init(void)
{ PORTA = 0x00;
DDRA = 0xFF;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00;
DDRC = 0xFF;
PORTD = 0x00;
DDRD = 0xFF;
PORTE = 0x00;
DDRE = 0xFF;
}
void uart0_init(void)
{ UCSRB = 0x00;
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x19;
UBRRH = 0x00;
UCSRB = 0xD8;
}
//***********************剎車子程序*************************
void black(void)
{ PORTE=0x00;
PORTD=0x00;
}
//------------------------延時子程序--------------------------
void delay(unsigned long pos)
{ while(pos>0)
pos--;
}
//--------------------前進子程序--------------------------------
void run_forword(void)
{ while(time<100)
{PORTE=0x04;
PORTD=0x70;
delay(6000);
time++;
}
time=0;
black();
}
//-----------------------后退子程序-----------------------------
void run_backword(void)
{ while(time<100)
{ PORTE=0x04;
PORTD=0x20;
delay(6000);
time++;
}
time=0;
black();
}
//***********************發送子程序***********************
void Transmit(unsigned char da)
{ while ( !( UCSRA & (1<
}
//**************************顯示字符串子程序********************
void outputstr(unsigned char str[])
{ l=strlen(str);
i=0;
while(i<=l)
{Transmit(str[i]);delay(800);i++;}
}
//********************選擇子程序***********************
void options(void)
{ switch ( pos )
{case 'A' : { outputstr(str2); break; }
case 'B' : { PORTA=0x9F;PORTC=0x00; break; }
case 'C' : {run_forword() ; break; }
case 'D' : {run_backword(); break; }
default:outputstr(str1);
}
}
#pragma interrupt_handler uart0_rx_isr:10
void uart0_rx_isr(void)
{
pos=UDR; //把接收到的字符送給pos
options();
}
#pragma interrupt_handler uart0_tx_isr:12
void uart0_tx_isr(void)
{
}
void init_devices(void)
{
CLI();
port_init();
uart0_init();
MCUCR = 0x00;
EMCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00;
SEI();
}
unsigned recvchar(void)
{
while ( !( UCSRA & 0x80) );
return UDR;
}
void main(void)
{
init_devices(); //初始化
a=0;i=0;
black(); //先讓小車靜止
PORTC=0x0F; //接通LED 的位線
while (1)
{
while(a= =0)
{outputstr(str1); //顯示提示字符串
a=1;}
}
}
評論
查看更多