📄 uart.c
字号:
//*****************************************************************
//
// File Name : 'uart.c'
// Title : UART driver
// Author : Pascal Stang
// Date : 11/22/2000
// Version : 0.1
// Target MCU : ATmega103
// Editor Tabs : 3
//
//*****************************************************************
#include <io.h>
#include <interrupt.h>
#include <signal.h>
#include <progmem.h>
#include "uart.h"
// UART global variables
volatile u08 uartReadyTx;
volatile u08 uartBufferedTx;
cBuffer uartRxBuffer;
cBuffer uartTxBuffer;
// end-of-line string = 'Line End' + 'Line Feed' character
prog_char UART_pszEndOfLine[3] = {0x0d,0x0a,0};
// outp( PRG_RDB(pUART_Buffer), UDR );
// UART Transmit Complete Interrupt Function
SIGNAL(SIG_UART_TRANS)
{
// check if buffered tx is enabled
if(uartBufferedTx)
{
// check if there's data left in the buffer
if(uartTxBuffer.datalength)
{
// send byte from top of buffer
outp( uartTxBuffer.dataptr[uartTxBuffer.dataindex], UDR );
// move index down and decrement length
uartTxBuffer.dataindex++;
if(uartTxBuffer.dataindex >= uartTxBuffer.size)
{
uartTxBuffer.dataindex = uartTxBuffer.dataindex % uartTxBuffer.size;
}
uartTxBuffer.datalength--;
}
else
{
// no data left
uartBufferedTx = FALSE;
// return to ready state
uartReadyTx = TRUE;
}
}
else
{
// we're using single-byte tx mode
// indicate transmit complete, back to ready
uartReadyTx = TRUE;
}
}
// UART Receive Complete Interrupt Function
SIGNAL(SIG_UART_RECV)
{
cli();
// put received char in circular buffer
// check if there's space
if(uartRxBuffer.datalength < uartRxBuffer.size)
{
// put data byte at end of buffer
// uartRxBuffer.dataptr[(uartRxBuffer.dataindex + uartRxBuffer.datalength) % uartRxBuffer.size] = inp(UDR);
uartRxBuffer.dataptr[(uartRxBuffer.dataindex + uartRxBuffer.datalength) & (uartRxBuffer.size-1)] = inp(UDR);
// increment the length
uartRxBuffer.datalength++;
}
else
{
inp(UDR);
uartPrintStr("UART RX OVFL");
}
sei();
}
void uartInitBuffers(void)
{
// initialize the UART receive buffer
uartRxBuffer.size = UART_RX_BUFFER_SIZE;
uartRxBuffer.datalength = 0;
uartRxBuffer.dataindex = 0;
uartRxBuffer.dataptr = (u08*) UART_RX_BUFFER_ADDR;
uartTxBuffer.size = UART_TX_BUFFER_SIZE;
uartTxBuffer.datalength = 0;
uartTxBuffer.dataindex = 0;
uartTxBuffer.dataptr = (u08*) UART_TX_BUFFER_ADDR;
}
void uartInit(void)
{
// initialize the buffers
uartInitBuffers();
// enable RxD/TxD and interrupts
outp(BV(RXCIE)|BV(TXCIE)|BV(RXEN)|BV(TXEN),UCR);
// set baud rate
outp( (u08)UART_BAUD_SELECT, UBRR);
// enable interrupts
sei();
// initialize states
uartReadyTx = TRUE;
}
void uartSendByte(u08 txData)
{
// wait for the transmitter to be ready
while(!uartReadyTx);
// send byte
outp( txData, UDR );
// set ready state to FALSE
uartReadyTx = FALSE;
}
u08 uartReceiveByte(u08* rxData)
{
// make sure we have data
if(uartRxBuffer.datalength != 0)
{
// get byte from beginning of buffer
*rxData = uartRxBuffer.dataptr[uartRxBuffer.dataindex];
// move index down and decrement length
uartRxBuffer.dataindex++;
if(uartRxBuffer.dataindex >= uartRxBuffer.size)
{
uartRxBuffer.dataindex = uartRxBuffer.dataindex % uartRxBuffer.size;
}
uartRxBuffer.datalength--;
return TRUE;
}
else
{
// no data
return FALSE;
}
}
void uartFlushReceiveBuffer(void)
{
// flush all data from receive buffer
uartRxBuffer.datalength = 0;
}
u08 uartReceiveBufferEmpty(void)
{
if(uartRxBuffer.datalength == 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
void uartPrintStr(char str[])
{
register u08 *c;
// check to make sure we have a good pointer
if (!(c=str)) return;
// print the string until a null-terminator
while (*c)
{
uartSendByte(*c++);
}
}
u08 uartSendBuffer(char *buffer, u16 nBytes)
{
register u08 first;
register u16 i;
// check if there's space (and that we have any bytes to send at all)
if((uartTxBuffer.datalength + nBytes < uartTxBuffer.size) && nBytes)
{
// grab first character
first = *buffer++;
// copy user buffer to uart transmit buffer
for(i = 0; i < nBytes-1; i++)
{
// put data bytes at end of buffer
uartTxBuffer.dataptr[(uartTxBuffer.dataindex + uartTxBuffer.datalength) % uartTxBuffer.size] = *buffer++;
// increment the length
uartTxBuffer.datalength++;
}
// send the first byte to get things going by interrupts
uartBufferedTx = TRUE;
uartSendByte(first);
// set ready state to FALSE (busy)
//uartReadyTx = FALSE;
// return success
return TRUE;
}
else
{
// return failure
return FALSE;
}
}
/*
void uartPrintfProgStr(u08* pBuf)
{
// wait for UART to become available
while(!UART_Ready);
UART_Ready = 0;
// Indicate to ISR the string to be sent
pUART_Buffer = pBuf;
// Send first character
outp( PRG_RDB(pUART_Buffer), UDR );
}
void uartPrintfEndOfLine(void)
{
// wait for UART to become available
while(!UART_Ready);
UART_Ready = 0;
// Indicate to ISR the string to be sent
pUART_Buffer = UART_pszEndOfLine;
// Send first character
outp( PRG_RDB(pUART_Buffer), UDR );
}
*/
void uartPrintfU4(u08 data)
{
// Send 4-bit hex value
u08 Character = data&0x0f;
if (Character>9)
{
Character+='A'-10;
}
else
{
Character+='0';
}
uartSendByte(Character);
}
void uartPrintfu08(u08 data)
{
// Send 8-bit hex value
uartPrintfU4(data>>4);
uartPrintfU4(data);
}
void uartPrintfu16(u16 data)
{
// Send 16-bit hex value
uartPrintfu08(data>>8);
uartPrintfu08(data);
}
void uartPrintfu32(u32 data)
{
// Send 32-bit hex value
uartPrintfu16(data>>16);
uartPrintfu16(data);
}
void uartPrintChar(u08 data)
{
// Send 32-bit hex value
uartSendByte(data);
}
// Print a number in the given base
/*
void print_number (int base, int unsigned_p, long n)
{
static char chars[16] = "0123456789abcdef";
char *p, buf[32];
unsigned long x;
if (!unsigned_p && n < 0)
{
UART_SendByte('-');
x = -n;
}
else
x = n;
p = buf + sizeof (buf);
*--p = '\0';
do
{
*--p = chars[x % base];
x /= base;
}
while (x != 0);
while (*p)
UART_SendByte(*p++);
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -