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

📄 sio.c

📁 应用于51芯片的很经典的串口通讯程序源代码 (采用fifo方式)
💻 C
字号:
/*------------------------------------------------------------------------------
SIO.C:  Serial Communication Routines.

Copyright 1995-2002 KEIL Software, Inc.
------------------------------------------------------------------------------*/
#pragma small

#include <reg51.h>
#include <string.h>
#include "sio.h"

/*------------------------------------------------------------------------------
Notes:

The length of the receive and transmit buffers must be a power of 2.

Each buffer has a next_in and a next_out index.

If next_in = next_out, the buffer is empty.

(next_in - next_out) % buffer_size = the number of characters in the buffer.
------------------------------------------------------------------------------*/
#define TBUF_SIZE   4           /*** Must be one of these powers of 2 (2,4,8,16,32,64,128) ***/
#define RBUF_SIZE   16           /*** Must be one of these powers of 2 (2,4,8,16,32,64,128) ***/

#define TBUF_SPACE  idata       /*** Memory space where the transmit buffer resides ***/
#define RBUF_SPACE  idata       /*** Memory space where the receive buffer resides ***/

#define CTRL_SPACE  data        /*** Memory space for the buffer indexes ***/

#define XTAL	11.059*1000000
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
#if TBUF_SIZE < 2
#error TBUF_SIZE is too small.  It must be larger than 1.
#elif TBUF_SIZE > 256
#error TBUF_SIZE is too large.  It must be smaller than 257.
#elif ((TBUF_SIZE & (TBUF_SIZE-1)) != 0)
#error TBUF_SIZE must be a power of 2.
#endif

#if RBUF_SIZE < 2
#error RBUF_SIZE is too small.  It must be larger than 1.
#elif RBUF_SIZE > 256
#error RBUF_SIZE is too large.  It must be smaller than 257.
#elif ((RBUF_SIZE & (RBUF_SIZE-1)) != 0)
#error RBUF_SIZE must be a power of 2.
#endif

/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
static TBUF_SPACE unsigned char tbuf [TBUF_SIZE];
static RBUF_SPACE unsigned char rbuf [RBUF_SIZE];

static CTRL_SPACE unsigned char t_in = 0;
static CTRL_SPACE unsigned char t_out = 0;

static CTRL_SPACE unsigned char r_in = 0;
static CTRL_SPACE unsigned char r_out = 0;

static bit ti_restart = 0;  /* NZ if TI=1 is required */


/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
static void com_isr (void) interrupt 4
{
/*------------------------------------------------
Received data interrupt.
------------------------------------------------*/
	if (RI != 0)
  	{
  		RI = 0;

  		if (((r_in - r_out) & ~(RBUF_SIZE-1)) == 0)
    		{
	    		rbuf [r_in & (RBUF_SIZE-1)] = SBUF;
	    		r_in++;
    		}
  	}

/*------------------------------------------------
Transmitted data interrupt.
------------------------------------------------*/
	if (TI != 0)
	{
		TI = 0;

  		if (t_in != t_out)
    		{
			SBUF = tbuf [t_out & (TBUF_SIZE-1)];
	    		t_out++;
	    		ti_restart = 0;
    		}
  		else
    		{
    			ti_restart = 1;
    		}
	}

}

/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
#pragma disable

void com_initialize (void)
{
	/*------------------------------------------------
	Setup TIMER1 to generate the proper baud rate.
	------------------------------------------------*/
	com_baudrate (1200);

	/*------------------------------------------------
	Clear com buffer indexes.
	------------------------------------------------*/
	t_in = 0;
	t_out = 0;

	r_in = 0;
	r_out = 0;

	/*------------------------------------------------
	Setup serial port registers.
	------------------------------------------------*/
	SM0 = 0; SM1 = 1;   /* serial port MODE 1 */
	SM2 = 0;
	REN = 1;            /* enable serial receiver */

	RI = 0;             /* clear receiver interrupt */
	TI = 0;             /* clear transmit interrupt */
	ti_restart = 1;

	ES = 1;             /* enable serial interrupts */
	PS = 0;             /* set serial interrupts to low priority */
}

/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
#pragma disable

void com_baudrate (
  unsigned baudrate)
{
	/*------------------------------------------------
	Clear transmit interrupt and buffer.
	------------------------------------------------*/
	TI = 0;             /* clear transmit interrupt */
	t_in = 0;           /* empty transmit buffer */
	t_out = 0;

	/*------------------------------------------------
	Set timer 1 up as a baud rate generator.
	------------------------------------------------*/
	TR1 = 0;            /* stop timer 1 */
	ET1 = 0;            /* disable timer 1 interrupt */

	PCON |= 0x80;       /* 0x80=SMOD: set serial baudrate doubler */

	TMOD &= ~0xF0;      /* clear timer 1 mode bits */
	TMOD |= 0x20;       /* put timer 1 into MODE 2 */

	TH1 = (unsigned char) (256 - (XTAL / (16L * 12L * baudrate)));

	TR1 = 1;            /* start timer 1 */
}

/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
#pragma disable

char com_putchar (
  unsigned char c)
{
	/*------------------------------------------------
	If the buffer is full, return an error value.
	------------------------------------------------*/
	if (com_tbuflen () >= TBUF_SIZE)
		return (-1);

	/*------------------------------------------------
	Add the data to the transmit buffer.  If the
	transmit interrupt is disabled, then enable it.
	------------------------------------------------*/
	tbuf [t_in & (TBUF_SIZE - 1)] = c;
	t_in++;

	if (ti_restart)
	{
		ti_restart = 0;
	  	TI = 1;               /* generate transmit interrupt */
	}

	return (0);
}

/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
#pragma disable

int com_getchar (void)
{
	if (com_rbuflen () == 0)
  		return (-1);

	return (rbuf [(r_out++) & (RBUF_SIZE - 1)]);
}

/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
#pragma disable

unsigned char com_rbuflen (void)
{
	return (r_in - r_out);
}

/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
#pragma disable

unsigned char com_tbuflen (void)
{
	return (t_in - t_out);
}

/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/

⌨️ 快捷键说明

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