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

📄 serial.c

📁 PC与单片机通信的握手协议的建立
💻 C
字号:
/*****************************************************************************
|*
|*  Copyright (c) 2001 TASKING, Inc.
|*
|*  Description:
|*
|*	This module shows an example how to initialize and use the serial port.
|*      It implements a circular buffer. On a pending overflow
|*	the sender will be notified with an XOFF character. Once the
|*	buffer is read out the sender will again be notified with
|*      an XON character. The command line handler supports backspace,
|*      delete and escape characters.
|*
 ****************************************************************************/

#pragma romstring

#include "serial.h"
void	se_clear_buffer( void );
/*****************************************************************************
|*
|*  FUNCTION:           se_int_transmit
|*
|*  DESCRIPTION:
|*
|*      Clear transmit interrupt flag, and check XOFF status.
|*
 */
_inline void
se_int_transmit( void )
{
	TI = 0;

	if ( flag_send_xoff )
	{
		/* we have to send XOFF */
		flag_send_xoff   = 0;
		SBUF = XOFF;
		flag_xoff_sent   = 1;	/* remember that we sent XOFF */
	}
	else
	{
		flag_TI = 1;
	}
}


/*****************************************************************************
|*
|*  FUNCTION:           se_int_receive
|*
|*  DESCRIPTION:
|*
|*      receive interrupt: store character in circular input buffer
|*
 */
_inline void
se_int_receive( void )
{
	unsigned char x;
	char size;

	x = SBUF;
	RI = 0;

	switch ( x )
	{
	case INTR:
		flag_ctrlC = 1;		/* set flag for handler */
		break;
	case XOFF:
		flag_stopped = 1;
		break;
	case XON:
		flag_stopped = 0;
		break;
	default:
		/* store character in input buffer */
		se_buf[se_buf_in] = x;

		/* increment "in" pointer */
		if ( ++se_buf_in == INPUT_BUFFER_SIZE+1 )
		{
			se_buf_in = 0;		/* wrap around */
		}

		size = se_buf_in - se_buf_out;
		
		if ( !size ) /* check for buffer overflow (se_buf_in == se_buf_out) */
		{
			/* buffer overflow! */
			se_buf_in--;

			if ( se_buf_in < 0 )
			{
				se_buf_in = INPUT_BUFFER_SIZE+1;  /* wrap around */
			}
		}
		else if ( size == HIGH_WATER_MARK )
		{
			/* high water mark reached, stop sender */
			if ( flag_TI )
			{
				flag_TI = 0;
				SBUF = XOFF;
			}
			else
			{
				flag_send_xoff = 1;	/* send XOFF as soon as transmitter is ready */
			}
		}
		break;
	}
}

_inline void
se_clear_buffer_xon( void )
{
	SBUF = XON;

	flag_xoff_sent = 0;
}

_inline void
se_clear_buffer_wait( void )
{
	while( !flag_TI )
	{
		;
	}

	flag_TI = 0;
}

_interrupt(4) void
se_interrupt( void )
{
	if ( RI )
	{
		se_int_receive();
	}
	else if ( TI )
	{
		se_int_transmit();
	}

	return;
}

void
se_initialize_port( void )
{
	flag_TI = 0;

	/* initialize serial port registers */
	SCON = 0x52;
	PCON = 0;

	/* Use Timer 1 */
	TMOD    = 0x21;		/* Timer 1 in mode 2, 8-bit auto-reload */
	TR1     = 1;		/* Turn on Timer 1 */
	TL1 = TH1 = 256-(28800/9600);	/* Set reload value */

	se_clear_buffer();

	ES      = 1;		/* enable serial interrupt */
}

void
se_clear_buffer( void )
{
	se_buf_in  = 0;
	se_buf_out = 0;

	flag_stopped   = 0;	/* no XOFF received */
	flag_send_xoff = 0;	/* no pending XOFF request */

	if ( flag_xoff_sent )
	{
		if ( flag_TI )
		{
			flag_TI = 0;
			se_clear_buffer_xon();
		}
		else
		{
			se_clear_buffer_wait();
		}
	}
}

