用于ATmega128的軟件UART范例程序
發(fā)布時間:2008/8/18 0:00:00 訪問次數(shù):1963
一般教科書上提供的uart收發(fā)的程序往往是一段采用輪循(polling)方式完成收發(fā)的簡單代碼。但對于高速的avr來講,采用這種方式大大降低了 muc的效率。在使用avr時,應(yīng)根據(jù)芯片本身的特點(diǎn)(片內(nèi)大容量數(shù)據(jù)存儲器ram,更適合采用高級語言編寫系統(tǒng)程序),編寫高效可靠的uart收發(fā)接口(低層)程序。下面是一個典型的atmega128的軟件usart的接口程序。
#include <mega128.h>
#define rxb8 1
#define txb8 0
#define upe 2
#define ovr 3
#define fe 4
#define udre 5
#define rxc 7
#define framing_error (1<<fe)
#define parity_error (1<<upe)
#define data_overrun (1<<ovr)
#define data_register_empty (1<<udre)
#define rx_complete (1<<rxc)
// usart0 receiver buffer
#define rx_buffer_size0 8
char rx_buffer0[rx_buffer_size0];
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
// this flag is set on usart0 receiver buffer overflow
bit rx_buffer_overflow0;
// usart0 receiver interrupt service routine
#pragma savereg-
interrupt [usart0_rxc] void uart0_rx_isr(void)
{
char status,data;
#asm
push r26
push r27
push r30
push r31
inr26,sreg
push r26
#endasm
status=ucsr0a;
data=udr0;
if ((status & (framing_error | parity_error | data_overrun))==0)
{
rx_buffer0[rx_wr_index0]=data;
if (++rx_wr_index0 == rx_buffer_size0) rx_wr_index0=0;
if (++rx_counter0 == rx_buffer_size0)
{
rx_counter0=0;
rx_buffer_overflow0=1;
};
};
#asm
popr26
outsreg,r26
popr31
popr30
popr27
popr26
#endasm
}
#pragma savereg+
#ifndef _debug_terminal_io_
// get a character from the usart0 receiver buffer
#define _alternate_getchar_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter0==0);
data=rx_buffer0[rx_rd_index0];
if (++rx_rd_index0 == rx_buffer_size0) rx_rd_index0=0;
#asm("cli")
--rx_counter0;
#asm("sei")
return data;
}
#pragma used-
#endif
// usart0 transmitter buffer
#define tx_buffer_size0 8
char tx_buffer0[tx_buffer_size0];
unsigned char tx_wr_index0,tx_rd_index0,tx_counter0;
// usart0 transmitter interrupt service routine
#pragma savereg-
interrupt [usart0_txc] void uart0_tx_isr(void)
{
#asm
push r26
push r27
push r30
push r31
inr26,sreg
push r26
#edasm
if (tx_counter0)
{
--tx_counter0;
udr0=tx_buffer0[tx_rd_index0];
if (++tx_rd_index0 == tx_buffer_size0) tx_rd_index0=0;
};
#asm
popr26
outsreg,r26
popr31
popr30
popr27
popr26
#endasm
}
#pragma savereg+
#ifndef _debug_terminal_io_
// write a character to the usart0 transmitter buffer
#define _alternate_putchar_
#pragma used+
void putchar(char c)
{
while (tx_counter0 == tx_buffer_size0);
#asm("cli")
if (tx_counter0 || ((ucsr0a & data_register_empty)==0))
{
tx_buffer0[tx_wr_index0]=c;
if (++tx_wr_index0 == tx_buffer_size0) tx_wr_index0=0;
++tx_counter0;
}
else
udr0=c;
#asm("sei")
}
#pragma used-
#endif
// standard input/output functions
#include <stdio.h>
// declare your global variables here
void main(void)
{
// usart0 initialization
// communication parameters: 8 data, 1 stop, no parity
// usart0 receiver: on
// usart0 transmitter: on
// usart0 mode: asynchronous
// usart0 baud rate: 9600
ucsr0a=0x00;
ucsr0b=0xd8;
ucsr0c=0x06;
ubrr0h=0x00;
ubrr0l=0x67;
// global enable interrupts
#asm("sei")
while (1)
{
// place your code here
};
}
這段由cvavr程序生成器產(chǎn)生的uart接口代碼是一個非常好的、高效可靠,并且值得認(rèn)真學(xué)習(xí)和體會的。其特點(diǎn)如下:
l. 它采用兩個8字節(jié)的接收和發(fā)送緩沖器來提高mcu的效率,如當(dāng)主程序調(diào)用putchar()發(fā)送數(shù)據(jù)時,如果uart口不空閑,就將數(shù)據(jù)放入發(fā)送緩沖器中,mcu不必等待,可以繼續(xù)執(zhí)行其它的工作。而uart的硬件發(fā)送完一個數(shù)據(jù)后,產(chǎn)生中斷,由中斷服務(wù)程序負(fù)責(zé)將發(fā)送緩沖器中數(shù)據(jù)依次送
一般教科書上提供的uart收發(fā)的程序往往是一段采用輪循(polling)方式完成收發(fā)的簡單代碼。但對于高速的avr來講,采用這種方式大大降低了 muc的效率。在使用avr時,應(yīng)根據(jù)芯片本身的特點(diǎn)(片內(nèi)大容量數(shù)據(jù)存儲器ram,更適合采用高級語言編寫系統(tǒng)程序),編寫高效可靠的uart收發(fā)接口(低層)程序。下面是一個典型的atmega128的軟件usart的接口程序。
#include <mega128.h>
#define rxb8 1
#define txb8 0
#define upe 2
#define ovr 3
#define fe 4
#define udre 5
#define rxc 7
#define framing_error (1<<fe)
#define parity_error (1<<upe)
#define data_overrun (1<<ovr)
#define data_register_empty (1<<udre)
#define rx_complete (1<<rxc)
// usart0 receiver buffer
#define rx_buffer_size0 8
char rx_buffer0[rx_buffer_size0];
unsigned char rx_wr_index0,rx_rd_index0,rx_counter0;
// this flag is set on usart0 receiver buffer overflow
bit rx_buffer_overflow0;
// usart0 receiver interrupt service routine
#pragma savereg-
interrupt [usart0_rxc] void uart0_rx_isr(void)
{
char status,data;
#asm
push r26
push r27
push r30
push r31
inr26,sreg
push r26
#endasm
status=ucsr0a;
data=udr0;
if ((status & (framing_error | parity_error | data_overrun))==0)
{
rx_buffer0[rx_wr_index0]=data;
if (++rx_wr_index0 == rx_buffer_size0) rx_wr_index0=0;
if (++rx_counter0 == rx_buffer_size0)
{
rx_counter0=0;
rx_buffer_overflow0=1;
};
};
#asm
popr26
outsreg,r26
popr31
popr30
popr27
popr26
#endasm
}
#pragma savereg+
#ifndef _debug_terminal_io_
// get a character from the usart0 receiver buffer
#define _alternate_getchar_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter0==0);
data=rx_buffer0[rx_rd_index0];
if (++rx_rd_index0 == rx_buffer_size0) rx_rd_index0=0;
#asm("cli")
--rx_counter0;
#asm("sei")
return data;
}
#pragma used-
#endif
// usart0 transmitter buffer
#define tx_buffer_size0 8
char tx_buffer0[tx_buffer_size0];
unsigned char tx_wr_index0,tx_rd_index0,tx_counter0;
// usart0 transmitter interrupt service routine
#pragma savereg-
interrupt [usart0_txc] void uart0_tx_isr(void)
{
#asm
push r26
push r27
push r30
push r31
inr26,sreg
push r26
#edasm
if (tx_counter0)
{
--tx_counter0;
udr0=tx_buffer0[tx_rd_index0];
if (++tx_rd_index0 == tx_buffer_size0) tx_rd_index0=0;
};
#asm
popr26
outsreg,r26
popr31
popr30
popr27
popr26
#endasm
}
#pragma savereg+
#ifndef _debug_terminal_io_
// write a character to the usart0 transmitter buffer
#define _alternate_putchar_
#pragma used+
void putchar(char c)
{
while (tx_counter0 == tx_buffer_size0);
#asm("cli")
if (tx_counter0 || ((ucsr0a & data_register_empty)==0))
{
tx_buffer0[tx_wr_index0]=c;
if (++tx_wr_index0 == tx_buffer_size0) tx_wr_index0=0;
++tx_counter0;
}
else
udr0=c;
#asm("sei")
}
#pragma used-
#endif
// standard input/output functions
#include <stdio.h>
// declare your global variables here
void main(void)
{
// usart0 initialization
// communication parameters: 8 data, 1 stop, no parity
// usart0 receiver: on
// usart0 transmitter: on
// usart0 mode: asynchronous
// usart0 baud rate: 9600
ucsr0a=0x00;
ucsr0b=0xd8;
ucsr0c=0x06;
ubrr0h=0x00;
ubrr0l=0x67;
// global enable interrupts
#asm("sei")
while (1)
{
// place your code here
};
}
這段由cvavr程序生成器產(chǎn)生的uart接口代碼是一個非常好的、高效可靠,并且值得認(rèn)真學(xué)習(xí)和體會的。其特點(diǎn)如下:
l. 它采用兩個8字節(jié)的接收和發(fā)送緩沖器來提高mcu的效率,如當(dāng)主程序調(diào)用putchar()發(fā)送數(shù)據(jù)時,如果uart口不空閑,就將數(shù)據(jù)放入發(fā)送緩沖器中,mcu不必等待,可以繼續(xù)執(zhí)行其它的工作。而uart的硬件發(fā)送完一個數(shù)據(jù)后,產(chǎn)生中斷,由中斷服務(wù)程序負(fù)責(zé)將發(fā)送緩沖器中數(shù)據(jù)依次送
熱門點(diǎn)擊
- 用于ATmega128的軟件UART范例程序
- 單片機(jī)驅(qū)動蜂鳴器原理與設(shè)計
- 51單片機(jī)8*8點(diǎn)陣LED顯示原理及程序
- PIC單片機(jī)CRC校驗(yàn)程序
- 80C51原始IP核內(nèi)部RAM的擴(kuò)展方案
- 單片機(jī)的圖形化編程方法探討
- 用AT89S51單片機(jī)來制作的手動計數(shù)器
- Proteus在單片機(jī)系統(tǒng)設(shè)計中的應(yīng)用
- TEA5767收音機(jī)模塊的C51控制程序
- pic單片機(jī)的模擬I2C通信
推薦技術(shù)資料
- 硬盤式MP3播放器終級改
- 一次偶然的機(jī)會我結(jié)識了NE0 2511,那是一個遠(yuǎn)方的... [詳細(xì)]
- 100A全集成電源模塊R
- Teseo-VIC6A GNSS車用精準(zhǔn)定位
- 高效先進(jìn)封裝工藝
- 模數(shù)轉(zhuǎn)換器 (Analog-to-Digit
- 集成模數(shù)轉(zhuǎn)換器(ADC)
- 128 通道20 位電流數(shù)字轉(zhuǎn)換器̴
- 多媒體協(xié)處理器SM501在嵌入式系統(tǒng)中的應(yīng)用
- 基于IEEE802.11b的EPA溫度變送器
- QUICCEngine新引擎推動IP網(wǎng)絡(luò)革新
- SoC面世八年后的產(chǎn)業(yè)機(jī)遇
- MPC8xx系列處理器的嵌入式系統(tǒng)電源設(shè)計
- dsPIC及其在交流變頻調(diào)速中的應(yīng)用研究