📄 uart.c.txt
字号:
00001 /*! \file uart.c \brief UART driver with buffer support. */
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 : 06/09/2003
00009 // Version : 1.3
00010 // Target MCU : ATMEL AVR Series
00011 // Editor Tabs : 4
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 <avr/io.h>
00019 #include <avr/interrupt.h>
00020
00021 #include "buffer.h"
00022 #include "uart.h"
00023
00024 // UART global variables
00025 // flag variables
00026 volatile u08 uartReadyTx; ///< uartReadyTx flag
00027 volatile u08 uartBufferedTx; ///< uartBufferedTx flag
00028 // receive and transmit buffers
00029 cBuffer uartRxBuffer; ///< uart receive buffer
00030 cBuffer uartTxBuffer; ///< uart transmit buffer
00031 unsigned short uartRxOverflow; ///< receive overflow counter
00032
00033 #ifndef UART_BUFFERS_EXTERNAL_RAM
00034 // using internal ram,
00035 // automatically allocate space in ram for each buffer
00036 static char uartRxData[UART_RX_BUFFER_SIZE];
00037 static char uartTxData[UART_TX_BUFFER_SIZE];
00038 #endif
00039
00040 typedef void (*voidFuncPtru08)(unsigned char);
00041 volatile static voidFuncPtru08 UartRxFunc;
00042
00043 // enable and initialize the uart
00044 void uartInit(void)
00045 {
00046 // initialize the buffers
00047 uartInitBuffers();
00048 // initialize user receive handler
00049 UartRxFunc = 0;
00050
00051 // enable RxD/TxD and interrupts
00052 outb(UCR, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
00053
00054 // set default baud rate
00055 uartSetBaudRate(UART_DEFAULT_BAUD_RATE);
00056 // initialize states
00057 uartReadyTx = TRUE;
00058 uartBufferedTx = FALSE;
00059 // clear overflow count
00060 uartRxOverflow = 0;
00061 // enable interrupts
00062 sei();
00063 }
00064
00065 // create and initialize the uart transmit and receive buffers
00066 void uartInitBuffers(void)
00067 {
00068 #ifndef UART_BUFFERS_EXTERNAL_RAM
00069 // initialize the UART receive buffer
00070 bufferInit(&uartRxBuffer, uartRxData, UART_RX_BUFFER_SIZE);
00071 // initialize the UART transmit buffer
00072 bufferInit(&uartTxBuffer, uartTxData, UART_TX_BUFFER_SIZE);
00073 #else
00074 // initialize the UART receive buffer
00075 bufferInit(&uartRxBuffer, (u08*) UART_RX_BUFFER_ADDR, UART_RX_BUFFER_SIZE);
00076 // initialize the UART transmit buffer
00077 bufferInit(&uartTxBuffer, (u08*) UART_TX_BUFFER_ADDR, UART_TX_BUFFER_SIZE);
00078 #endif
00079 }
00080
00081 // redirects received data to a user function
00082 void uartSetRxHandler(void (*rx_func)(unsigned char c))
00083 {
00084 // set the receive interrupt to run the supplied user function
00085 UartRxFunc = rx_func;
00086 }
00087
00088 // set the uart baud rate
00089 void uartSetBaudRate(u32 baudrate)
00090 {
00091 // calculate division factor for requested baud rate, and set it
00092 u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
00093 outb(UBRRL, bauddiv);
00094 #ifdef UBRRH
00095 outb(UBRRH, bauddiv>>8);
00096 #endif
00097 }
00098
00099 // returns the receive buffer structure
00100 cBuffer* uartGetRxBuffer(void)
00101 {
00102 // return rx buffer pointer
00103 return &uartRxBuffer;
00104 }
00105
00106 // returns the transmit buffer structure
00107 cBuffer* uartGetTxBuffer(void)
00108 {
00109 // return tx buffer pointer
00110 return &uartTxBuffer;
00111 }
00112
00113 // transmits a byte over the uart
00114 void uartSendByte(u08 txData)
00115 {
00116 // wait for the transmitter to be ready
00117 while(!uartReadyTx);
00118 // send byte
00119 outb(UDR, txData);
00120 // set ready state to FALSE
00121 uartReadyTx = FALSE;
00122 }
00123
00124 // gets a single byte from the uart receive buffer (getchar-style)
00125 int uartGetByte(void)
00126 {
00127 u08 c;
00128 if(uartReceiveByte(&c))
00129 return c;
00130 else
00131 return -1;
00132 }
00133
00134 // gets a byte (if available) from the uart receive buffer
00135 u08 uartReceiveByte(u08* rxData)
00136 {
00137 // make sure we have a receive buffer
00138 if(uartRxBuffer.size)
00139 {
00140 // make sure we have data
00141 if(uartRxBuffer.datalength)
00142 {
00143 // get byte from beginning of buffer
00144 *rxData = bufferGetFromFront(&uartRxBuffer);
00145 return TRUE;
00146 }
00147 else
00148 {
00149 // no data
00150 return FALSE;
00151 }
00152 }
00153 else
00154 {
00155 // no buffer
00156 return FALSE;
00157 }
00158 }
00159
00160 // flush all data out of the receive buffer
00161 void uartFlushReceiveBuffer(void)
00162 {
00163 // flush all data from receive buffer
00164 //bufferFlush(&uartRxBuffer);
00165 // same effect as above
00166 uartRxBuffer.datalength = 0;
00167 }
00168
00169 // return true if uart receive buffer is empty
00170 u08 uartReceiveBufferIsEmpty(void)
00171 {
00172 if(uartRxBuffer.datalength == 0)
00173 {
00174 return TRUE;
00175 }
00176 else
00177 {
00178 return FALSE;
00179 }
00180 }
00181
00182 // add byte to end of uart Tx buffer
00183 u08 uartAddToTxBuffer(u08 data)
00184 {
00185 // add data byte to the end of the tx buffer
00186 return bufferAddToEnd(&uartTxBuffer, data);
00187 }
00188
00189 // start transmission of the current uart Tx buffer contents
00190 void uartSendTxBuffer(void)
00191 {
00192 // turn on buffered transmit
00193 uartBufferedTx = TRUE;
00194 // send the first byte to get things going by interrupts
00195 uartSendByte(bufferGetFromFront(&uartTxBuffer));
00196 }
00197 /*
00198 // transmit nBytes from buffer out the uart
00199 u08 uartSendBuffer(char *buffer, u16 nBytes)
00200 {
00201 register u08 first;
00202 register u16 i;
00203
00204 // check if there's space (and that we have any bytes to send at all)
00205 if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes)
00206 {
00207 // grab first character
00208 first = *buffer++;
00209 // copy user buffer to uart transmit buffer
00210 for(i = 0; i < nBytes-1; i++)
00211 {
00212 // put data bytes at end of buffer
00213 bufferAddToEnd(&uartTxBuffer, *buffer++);
00214 }
00215
00216 // send the first byte to get things going by interrupts
00217 uartBufferedTx = TRUE;
00218 uartSendByte(first);
00219 // return success
00220 return TRUE;
00221 }
00222 else
00223 {
00224 // return failure
00225 return FALSE;
00226 }
00227 }
00228 */
00229 // UART Transmit Complete Interrupt Handler
00230 UART_INTERRUPT_HANDLER(SIG_UART_TRANS)
00231 {
00232 // check if buffered tx is enabled
00233 if(uartBufferedTx)
00234 {
00235 // check if there's data left in the buffer
00236 if(uartTxBuffer.datalength)
00237 {
00238 // send byte from top of buffer
00239 outb(UDR, bufferGetFromFront(&uartTxBuffer));
00240 }
00241 else
00242 {
00243 // no data left
00244 uartBufferedTx = FALSE;
00245 // return to ready state
00246 uartReadyTx = TRUE;
00247 }
00248 }
00249 else
00250 {
00251 // we're using single-byte tx mode
00252 // indicate transmit complete, back to ready
00253 uartReadyTx = TRUE;
00254 }
00255 }
00256
00257 // UART Receive Complete Interrupt Handler
00258 UART_INTERRUPT_HANDLER(SIG_UART_RECV)
00259 {
00260 u08 c;
00261
00262 // get received char
00263 c = inb(UDR);
00264
00265 // if there's a user function to handle this receive event
00266 if(UartRxFunc)
00267 {
00268 // call it and pass the received data
00269 UartRxFunc(c);
00270 }
00271 else
00272 {
00273 // otherwise do default processing
00274 // put received char in buffer
00275 // check if there's space
00276 if( !bufferAddToEnd(&uartRxBuffer, c) )
00277 {
00278 // no space in buffer
00279 // count overflow
00280 uartRxOverflow++;
00281 }
00282 }
00283 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -