打印
[AVR单片机]

看到hotpower的“利用UDRIE实现"手动触发"”帖子,俺也凑个热

[复制链接]
2181|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zsmbj|  楼主 | 2007-9-9 22:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
很久就在用这个功能,一直很好用。现在整理了一下,把这个软件帖出来,希望对大家有用处。
可以用于232或485通讯。通过预编译选择。

以下uart.h:

#ifndef    _uart_h
#define    _uart_h

#include "avr/io.h"

#define        TURE                    1
#define        FALSE                     0

#define        RS485MODE                TURE        //TURE:rs485   FALSE:rs232

#define        BAUDRATE                51            //baud rate
#define        UART_buffer_size        32            //must 1,2,4,8,16,32,64,128 or 256 bytes

#if    (RS485MODE == TURE)
    #define TX_EN                    PIND2
    #define TX_DDR                    DDRD
    #define TX_PORT                    PORTD
    #define    RS_485_port_init()        TX_DDR |= (1<<TX_EN)
    #define RS_485_send()             TX_PORT |= (1<<TX_EN)        //RS485 enable
    #define RS_485_receive()         TX_PORT &= ~(1<<TX_EN)        //RS485 disable
#endif

//--------------------------------------------------------------------------------------
//UART Buffer Defines
//--------------------------------------------------------------------------------------
#define UART_RX_BUFFER_SIZE     UART_buffer_size
#define UART_RX_BUFFER_MASK     ( UART_RX_BUFFER_SIZE - 1 )
#define UART_TX_BUFFER_SIZE     UART_buffer_size
#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
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
#error TX buffer size is not a power of 2
#endif

//--------------------------------------------------------------------------------------
//unsigned char ReceiveByte( void )
//Parameters:  none
//Function:  Read a byte from uart
//Notice:    None
//Created:  2005-3-1 , By zsmbj
//--------------------------------------------------------------------------------------
unsigned char ReceiveByte( void );

//--------------------------------------------------------------------------------------
//void TransmitByte( unsigned char data )
//Parameters:  
//Function:  write a byte to uart
//Notice:    None
//Created:  2005-3-1 , By zsmbj
//--------------------------------------------------------------------------------------
void TransmitByte( unsigned char data );

//--------------------------------------------------------------------------------------
//unsigned char DataInReceiveBuffer( void )
//Parameters: 
//Function:  if have a uart data then return 1
//Notice:    None
//Created:  2005-3-1 , By zsmbj
//--------------------------------------------------------------------------------------
unsigned char DataInReceiveBuffer( void );

#endif


以下uart.c:

#include "uart.h"
#include "avr/interrupt.h"

/**********************************************************************/
/* These are the global variables                                     */
/**********************************************************************/
//UART related buffers and variables
            unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
volatile    unsigned char UART_RxHead;
volatile    unsigned char UART_RxTail;

            unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
volatile    unsigned char UART_TxHead;
volatile    unsigned char UART_TxTail;

/**********************************************************************/
/* UART subroutine. */
/**********************************************************************/

/* initialize UART */
void init_UART( void )
{
    UBRRL = BAUDRATE;                                        //set the baud rate
    UBRRH = 0;
    //enable UART receiver and transmitter, and    receive interrupt

    UCSRA = 0;
    UCSRB = ( (1<<RXCIE) | (1<<RXEN) | (1<<TXEN) );
    UCSRC = ( (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0) );
    
    UART_RxTail = 0;                                        //flush receive buffer
    UART_RxHead = 0;
    UART_TxTail = 0;
    UART_TxHead = 0;

    #if    (RS485MODE == TURE)
    RS_485_port_init();
    RS_485_receive();
    #endif
}

//--------------------------------------------------------------------------------------
//SIGNAL (SIG_UART_RECV)
//Parameters:  none
//Function:  uart rxd interrupt
//Notice:    None
//Created:  2005-3-1 , By zsmbj
//--------------------------------------------------------------------------------------
SIGNAL (SIG_UART_RECV)
{
    unsigned char data;
    unsigned char tmphead;

    data = UDR;                                             //read the received data
    tmphead = ( UART_RxHead + 1 ) & UART_RX_BUFFER_MASK;    //calculate buffer index
    UART_RxHead = tmphead;                                     //store new index
    if ( tmphead == UART_RxTail )                            //ERROR! Receive buffer overflow
    {

    }
    UART_RxBuf[tmphead] = data;                             //store received data in buffer
    
}

