📄 sio.c
字号:
/*------------------------------------------------------------------------------
SIO.C: Serial Communication Routines.
Copyright 1995-2002 KEIL Software, Inc.
------------------------------------------------------------------------------*/
#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 64 /*** Must be one of these powers of 2 (2,4,8,16,32,64,128) ***/
#define RBUF_SIZE 8 /*** 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 ***/
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
#if TBUF_SIZE < 2
#error TBUF_SIZE is too small. It must be larger than 1.
#elif TBUF_SIZE > 128
#error TBUF_SIZE is too large. It must be smaller than 129.
#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 > 128
#error RBUF_SIZE is too large. It must be smaller than 129.
#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 + -