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

📄 16550.c

📁 想必大家一定想了解16650吧,现在上专给大家共享
💻 C
字号:
#include "ip51_sfr.h"
#include "target.h"
#include "16550.h"
#include "stdio.h"

static	UINT8	xdata	utbuf[UTBUF_SIZE];
static	UINT8	xdata	urbuf[URBUF_SIZE];
static	UINT16	idata	ur_in=0;
static	UINT16	idata	ur_out=0;
static	UINT16	idata	ut_in=0;
static	UINT16	idata	ut_out=0;
static	bit				ut_restart=1;
static	UINT16	idata	ur_ovf_cnt =0;

void uart_initialize (UINT8 confg,UINT32 baut)
{
	/******************************************************************************/
	/******************************************************************************/
	UINT8	temp;
	FCR	=	0x87;//set receive FIFO threshold = 8 byte,enable FIFO,reset RX/TX FIFO
	//******************************************************************************/
	/*********Read the following register to clear IIR *****************************/
	/*******************************************************************************/
	temp	=	LSR;
	temp	=	MSR;
	temp	=	IIR;

	/********************************************************************************/
	/*****************set UART work mode ********************************************/
	//CLS	:confg.1  confg.0 	00--data bits = 5
	//							01--data bits = 6
	//							10--data bits = 7
	//							11--data bits = 8				
	//STOP	:confg.2			0---stop bits = 1
	//							1---stop bits = 1.5/2;when data bits=5,stop bits = 1.5,
	//								otherwise,stop bits=2
	//PEN	:confg.3			0---disable odd/even check
	//							1---enable  odd/even check
	//PES	:confg.4			0---odd  check
	//							1---even check
	/********************************************************************************/
	LCR	=	confg & 0x1F;
	

	//set communicate baudrate
	uart_baudrate(baut);
	/********************************************************************************/
	/***********Set UART interrupt  enable ******************************************/
	/********************************************************************************/
	IER	|=	0x0F;

	/********************************************************************************/	
	/***********Remove RX FIFO/TX FIFO reset*****************************************/
	/********************************************************************************/
	FCR	&=	0xF9;

	//clear UART Interrupt flag
	EXIF	&=	0xBF;
	//open UART's interrupt enable
	EIE |= 	0x04;
}


void uart_baudrate (UINT32 baudrate)
{
	int_2_c	div ;
	div.i = XTAL/baudrate/16;
	LCR	|=	0x80;//select DLH,DLL sfr
	DLH	=	div.u8.u8_1;
	DLL	=	div.u8.u8_2;
	LCR	&=	0x7F;//deselect DLH,DLL
}


static void uart_isr() interrupt 10 using 3
{
	UINT8	i;
	EIE	&=	0xFB;
	P6	^=	0x01;
	P5	=	IIR;
	EXIF	&=	0xBF;//clear int flag
	switch(IIR & 0x0F)
	{
		case 0x06://0110 :receive status---overflow;odd/even chech err;frame err;pause int
			P4	=	LSR;//read LSR to clear interrupt
			switch(LSR)
			{
				default:
					break;
			}
			break;
		case 0x04://0100 :receive data valid//
		case 0x0C://1100 :receive time out//Read RBR to clear interrupt
			while(LSR & 0x01)
			{
				urbuf[ur_in & (URBUF_SIZE-1)]	=	RBR;
				if((uart_rbuflen() & ~(URBUF_SIZE-1)) == 0)
					ur_in	++;
				else
					ur_ovf_cnt ++;
			}
			break;
		case 0x01://enable at uput_char
/*			if((LSR&0x60) != 0x60)
				break;*/
//			if(LSR == 0x00)
				break;
		case 0x02://0010 :THR empty //Read IIR or Write THR to clear interrupt
			//if((LSR & 0x60))
				for(i=0;i<16;i++)
				{
					if(ut_in != ut_out)
					{
						THR	=	utbuf[ut_out & (UTBUF_SIZE-1)];
						ut_out	++;
						ut_restart	=	0;
					}
					else
					{
						ut_restart	=	1;
						break;
					}
				}
			break;
		case 0x00://0000 :Modem status change
			P5	=	MSR;
			break;
		default:
			P6	=	0x55;
			break;
	}


	if(ut_restart)
		for(i=0;i<16;i++)
		{
			if(ut_in != ut_out)
			{
				THR	=	utbuf[ut_out & (UTBUF_SIZE-1)];
				ut_out	++;
				ut_restart	=	0;
			}
			else
			{
				ut_restart	=	1;
				break;
			}
		}


	EIE	|=	0x04;
}


INT8	uput_char(UINT8 c)
{
	//if the output buffer is full,return an error value

	if(uart_tbuflen() >= UTBUF_SIZE)
	return (-1);
	/*******************************************************/
	//Add the data to the transmit buffer.  If the
	//transmit interrupt is disabled, then enable it.
	/*******************************************************/
//	printf("uput\n");
	utbuf [ut_in & (UTBUF_SIZE - 1)] = c;
	ut_in++;

	/*Add the follwing code to be strong */
//	if(LSR & 0x40)//TEMT
//		ut_restart	=	1;

	if (ut_restart)
	  {
//		  printf("restart\n");
//		  ut_restart = 0;
		  EXIF |= 0x40;               // generate transmit interrupt 
	  }	
	return (0);
}


INT8	usend(UINT8 xdata *str,UINT16 len)
{
	UINT8 * character;
	UINT16	l;
	
//	printf("usend = %x \n",uart_tbuflen());

	l	=	len;
	character = str;
	if((uart_tbuflen()+l) > UTBUF_SIZE)//utbuf will overflow
		return(-1);

	while(l >0)
	{
		while(1)
		if(uput_char(*character)==0)
		{
			character ++;
			l	--;
			break;
		}
	}
	return (0);

}

INT8 uart_getchar (void)
{
if (uart_rbuflen () == 0)
  return (-1);

return (urbuf [(ur_out++) & (URBUF_SIZE - 1)]);
}



UINT16 uart_tbuflen (void)
{
return (ut_in - ut_out);
}

UINT16 uart_rbuflen (void)
{
return (ur_in - ur_out);
}

⌨️ 快捷键说明

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