//--------------------------------------------------------------------------------------
//SIGNAL (SIG_UART_DATA)
//Parameters:  none
//Function:  uart udre interrupt
//Notice:    None
//Created:  2005-3-1 , By zsmbj
//--------------------------------------------------------------------------------------
SIGNAL (SIG_UART_DATA)
{
    unsigned char tmptail;

    if ( UART_TxHead != UART_TxTail )                        //check if all data is transmitted
    {
        tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;//calculate buffer index
        UART_TxTail = tmptail;                                 //store new index
        UDR = UART_TxBuf[tmptail];                             //start transmition
    }
    else
    {
        UCSRB &= ~(1<<UDRIE);                                 //disable UDRE interrupt

        #if    (RS485MODE == TURE)
        UCSRB |= (1<<TXCIE);                                 //enable TXCIE interrupt
        #endif
    }
}

//--------------------------------------------------------------------------------------
//SIGNAL (SIG_UART_TRANS)
//Parameters:  none
//Function:  uart txd interrupt
//Notice:    None
//Created:  2005-3-1 , By zsmbj
//--------------------------------------------------------------------------------------
#if    (RS485MODE == TURE)
SIGNAL (SIG_UART_TRANS)
{
    RS_485_receive();                                        //close rs485 send data.
    UCSRB &= ~(1<<TXCIE);                                     //disable TXCIE interrupt
}
#endif
//--------------------------------------------------------------------------------------
//unsigned char ReceiveByte( void )
//Parameters:  none
//Function:  Read a byte from uart
//Notice:    None
//Created:  2005-3-1 , By zsmbj
//--------------------------------------------------------------------------------------
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[tmptail];                             //return data
    }

//--------------------------------------------------------------------------------------
//void TransmitByte( unsigned char data )
//Parameters:  
//Function:  write a byte to uart
//Notice:    None
//Created:  2005-3-1 , By zsmbj
//--------------------------------------------------------------------------------------
void TransmitByte( unsigned char data )
{
    unsigned char tmphead;

    tmphead = ( UART_TxHead + 1 ) & UART_TX_BUFFER_MASK;     //calculate buffer index
    while ( tmphead == UART_TxTail )                        //wait for free space in buffer
    ;
    UART_TxBuf[tmphead] = data;                             //store data in buffer
    UART_TxHead = tmphead;                                     //store new index

    #if    (RS485MODE == TURE)
    RS_485_send();                                            //open rs485 send data mode if send data ok then close
    #endif
    
    UCSRB |= (1<<UDRIE);                                     //enable UDRE interrupt
}

//--------------------------------------------------------------------------------------
//unsigned char DataInReceiveBuffer( void )
//Parameters: 
//Function:  if have a uart data then return 1
//Notice:    None
//Created:  2005-3-1 , By zsmbj
//--------------------------------------------------------------------------------------
unsigned char DataInReceiveBuffer( void )
{
    return ( UART_RxHead != UART_RxTail );                     //return 0 (FALSE) if the receive buffer is empty 
}

//end of program


以下main.c:测试用

#include "uart.h"

int main(void)
{
    init_UART();
    
    //if received a uart byte then send it
    if( DataInReceiveBuffer() )
    {
        TransmitByte( ReceiveByte() );
    }
}


以上程序在winavr20060421下编译通过,单片机atmega8515。

相关帖子

沙发
dcp| | 2007-9-10 00:20 | 只看该作者

着凉

使用特权

评论回复
板凳
dcp| | 2009-11-13 14:10 | 只看该作者
while ( tmphead == UART_TxTail )                        //wait for free space in buffer
    ;
这一句好象不太好吧

使用特权

评论回复
地板
wangwo| | 2009-11-13 22:29 | 只看该作者
支持楼主

使用特权

评论回复
5
laslison| | 2009-11-15 22:00 | 只看该作者
不错:)

使用特权

评论回复
6
lovelyegle| | 2009-11-16 23:06 | 只看该作者
收下了,谢啦

使用特权

评论回复
7
hotpower| | 2010-7-27 19:32 | 只看该作者
行使些职权~~~

使用特权

评论回复
8
xuyiyi| | 2010-7-28 12:09 | 只看该作者
哈!
HOT大叔滥用职权, 挖墓~~~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

227

帖子

1

粉丝