⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 AVR mp3 embedded program code support IDE with FAT16
💻 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 + -