void
se_putchar( unsigned char ch )
{
	do
	{
		while ( flag_stopped )
		{
			;
		}
	}
	while ( !flag_TI );
	flag_TI = 0;
	
	SBUF = ch;

	if ( ch == RETURN )
	{
		se_putchar( LINEFEED );
	}
}

unsigned char
se_getchar( void )
{
	char x;

	do
	{
		x = se_buf_in - se_buf_out;	/* calculate current size of input buffer */

		if ( x < 0 )
		{
			x += INPUT_BUFFER_SIZE+1;  /* wrap around */
		}

		if ( (x != LOW_WATER_MARK) && flag_xoff_sent )
		{
			/* wait until transmitter is available */
			while ( !flag_TI )
			{
				;
			}
			SBUF = XON;	/* send XON even when 'flag_stopped' is set */

			flag_xoff_sent = 0;
		}

/*
		if(P1_7 == 0)
		{
		  P2_0 = 1;
		}

		if(P1_6 == 0)
		{
		  P2_0 = 0;
		}
*/

		if(P1_5 == 0)
		{
			key_f4_prs = 1;
		}
		if(P1_4 == 0)
		{
			key_f5_prs = 1;
		}
		if(P1_3 == 0)
		{
			key_f8_prs = 1;
		}
	} while ( !x );  /* wait until a character is available */

	x = se_buf[se_buf_out]; /* get character from serial buffer */

	se_buf_out++;	/* increment "out" pointer */

	if ( se_buf_out == INPUT_BUFFER_SIZE+1 )
	{
		se_buf_out = 0;	/* wrap around */
	}

	return x;
}

/*****************************************************************************
|*
|*  FUNCTION:           se_getline
|*
|*  AVAILABILITY:
|*
|*  PARAMETERS:
|*
|*  RETURN VALUE:
|*
|*  DESCRIPTION:
|*
|*      Return the command line in the 'cmdline' buffer
|*
 */
void
se_getline( void )
{
	unsigned char x;
	unsigned char ptr = 0;

	do
	{
		x = se_getchar();	/* get one input character */

		switch ( x )
		{
		case DEL:		/* treat DEL like BACKSPACE */
		case BACKSPACE:
			if ( ptr > 0 )
			{
				se_putchar( BACKSPACE );
				se_putchar( ' ' );
				se_putchar( BACKSPACE );
				ptr--;
			}
			break;
		case ESC:
			while ( ptr )
			{
				se_putchar( BACKSPACE );
				se_putchar( ' ' );
				se_putchar( BACKSPACE );
				ptr--;
			}
			break;
		case RETURN:
			se_putchar( RETURN );	/* echo RETURN */
			cmdline[ptr] = '\0';
			if(P0_3 == 1)
			{
			 P0_3 = 0;
			}
			else
			{
			 P0_3 = 1;
			}
			break;
		default:
			if ( (ptr < COMMAND_LINE_SIZE-1) /* don't write outside cmdline buffer */
			     &&
			     ( x >= 0x20 )  /* ignore control characters */
			     )
			{
				se_putchar( x );	/* echo character */
				cmdline[ptr++] = x;
			}
		}

	} while ( x != RETURN );

	cmdline_ptr = cmdline;
}

/*****************************************************************************
|*
|*  FUNCTION:           se_print
|*
|*  AVAILABILITY:
|*
|*  PARAMETERS:
|*
|*  RETURN VALUE:
|*
|*  DESCRIPTION:
|*
|*      Print a string (located in ROM)
|*
 */
void
se_print( _rom char *str )
{
	while ( *str )
	{
		se_putchar( *str );
		str++;
	}
}

⌨️ 快捷键说明

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