📄 uart.c
字号:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include "buffer.c"
#include "uart.h"
volatile u08 uartReadyTx; ///< uartReadyTx flag
volatile u08 uartBufferedTx; ///< uartBufferedTx flag
cBuffer uartRxBuffer; ///< uart receive buffer
cBuffer uartTxBuffer; ///< uart transmit buffer
unsigned short uartRxOverflow; ///< receive overflow counter
#ifndef UART_BUFFERS_EXTERNAL_RAM
static char uartRxData[UART_RX_BUFFER_SIZE];
static char uartTxData[UART_TX_BUFFER_SIZE];
#endif
typedef void (*voidFuncPtru08)(unsigned char);
volatile static voidFuncPtru08 UartRxFunc;
void uartInit(void)
{
uartInitBuffers();
UartRxFunc = 0;
outb(UCR, BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN));
uartSetBaudRate(UART_DEFAULT_BAUD_RATE);
uartReadyTx = TRUE;
uartBufferedTx = FALSE;
uartRxOverflow = 0;
sei();
}
void uartInitBuffers(void)
{
#ifndef UART_BUFFERS_EXTERNAL_RAM
bufferInit(&uartRxBuffer, uartRxData, UART_RX_BUFFER_SIZE);
bufferInit(&uartTxBuffer, uartTxData, UART_TX_BUFFER_SIZE);
#else
bufferInit(&uartRxBuffer, (u08*) UART_RX_BUFFER_ADDR, UART_RX_BUFFER_SIZE);
bufferInit(&uartTxBuffer, (u08*) UART_TX_BUFFER_ADDR, UART_TX_BUFFER_SIZE);
#endif
}
void uartSetRxHandler(void (*rx_func)(unsigned char c))
{
UartRxFunc = rx_func;
}
void uartSetBaudRate(u32 baudrate)
{
u16 bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
outb(UBRRL, bauddiv);
#ifdef UBRRH
outb(UBRRH, bauddiv>>8);
#endif
}
cBuffer* uartGetRxBuffer(void)
{
return &uartRxBuffer;
}
cBuffer* uartGetTxBuffer(void)
{
return &uartTxBuffer;
}
void uartSendByte(u08 txData)
{
while(!uartReadyTx);
outb(UDR, txData);
uartReadyTx = FALSE;
}
int uartGetByte(void)
{
u08 c;
if(uartReceiveByte(&c))
return c;
else
return -1;
}
u08 uartReceiveByte(u08* rxData)
{
if(uartRxBuffer.size)
{
if(uartRxBuffer.datalength)
{
*rxData = bufferGetFromFront(&uartRxBuffer);
return TRUE;
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
void uartFlushReceiveBuffer(void)
{
uartRxBuffer.datalength = 0;
}
u08 uartReceiveBufferIsEmpty(void)
{
if(uartRxBuffer.datalength == 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
u08 uartAddToTxBuffer(u08 data)
{
return bufferAddToEnd(&uartTxBuffer, data);
}
void uartSendTxBuffer(void)
{
uartBufferedTx = TRUE;
uartSendByte(bufferGetFromFront(&uartTxBuffer));
}
UART_INTERRUPT_HANDLER(SIG_UART_TRANS)
{
if(uartBufferedTx)
{
if(uartTxBuffer.datalength)
{
outb(UDR, bufferGetFromFront(&uartTxBuffer));
}
else
{
uartBufferedTx = FALSE;
uartReadyTx = TRUE;
}
}
else
{
uartReadyTx = TRUE;
}
}
UART_INTERRUPT_HANDLER(SIG_UART_RECV)
{
u08 c;
c = inb(UDR);
if(UartRxFunc)
{
UartRxFunc(c);
}
else
{
if( !bufferAddToEnd(&uartRxBuffer, c) )
{
uartRxOverflow++;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -