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

📄 uartintr.c

📁 老外写得最新arm 库很多值得学习的基于mcu得c函数写法
💻 C
字号:
/*! \file uartintr.c \brief UART driver for ARM LPC2000 16550 with interrupts. */
//*****************************************************************************
//
// File Name	: 'uartintr.c'
// Title		: UART driver for ARM LPC2000 16550 with interrupts
// Author		: Pascal Stang - Copyright (C) 2004-2006
// Created		: 4/3/2004
// Revised		: 4/11/2006
// Version		: 0.1
// Target MCU	: Philips ARM LPC2000 Series
// Editor Tabs	: 4
//
// This code is distributed under the GNU Public License
//		which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************

#include <limits.h>
#include "LPC2000.h"

#include "global.h"
#include "processor.h"
#include "buffer.h"
#include "uartintr.h"

// receive and transmit buffers
cBuffer uartRxBuffer[2];			///< uart receive buffer
cBuffer uartTxBuffer[2];			///< uart transmit buffer
static unsigned char uart0RxData[UART0_RX_BUFFER_SIZE];
static unsigned char uart1RxData[UART1_RX_BUFFER_SIZE];

//! enable and initialize the uart
void uart0Init(uint16_t baud, uint8_t mode, uint8_t fifomode)
{
	// set pin-select register to connect to UART0
	PINSEL0 = (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
	// reset and initialize the UART
	U0IER = 0;		// disable all interrupt sources
	U0IIR;			// clear any pending interrupts
	U0FCR = (UFCR_TX_FIFO_RESET|UFCR_RX_FIFO_RESET);	// reset the Tx/Rx FIFOs
	// set the baudrate divisor
	U0LCR = ULCR_DLAB_ENABLE;	// set divisor access bit (permits modification of divisors)
	U0DLL = (baud);				// set the baud division
	U0DLM = (baud>>8);
	U0LCR = 0;					// reset DLAB (normal operation)
	// set line parameters and fifo mode
	U0LCR = mode;
	U0FCR = fifomode;
	// with uart configured, clear line status and receive registers
	U0RBR; U0LSR;
	// initialize buffers
	uart0InitBuffers();
	// attach interrupt handler
	processorVicAttach(VIC_UART0, 0, uart0Service);
	// enable receive interrupt
	U0IER |= UIER_ERBFI;
}

void uart1Init(uint16_t baud, uint8_t mode, uint8_t fifomode)
{
	// set pin-select register to connect to UART1
	PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL;
	// reset and initialize the UART
	U1IER = 0;		// disable all interrupt sources
	U1IIR;			// clear any pending interrupts
	U1FCR = (UFCR_TX_FIFO_RESET|UFCR_RX_FIFO_RESET);	// reset the Tx/Rx FIFOs
	// set the baudrate divisor
	U1LCR = ULCR_DLAB_ENABLE;	// set divisor access bit (permits modification of divisors)
	U1DLL = (baud);				// set the baud division
	U1DLM = (baud>>8);
	U1LCR = 0;					// reset DLAB (normal operation)
	// set line parameters and fifo mode
	U1LCR = mode;
	U1FCR = fifomode;
	// with uart configured, clear line status and receive registers
	U1RBR; U1LSR;
	// initialize buffers
	uart1InitBuffers();
	// attach interrupt handler
	processorVicAttach(VIC_UART1, 0, uart1Service);
	// enable receive interrupt
	U1IER |= UIER_ERBFI;
}

void uart0InitBuffers(void)
{
	// initialize the UART0 buffers
	bufferInit(&uartRxBuffer[0], uart0RxData, UART0_RX_BUFFER_SIZE);
	//bufferInit(&uartTxBuffer[0], uart0TxData, UART0_TX_BUFFER_SIZE);
}

void uart1InitBuffers(void)
{
	// initialize the UART1 buffers
	bufferInit(&uartRxBuffer[1], uart1RxData, UART1_RX_BUFFER_SIZE);
	//bufferInit(&uartTxBuffer[1], uart1TxData, UART1_TX_BUFFER_SIZE);
}

cBuffer* uart0GetRxBuffer(void)
{
	// return rx buffer pointer
	return &uartRxBuffer[0];
}

cBuffer* uart1GetRxBuffer(void)
{
	// return rx buffer pointer
	return &uartRxBuffer[1];
}

int uart0SendByte(int data)
{
	// wait for tx buffer ready
	while( !(U0LSR & ULSR_THRE) );
	// send the character
	return (U0THR = data);
}

int uart1SendByte(int data)
{
	// wait for tx buffer ready
	while( !(U1LSR & ULSR_THRE) );
	// send the character
	return (U1THR = data);
}

int uart0GetByte(void)
{
	// if character is available, return it
	if(uartRxBuffer[0].datalength)
		return bufferGetFromFront(&uartRxBuffer[0]);
	// otherwise, return failure
	return -1;
}

int uart1GetByte(void)
{	
	// if character is available, return it
	if(uartRxBuffer[1].datalength)		// check if character is available
		return bufferGetFromFront(&uartRxBuffer[1]);	// return character
	// otherwise, return failure
	return -1;
}

void uart0Service(void)
{
	uint8_t intr_flags;

//	ISR_ENTRY();
	
	// service pending interrupts until the interrupt status register is clear
	while( !((intr_flags=U0IIR) & UIIR_NO_INT) )
	{
		// check the interrupt source
		switch(intr_flags & UIIR_ID_MASK)
		{
		case UIIR_RLS_INT:	// receive line status interrupt
			U0LSR;					// clear interrupt by reading status
			break;
		case UIIR_CTI_INT:	// character timeout interrupt
		case UIIR_RDA_INT:	// receive data available interrupt
			do { bufferAddToEnd(&uartRxBuffer[1], U0RBR); } while(U0LSR & ULSR_RDR);
			break;
		case UIIR_THRE_INT:	// transmit holding register empty
			break;
		default:			// unknown/unhandled interrupt
			U0LSR;					// read registers to clear
			U0RBR;
			break;
		}
	}

	VICSoftIntClear = (1<<VIC_UART0);	// clear software interrupt
	VICVectAddr = 0x00000000;			// clear the VIC
//	ISR_EXIT();
}

void uart1Service(void)
{
	uint8_t intr_flags;

//	ISR_ENTRY();

	// service pending interrupts until the interrupt status register is clear
	while( !((intr_flags=U1IIR) & UIIR_NO_INT) )
	{
		// check the interrupt source
		switch(intr_flags & UIIR_ID_MASK)
		{
		case UIIR_RLS_INT:	// receive line status interrupt
			U1LSR;					// clear interrupt by reading status
			break;
		case UIIR_CTI_INT:	// character timeout interrupt
		case UIIR_RDA_INT:	// receive data available interrupt
			do { bufferAddToEnd(&uartRxBuffer[1], U1RBR); } while(U1LSR & ULSR_RDR);
			break;
		case UIIR_THRE_INT:	// transmit holding register empty
			break;
		case UIIR_MS_INT:	// MODEM Status
			U1MSR;					// read MSR to clear
			break;
		default:			// unknown/unhandled interrupt
			U1LSR;					// read registers to clear
			U1RBR;
			U1MSR;
			break;
		}
	}
	
	VICSoftIntClear = (1<<VIC_UART1);	// clear software interrupt
	VICVectAddr = 0x00000000;			// clear the VIC
//	ISR_EXIT();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -