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

📄 uart.c

📁 实现功能ATmega单片机上处理GSM模块的数据
💻 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 + -