📄 uart.c
字号:
uart.c
Go to the documentation of this file.00001
00002 //*****************************************************************
00003 //
00004 // File Name : 'uart.c'
00005 // Title : UART driver with buffer support
00006 // Author : Pascal Stang - Copyright (C) 2000-2002
00007 // Created : 11/22/2000
00008 // Revised : 11/01/2001
00009 // Version : 1.3
00010 // Target MCU : ATMEL AVR Series
00011 // Editor Tabs : 3
00012 //
00013 // This code is distributed under the GNU Public License
00014 // which can be found at http://www.gnu.org/licenses/gpl.txt
00015 //
00016 //*****************************************************************
00017
00018 #include <io.h>
00019 #include <interrupt.h>
00020 #include <sig-avr.h>
00021
00022 #include "buffer.h"
00023 #include "uart.h"
00024
00025 // UART global variables
00026 // flag variables
00027 volatile u08 uartReadyTx;
00028 volatile u08 uartBufferedTx;
00029 // receive and transmit buffers
00030 cBuffer uartRxBuffer;
00031 cBuffer uartTxBuffer;
00032
00033 // UART Transmit Complete Interrupt Function
00034 SIGNAL(SIG_UART_TRANS)
00035 {
00036 // check if buffered tx is enabled
00037 if(uartBufferedTx)
00038 {
00039 // check if there's data left in the buffer
00040 if(uartTxBuffer.datalength)
00041 {
00042 // send byte from top of buffer
00043 outp( bufferGetFromFront(&uartTxBuffer), UDR );
00044 }
00045 else
00046 {
00047 // no data left
00048 uartBufferedTx = FALSE;
00049 // return to ready state
00050 uartReadyTx = TRUE;
00051 }
00052 }
00053 else
00054 {
00055 // we're using single-byte tx mode
00056 // indicate transmit complete, back to ready
00057 uartReadyTx = TRUE;
00058 }
00059 }
00060
00061 // UART Receive Complete Interrupt Function
00062 SIGNAL(SIG_UART_RECV)
00063 {
00064 // put received char in buffer
00065 // check if there's space
00066 if( !bufferAddToEnd(&uartRxBuffer, inp(UDR)) )
00067 {
00068 // no space - do something to signal an overflow
00069 //printfProgStrM("UART RX OVFL");
00070 }
00071 }
00072
00073 void uartInitBuffers(void)
00074 {
00075 // initialize the UART receive buffer
00076 bufferInit(&uartRxBuffer, (u08*) UART_RX_BUFFER_ADDR, UART_RX_BUFFER_SIZE);
00077 // initialize the UART transmit buffer
00078 bufferInit(&uartTxBuffer, (u08*) UART_TX_BUFFER_ADDR, UART_TX_BUFFER_SIZE);
00079 }
00080
00081 void uartSetBaudRate(u16 baudrate)
00082 {
00083 // calculate division factor for requested baud rate, and set it
00084 outp( (u08)((F_CPU+(baudrate*8L))/(baudrate*16L)-1), UBRR);
00085 }
00086
00087 void uartInit(void)
00088 {
00089 // initialize the buffers
00090 uartInitBuffers();
00091
00092 // enable RxD/TxD and interrupts
00093 // this line for AT90S8515,8535,ATmega103,etc
00094 //outp(BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN),UCR);
00095 // this line for the Mega163
00096 outp(BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN),UCSRB);
00097
00098 // set default baud rate
00099 uartSetBaudRate(UART_BAUD_RATE);
00100 // enable interrupts
00101 sei();
00102 // initialize states
00103 uartReadyTx = TRUE;
00104 }
00105
00106 cBuffer* uartGetRxBuffer(void)
00107 {
00108 // return rx buffer pointer
00109 return &uartRxBuffer;
00110 }
00111
00112 cBuffer* uartGetTxBuffer(void)
00113 {
00114 // return tx buffer pointer
00115 return &uartTxBuffer;
00116 }
00117
00118 void uartSendByte(u08 txData)
00119 {
00120 // wait for the transmitter to be ready
00121 while(!uartReadyTx);
00122 // send byte
00123 outp( txData, UDR );
00124 // set ready state to FALSE
00125 uartReadyTx = FALSE;
00126 }
00127
00128 u08 uartReceiveByte(u08* rxData)
00129 {
00130 // make sure we have a receive buffer
00131 if(uartRxBuffer.size)
00132 {
00133 // make sure we have data
00134 if(uartRxBuffer.datalength)
00135 {
00136 // get byte from beginning of buffer
00137 *rxData = bufferGetFromFront(&uartRxBuffer);
00138 return TRUE;
00139 }
00140 else
00141 {
00142 // no data
00143 return FALSE;
00144 }
00145 }
00146 else
00147 {
00148 // no buffer
00149 return FALSE;
00150 }
00151 }
00152
00153 void uartFlushReceiveBuffer(void)
00154 {
00155 // flush all data from receive buffer
00156 bufferFlush(&uartRxBuffer);
00157 // same effect as above
00158 // uartRxBuffer.datalength = 0;
00159 }
00160
00161 u08 uartReceiveBufferIsEmpty(void)
00162 {
00163 if(uartRxBuffer.datalength == 0)
00164 {
00165 return TRUE;
00166 }
00167 else
00168 {
00169 return FALSE;
00170 }
00171 }
00172
00173 void uartSendTxBuffer(void)
00174 {
00175 // turn on buffered transmit
00176 uartBufferedTx = TRUE;
00177 // send the first byte to get things going by interrupts
00178 uartSendByte(bufferGetFromFront(&uartTxBuffer));
00179 }
00180
00181 u08 uartSendBuffer(char *buffer, u16 nBytes)
00182 {
00183 register u08 first;
00184 register u16 i;
00185
00186 // check if there's space (and that we have any bytes to send at all)
00187 if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes)
00188 {
00189 // grab first character
00190 first = *buffer++;
00191 // copy user buffer to uart transmit buffer
00192 for(i = 0; i < nBytes-1; i++)
00193 {
00194 // put data bytes at end of buffer
00195 uartTxBuffer.dataptr[(uartTxBuffer.dataindex + uartTxBuffer.datalength) % uartTxBuffer.size] = *buffer++;
00196 // increment the length
00197 uartTxBuffer.datalength++;
00198 }
00199
00200 // send the first byte to get things going by interrupts
00201 uartBufferedTx = TRUE;
00202 uartSendByte(first);
00203 // return success
00204 return TRUE;
00205 }
00206 else
00207 {
00208 // return failure
00209 return FALSE;
00210 }
00211 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -