📄 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 <progmem.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
#ifdef YAMPP3USB
#define UDR UDR0
#define UCR UCSR0B
#define USR UCSR0A
#define RXCIE RXCIE0
#define RXEN RXEN0
#define TXEN TXEN0
#define UBRR UBRR0
#define UDRE UDRE0
#endif //YAMPP3USB
// ---- 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);
#ifdef YAMPP3USB
outp(0,UBRRH);
#endif
outp((u08)UART_BAUD_SELECT, UBRR); // set baud rate
sei(); // enable interrupts
}
// Receiving part
// UART Receive Complete Interrupt Function
#ifdef YAMPP3USB
SIGNAL(SIG_UART0_RECV)
#else
SIGNAL(SIG_UART_RECV)
#endif
{
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_PrintfEndOfLine(void)
{
UART_SendByte('\r');
UART_SendByte('\n');
}
//------------------------------------------------------------------------------------
// Following functions is needed only for debugging
#if defined(DEBUG_ATA) || defined(HEXDUMP) || defined(ENABLE_CRC) || defined(SHOW_REMOTE_CODES) || defined(YAMPP3USB)
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);
}
#endif // defined...
//------------------------------------------------------------------------------------
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_Puts_p(u08* p)
{
register u08 c;
while ((c = PRG_RDB(p++)))
{
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 + -