📄 uart.c
字号:
/*
Jesper Hansen <jesperh@telia.com>
Rewritten by: Nikolai Vorontsov <nickviz@mail.be>
Original Author: Volker Oth <volkeroth@gmx.de>
This file is part of the yampp system.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <io.h>
#include <interrupt.h>
#include <sig-avr.h>
#include "uart.h"
#ifdef ENABLE_SERIAL
// UART global variables
volatile bool UART_CharReceived = false;
volatile bool UART_RxBufOverflow = false;
volatile u08 UART_RxChar = 0;
#ifdef UART_TX_ASYNC
volatile u08 *pUART_TxBuffer = NULL; // if != NULL transmit is going
#endif
// ---- UART core functions --------------------------------------------
// Initialisation
void UART_Init(void)
{
UART_CharReceived = false;
UART_RxBufOverflow = false;
#ifdef UART_TX_ASYNC
pUART_TxBuffer = NULL;
#endif
// enable RxD/TxD and interrupts
#ifdef UART_TX_ASYNC
#define UART_FLAGS (BV(RXCIE) | BV(TXCIE) | BV(RXEN) | BV(TXEN))
#else
#define UART_FLAGS (BV(RXCIE) | BV(RXEN) | BV(TXEN))
#endif
outp(UART_FLAGS, UCR);
outp((u08)UART_BAUD_SELECT, UBRR); // set baud rate
sei(); // enable interrupts
}
// Receiving part
// UART Receive Complete Interrupt Function
SIGNAL(SIG_UART_RECV)
{
if (UART_CharReceived) // buffer overflow
UART_RxBufOverflow = true;
UART_RxChar = inp(UDR); // Store received character
UART_CharReceived = true; // Now, and only now we can indicate
// that the UART has received a character
}
// Retrieve received character or wait until receive
u08 UART_ReceiveByte(void)
{
register u08 temp;
while(!UART_CharReceived); // wait for UART indicates that a character
// has been received. Watchdog protected
temp = UART_RxChar; // first we have to take received character
UART_CharReceived = false; // and only then report that buffer is free
return temp; // return received character
}
// Checks and clear Rx buffer overflow bug
bool UART_CheckRxBuf(void)
{
register bool temp;
temp = UART_RxBufOverflow;
UART_RxBufOverflow = false;
return temp;
}
// Transmit part
#ifdef UART_TX_ASYNC
// UART Transmit Complete Interrupt Function
SIGNAL(SIG_UART_TRANS)
{
if (pUART_TxBuffer != 0) // Test if a string is being sent
{
if (*pUART_TxBuffer != 0) // Test the end of string
outp(*pUART_TxBuffer++, UDR); // Send next character in string
else
pUART_TxBuffer = 0;
}
}
#endif // UART_TX_ASYNC
void UART_SendByte(u08 Data)
{
WDR;
#ifdef UART_TX_ASYNC
while (pUART_TxBuffer); // wait for prev transmit end
#endif
// wait for UART to become available
while ((inp(USR) & BV(UDRE)) != BV(UDRE));
// send character
outp(Data, UDR);
}
void UART_SendStr(u08* pBuf)
{
#ifdef UART_TX_ASYNC
WDR;
while(pUART_TxBuffer);
// cli();
outp(*pBuf, UDR); // this code is not 100% bullet proof!!!
pUART_TxBuffer = pBuf + 1; // uncomment cli/sei to make it b.p.
// sei();
#else
register u08 b;
while ((b = *pBuf++))
UART_SendByte(b);
#endif
}
void UART_PrintfEndOfLine(void)
{
UART_SendByte('\r');
UART_SendByte('\n');
}
static void UART_PrintfU4(u08 Data)
{
/* Send 4-bit hex value */
u08 Character = Data & 0x0f;
Character += '0';
if (Character > '9')
Character += 'A' - '0' - 10;
UART_SendByte(Character);
}
void UART_Printfu08(u08 Data)
{
/* Send 8-bit hex value */
UART_PrintfU4(Data >> 4);
UART_PrintfU4(Data);
}
void UART_Printfu16(u16 Data)
{
/* Send 16-bit hex value */
UART_Printfu08(Data >> 8);
UART_Printfu08(Data);
}
void UART_Printfu32(u32 Data)
{
/* Send 32-bit hex value */
UART_Printfu16(Data >> 16);
UART_Printfu16(Data);
}
void UART_Puts(u08* pBuf)
{
register u08 c;
while ((c = *pBuf++))
{
if (c == '\n')
UART_SendByte('\r'); // for stupid terminal program
UART_SendByte(c);
}
}
void UART_Putsln(u08* pBuf)
{
UART_Puts(pBuf);
UART_PrintfEndOfLine();
}
#endif // ENABLE_SERIAL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -