alisha 发表于 2006-5-9 15:48:25

ICCAVR库函数USART中断例子

//ICC-AVR application builder : 09-05-2006 8:59:17

// Target : M16

// Crystal: 4.0000Mhz

/*

RX程序流程:

没有新字符输入,头指针和尾指针相同

有新字符输入,中断处理,头指针加一,取UDR到RX-BUFER

之后RECEIVE程序中对尾指针加一,准备接收下一个字符,同时返回当前字符

TX程序流程:

TRANS接收到RX的输入字符,头指针加一,将数据存入发送缓冲区,打开UDRIE寄存器空中断,进入中断程序。

尾指针加一,之后发送字符,直到头尾指针相同,即发送完毕,关闭UDRIE中断寄存器。



*/



#include <iom16v.h>

#include <macros.h>

/* UART Buffer Defines */

#define UART_RX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */

#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 )

#define UART_TX_BUFFER_SIZE 128 /* 1,2,4,8,16,32,64,128 or 256 bytes */

#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1 )



#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )

#error RX buffer size is not a power of 2

#endif



/* Static Variables */

static unsigned char UART_RxBuf;

static volatile unsigned char UART_RxHead;

static volatile unsigned char UART_RxTail;

static unsigned char UART_TxBuf;

static volatile unsigned char UART_TxHead;

static volatile unsigned char UART_TxTail;

static volatile unsigned char CHECK=0;

void port_init(void)

{

PORTA = 0x00;

DDRA= 0x00;

PORTB = 0x00;

DDRB= 0x00;

PORTC = 0x00; //m103 output only

DDRC= 0x00;

PORTD = 0x00;

DDRD= 0x00;

}



//UART0 initialize

// desired baud rate: 9600

// actual: baud rate:2404 (0.2%)

// char size: 5 bits

// parity: Disabled

void uart0_init(void)

{

unsigned char x;

x=0;

UART_RxTail = x;

UART_RxHead = x;

UART_TxTail = x;

UART_TxHead = x;

UCSRB = 0x00; //disable while setting baud rate

UCSRA = 0x00;

UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

UBRRL = 0x19; //set baud rate lo

UBRRH = 0x00; //set baud rate hi

UCSRB = (1<<RXCIE)|(1<<TXEN)|(1<<RXEN);//|(1<<TXCIE)

}

unsigned char DataInReceiveBuffer( void )

        {

        return ( UART_TxHead != UART_TxTail );

                /* return 0 (FALSE) if the TX complete */

        }

#pragma interrupt_handler uart0_rx_isr:12

void uart0_rx_isr(void)

{

//uart has received a character in UDR

        unsigned char data;

        unsigned char tmphead;

        data = UDR; /* read the received data */

        /* calculate buffer index */

        tmphead = ( UART_RxHead + 1 ) & UART_RX_BUFFER_MASK;

        UART_RxHead = tmphead; /* store new index */

        if ( tmphead == UART_RxTail )

                {

                /* ERROR! Receive buffer overflow */

                /*仿真中没有出现这种情况*/

                }

        UART_RxBuf = data; /* store received data in buffer */

}



#pragma interrupt_handler uart0_tx_isr:14

void uart0_tx_isr(void)

{

//character has been transmitted

        unsigned char tmptail;

    CHECK++;

        /* check if all data is transmitted */

        if ( DataInReceiveBuffer( ))//UART_TxHead != UART_TxTail

                {

                /* calculate buffer index */

                tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;

                UART_TxTail = tmptail; /* store new index */

                UDR = UART_TxBuf; /* start transmition */

                }

        else

                {

                UCSRB &= ~(1<<UDRIE); /* disable UDRE interrupt */

                }

       

}



//call this routine to initialize all peripherals

void init_devices(void)

{

//stop errant interrupts until set up

CLI(); //disable all interrupts

port_init();

uart0_init();



MCUCR = 0x00;

GICR= 0x00;

TIMSK = 0x00; //timer interrupt sources

SEI(); //re-enable interrupts

//all peripherals are now initialized

}

/* Read and write functions */

unsigned char ReceiveByte( void )

        {

        unsigned char tmptail;



        while ( UART_RxHead == UART_RxTail ) /* wait for incomming data */

                ;

        tmptail = ( UART_RxTail + 1 ) & UART_RX_BUFFER_MASK;/* calculate buffer index */

        UART_RxTail = tmptail; /* store new index */

        return UART_RxBuf; /* return data */

        }



void TransmitByte( unsigned char data )

        {

        unsigned char tmphead;

        /* calculate buffer index */

        tmphead = ( UART_TxHead + 1 ) & UART_TX_BUFFER_MASK;

                /* wait for free space in buffer */



        while ( tmphead == UART_TxTail )

                ;

        UART_TxBuf = data; /* store data in buffer */

        UART_TxHead = tmphead; /* store new index */

        UCSRB |= (1<<UDRIE); /* enable UDRE interrupt */

        }







void main(void)

{

init_devices();

while ( 1 ) /* forever */

                {

                TransmitByte( ReceiveByte() ); /* echo the received character */

                }

}

alisha 发表于 2006-5-10 10:20:45

点击此处下载armok01116888.rar

oldkey 发表于 2006-5-27 17:31:48

请问:不知楼主是在什么版本下仿真的,我用6.7sp3不成功。谢谢!

alisha 发表于 2006-5-28 14:57:08

6.7sp3

SKYdai 发表于 2006-5-28 23:06:22

不错,谢谢!!

oldkey 发表于 2006-5-29 19:17:58

alisha 大侠:

你好!

能把AVR.DLL这个文件传上来吗?

我怀疑我那个有问题

谢谢

alisha 发表于 2006-5-30 14:09:11

你从新安装一下就应该可以吧!

oldkey 发表于 2006-5-30 15:54:50

谢谢alisha !

我改用6.9了

oleon 发表于 2006-9-11 11:43:04

怎么不行呢

好像没有任何显示

konger2012 发表于 2014-9-25 17:03:46

刚刚看了一下,程序这里是否存在问题啊这里是开 UDRE 中断,UCSRB |= (1<<UDRIE); /* enable UDRE interrupt */ ,而实际中断地址是14应该不是UDRE中断,而是TX结束中断。 不知道楼主有没有注意这个问题?还是我理解的有问题?

konger2012 发表于 2014-9-25 17:22:49

不知道有没有人回复啊
页: [1]
查看完整版本: ICCAVR库函数USART中断例子