Atmega128序列槽詳解
Atmega128有兩個序列槽:USART0與USART1
以USART0為例
序列槽的初始化包括:
傳輸模式的選擇:同步還是異步,預設為異步模式,可通過選擇USART控制和狀态寄存器UCSR0C中的UMSEL位來選擇,UMSEL為0,是異步模式.
波特率的設定:通信的雙方都必須有相同的波特率,波特率可以通過設定波特率發生寄存器UBRR0來确定,UBRR0為兩位元組16位的寄存器,可分為 UBRR0H和UBRR0L.同時起作用的還有UCSR0A中的波特率加倍位UX2,當UX2為1時設定的波特率加倍.
傳輸幀格式的設定:預設是8位資料位,一位停止位
發送接受的使能與中斷:通過設定UCSR0B來根據需要選擇接收或發送的使能和是否使用中斷,對使用中斷的USART操作,初始化前要關閉中斷
USART0的控制和狀态寄存器有:UCSR0A,UCSR0B,UCSR0C,波特率寄存器有UBRR0,即UBRR0H和UBRR0L, 資料寄存器為UDR0 1、初始化:
設定波特率前,要關閉USART0的所有使用,包括使能和中斷:
UCSR0B=0B00000000; //關閉USART0
2、設定UCSR0A:
UCSR0A能寫的有Bit0,Bit1,Bit6,其他5位為狀态位.我們一般使用的有Bit1-U2X0,當這一位為1時,波特率的分頻因子從16降到8,能夠有效的将異步通信模式的傳輸速率加倍,但是這一位僅對異步操作有影響,使用同步操作時應将此位清零.
UCSR0A=0B00000000; //不使用倍速發送
3、設定UCSR0C:
Bit6-UMSEL0:USART0的模式選擇,0為異步模式,1為同步模式
Bit5:4-UPM01:0:奇偶校驗模式,00禁止,01,保留,10偶校驗,11,奇校驗
Bit3-USBS0:停止位的選擇,0停止位為1bit,1停止位為2-bits
Bit2:1-UCSZ01:0:字元長度,當UCSZ02為0時,00表示5位,01表示6位,10表示7位,11表示8位.當UCSZ02為1時,11表示9位.(UCSZ02為UCSR0B裡的一位寄存器) eg:
UCSR0C=0B00000110 //異步模式,禁止奇偶校驗,停止位為1位,資料位為8位
4、設定UBRR:
UBRR的設定和這些參數有關:U2X0,CPU頻率,波特率
當U2X0為0時,即異步正常模式下,UBRR的計算公式:
1、U2X=0時的公式計算
UBRR0L= (F_CPU/BAUDRATE/16-1)%256;
UBRR0H= (F_CPU/BAUDRATE/16-1)/256;
2、U2X=1時的公式計算
UBRRL= (F_CPU/BAUDRATE/8-1)%256;
UBRRH= (F_CPU/BAUDRATE/8-1)/256;
//也可根據資料手冊的[波特率設定的例子]查得
//UBRRL = 0x2F; //set baud rate lo
//UBRRH = 0x00; //set baud rate hi
設定一般會有誤差,誤差計算方法為: Error[%]=(BaudRate_ture/BaudRate-1)*100%;
5、然後就是設定UCSR0B:
Bit7-RXCIE0為接收結束中斷使能,Bit6-TXCIE0為發送結束中斷使能,Bit4-RXEN0為接收使能,Bit3-TXEN0為發送使能 .一般情況下,接收使用中斷方式,是以使用接收結束中斷使能.
UCSR0B=0B10011000 //發送接收使能,接收結束使能
還一種寫法是UCSR0B|=(1<< RXEN0)|(1<< TXEN0)|(RXCIE0);
如果更熟練,可以直接以10進制活16進制來設定這些寄存器:
UCSR0B=0x98;或者UCSR0B=152; 序列槽的初始化函數: void uart_init(void) //序列槽0初始化
{
UCSR0B=0x00; //disable while setting baud rate
UCSR0A=0B00000000; //Bit1為1則倍速發送 U2X=0
UCSR0C=0x06; //B00000110 //奇偶模式無,八位資料位,一位停止位
UBRR0L=103; //B00011001波特率:9600 Bps
UBRR0H=0x00; //誤差率:0.156%
UCSR0B=0x98;
} 初始化之後就是對USART0進行讀寫了.
UCSR0A的Bit5-UDRE0标志指出發送緩沖器UDR0是否準備好接收新資料,UDRE0為1說明緩沖器為空,可以接收新資料,UDRE0标志也可用來産生寄存器空中斷.複位後的UDRE0置位,表明發送器已經就緒:
當UDRE0為1時!(UCSR0A&(1<< UDRE0))為0
void putchar(uchar c) //序列槽0發送字元
{
while(!(UCSR0A&(1<< UDRE0))); //while(!(UCSR0A&32)); 表明發送器已經就緒。
UDR0=c;
} 序列槽0發送字元串:
void putstr(uchar *s) //序列槽0發送字元串
{
while(*s)
{
putchar(*s);
s++;
}
} RXC0為UCSR0A裡的Bit7位,為USART0接收結束的狀态位, 接收緩沖器中有未讀出的資料時RXC0置位,否則清零. 序列槽0接收字元:
uchar getchar(void) //序列槽0接收字元
{
while(!(UCSR0A&(1<< RXC0)));
return UDR0;
} 在使用序列槽的程式中一般包含這些檔案:
#include
#include
#include
#include
avr/io.h裡有各種寄存器的定義,avr/signal.h,avr/interrupt.h裡有中斷的定義,avr/delay.h包含延時函數. 例程: 序列槽通信(USART0)
#include<iom128v.h>
#include<macros.h>
#define fosc 8000000 //晶振8MHZ
#define baud 2400 //波特率
void uart0_init(void)
{
UCSR0B = 0x00; //關閉UART00
UCSR0A = 0x00; //不使用倍速發送(異步)
UCSR0C =(1<<UCSZ01)|(1<<UCSZ00); //資料位為8位
UBRR0L=(fosc/16/(baud+1))%256; //異步正常情況下的計算公式
UBRR0H=(fosc/16/(baud+1))/256;
UCSR0B =(1<<RXEN0)|(1<<TXEN0); //接收使能和發送使能
}
void putchar0(unsigned char c)
{
while (!(UCSR0A&(1<<UDRE0)));//表明發送器已經準備就緒
UDR0=c; //将要發送的資料裝入UDR0寄存器
}
unsigned char getchar0(void)
{
while(!(UCSR0A& (1<<RXC0)));//表明已經接收完畢
return UDR0;
}
void puts0(char *s)
{
while (*s)
{
putchar0(*s);
s++;
}
putchar0(0x0a);//回車換行
//putchar0(0x0d);
}
void main(void)
{
unsigned char i; uart0_init();//UART0初始化
puts0("HELLO!"); while(1)
{
puts0("test ok!");
}
} 序列槽通信(USART1)
#include<iom128v.h>
#include<macros.h>
#define fosc 8000000 //晶振8MHZ
#define baud 9600 //波特率
void uart1_init(void) //USART1初始化
{
UCSR1B = 0x00; //關閉USART1
UCSR1A = 0x00; //不适使用倍速發送
UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);//資料位為八位
UBRR1L=(fosc/16/(baud+1))%256;//異步正常模式下,UBRR的計算公式
UBRR1H=(fosc/16/(baud+1))/256;
UCSR1B =(1<<RXEN1)|(1<<TXEN1); //接收使能,傳送使能
}
void putchar1(unsigned char c)//序列槽1發送字元
{
while (!(UCSR1A&(1<<UDRE1)));//表明發送器一準備就緒
UDR1=c;
}
unsigned char getchar1(void) //序列槽1接回收資料
{
while(!(UCSR1A& (1<<RXC1)));
return UDR1; //将接收到的字元傳回
}
void puts1(char *s)
{
while (*s)
{
putchar1(*s);
s++;
}
putchar1(0x0a);//回車換行
putchar1(0x0d);
}
void main(void)
{
unsigned char i; uart1_init();
puts1("HELLO!"); while(1)
{
puts1("test ok!");
}
} 原文:http://blog.chinaunix.net/uid-21658993-id-1819999.html