計(jì)算機(jī)與智能小車的串口通信
【實(shí)驗(yàn)?zāi)康摹?br>學(xué)會使用串口調(diào)試軟件
熟悉ICCAVR 編譯環(huán)境
進(jìn)一步熟悉單片機(jī)的原理及應(yīng)用
能夠編寫程序?qū)崿F(xiàn)計(jì)算機(jī)與單片機(jī)之間的串口通信
【實(shí)驗(yàn)器材】
小車一輛 數(shù)據(jù)線一根 下載線一根
【實(shí)驗(yàn)原理】
所謂“串行通信”就是指外設(shè)和計(jì)算機(jī)間使用一根數(shù)據(jù)信號線(另外需要地線,可能還需
要控制線),數(shù)據(jù)在一根數(shù)據(jù)信號線上一位一位地進(jìn)行傳輸,每一位數(shù)據(jù)都占據(jù)一個(gè)固定的時(shí)
間長度。
計(jì)算機(jī)上的串行接口一般是DB9,它可以分為公口(針型)和母口(孔型),圖1 給出
了公口(針型)和母口(孔型)的圖示,由圖可知母口的2,3 腳剛好與公口相反,2 腳為
發(fā)送TXD。單片機(jī)則是通過UART(即Universal Asynchronous Receiver Transmitter 通
用異步收發(fā)器)來收發(fā)數(shù)據(jù)的, 它允許在串行鏈路上進(jìn)行全雙工的通信。UART 主要有由數(shù)
據(jù)總線接口、控制邏輯、波特率發(fā)生器、發(fā)送部分和接收部分等組成。 包括微處理器接口,
發(fā)送緩沖器(TXB)、發(fā)送移位寄存器(TSR)、幀產(chǎn)生、奇偶校驗(yàn)、并轉(zhuǎn)串、數(shù)據(jù)接收緩沖
器(RXB)、接收移位寄存器(RSR)、幀產(chǎn)生、奇偶校驗(yàn)、串轉(zhuǎn)并。 圖2 是UART 的典型應(yīng)
用,本實(shí)驗(yàn)所用的芯片是Atmega8515,有興趣的同學(xué)可以查閱一下它的datasheet。
【實(shí)驗(yàn)步驟】
(1) 連接好電路,把數(shù)據(jù)線,下載線連接好,打開電源
(2) 進(jìn)入ICCAVR 編譯環(huán)境,調(diào)試程序直至沒有錯(cuò)誤,編譯環(huán)境簡介請參見附錄一
(3) 下載,燒錄進(jìn)單片機(jī),在串口調(diào)試軟件上觀看實(shí)驗(yàn)結(jié)果,關(guān)于串口調(diào)試軟件參
見附錄二
(4) 反復(fù)修改調(diào)試程序,逐漸增強(qiáng)其功能
(5) 寫好實(shí)驗(yàn)報(bào)告,實(shí)驗(yàn)心得體會
【程序示例】
(1)功能:計(jì)算機(jī)發(fā)送一個(gè)字節(jié)到單片機(jī),單片機(jī)把接收到的字節(jié)的ASCII 碼加一后
再發(fā)送給計(jì)算機(jī)。程序運(yùn)行結(jié)果如圖2-7 所示,輸入“abcdefg”時(shí),輸出為“bcdefgh”.
1.用查詢方法實(shí)現(xiàn)
#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(); //全局中斷關(guān)
port_init();
uart0_init();
MCUCR = 0x00;
EMCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00;
SEI(); //使能中斷 //初始化完成
}
//*************************發(fā)送子程序
******************************
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.用中斷方式實(shí)現(xiàn)
初始化程序同上;
#pragma interrupt_handler uart0_rx_isr:10
void uart0_rx_isr(void)
{ pos=UDR;
UDR=pos+1; }
//uart 接收了一個(gè)字符產(chǎn)生中斷,并將接收到的字符
的ASCII 碼加一
//把加一以后的字符發(fā)送出去
#pragma interrupt_handler uart0_tx_isr:12
void uart0_tx_isr(void)
{
}
void main(void)
{
init_devices();
while (1)
;
}
(2)用串口通信實(shí)現(xiàn)人機(jī)交互菜單的程序
功能:實(shí)現(xiàn)了一個(gè)人機(jī)交互菜單,可以通過簡單的鍵盤輸入來控制小車動作
當(dāng)輸入“A”并發(fā)送,屏幕上會顯示:“You have input a A”
當(dāng)輸入“B”并發(fā)送,小車上的LED 會顯示“1111”
當(dāng)輸入“C”并發(fā)送,小車會向前走一段然后停下
當(dāng)輸入“D”并發(fā)送,小車會后退一段然后停下
#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;
}
//------------------------延時(shí)子程序--------------------------
void delay(unsigned long pos)
{ while(pos>0)
pos--;
}
//--------------------前進(jìn)子程序--------------------------------
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();
}
//***********************發(fā)送子程序***********************
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;}
}
}
評論
查看更多