📄 io.c
字号:
#include "compiler.h"
#include "config.h"
#include "isp.h"
/******************************* 宏定义 **********************************/
#define XON 17 /* 定义 XON / XOFF 控制字符 */
#define XOFF 19
#define RX_BUF_SIZE 16 /* 定义接收缓冲区大小,必须为2^y */
/* 定义当接收缓冲区仅剩50%时XOFF标志 */
#define XOFF_THRESH (RX_BUF_SIZE - (RX_BUF_SIZE / 2) )
/* 定义当25%接收缓冲区满时XON标志 */
#define XON_THRESH (RX_BUF_SIZE / 4)
/* 定义等待串行口发送完毕标志 */
#define WAIT_EO_TX {while (TI==0); TI=0;}
/******************************** 变量定义 *******************************/
static Uchar rx_buffer[RX_BUF_SIZE]; /* 接收环形缓冲区 */
static Uchar rx_index_wr; /* 接收环形缓冲区索引 */
static Uchar rx_index_rd;
static Bool tx_off; /* XOFF 状态标志 */
Uchar nb_rx_data; /* 接收缓冲区内的数据个数 */
void rx_buffer_wr(Uchar rx_data);
/***************************** 串行口中断函数 ****************************
* 功 能: 仅处理串行口接收中断。
*************************************************************************/
Interrupt(void uart(void),4) {
if (RI == 1) {
rx_buffer_wr(SBUF); /* 将接收到的数据写入接收缓冲区 */
RI = 0;
}
}
/***************************** 数据发送函数 ******************************
* 功 能: 从串行口发送一个字符。
*************************************************************************/
void uart_tx(Uchar tx_data) {
SBUF = tx_data;
WAIT_EO_TX;
}
/************************** 串行口初始化函数 *****************************
* 功 能: 设置串行口工作方式。
*************************************************************************/
void uart_init(void) {
SCON = 0x50;
TMOD = TMOD | 0x20 ; /* 设置定时器T1为方式2,作为波特率发生器 */
TH1 = 0xFD; /* 采用11.059200MHZ晶振时,波特率为9600 */
TL1 = 0xFD;
PCON = PCON & 0X80;
TCON |= 0x40;
TI=1;
}
/**************************** 允许串行口接收函数 *************************
* 功 能: 复位环形缓冲区,初始化XON/XOFF协议,允许串行口中断
*************************************************************************/
void uart_rx_enable(void) {
rx_index_wr = rx_index_rd = nb_rx_data = 0;
WAIT_EO_TX; /* 等待前面发送完成(printf) */
uart_tx(XON);
ES = 1;
}
/**************************** 禁止串行口接收函数 *************************
* 功 能: 禁止串行口接收中断。
*************************************************************************/
void uart_rx_disable(void) {
ES = 0;
TI = 1; /* 允许串行口发送中断,以便用printf函数进行查询 */
}
/************************** 接收缓冲区检测函数 ***************************
* 功 能:检测是否有新接收数据存入到接收缓冲区,当缓冲区为空时返回1,否
* 则返回0。
*************************************************************************/
Bool rx_buffer_empty(void) {
if (nb_rx_data == 0)
return TRUE;
else
return FALSE;
}
/**************************** 缓冲区数据写入函数 *************************
* 功 能: 将新接收的数据写入缓冲区并更新缓冲区索引值。
* 参 数: Uchar rx_data,要存入缓冲区的数据。
*: Rx data to store in the buffer.
*************************************************************************/
void rx_buffer_wr(Uchar rx_data) {
nb_rx_data++;
rx_buffer[rx_index_wr] = rx_data;
rx_index_wr=(rx_index_wr+1)%RX_BUF_SIZE; /* 计算环形缓冲区索引值 */
/* 当接收缓冲区中存入的字符多于XOFF_THRES标志时PC机停止发送数据 */
if ((tx_off==FALSE) && (nb_rx_data > XOFF_THRESH)) {
uart_tx(XOFF);
tx_off = TRUE;
}
}
/************************* 读取接收缓冲区数据函数 *************************
* 功 能:读取接收缓冲区中的下一个数据并返回。
*************************************************************************/
Uchar rx_buffer_rd(void) {
static Uchar data_cnt=0;
Uchar rx_data;
EA=0; /* 关中断,以避免与rx_buffer_wr()函数发生冲突 */
nb_rx_data--;
EA=1; /* 开中断 */
rx_data = rx_buffer[rx_index_rd];
rx_index_rd=(rx_index_rd+1)%RX_BUF_SIZE; /* 计算环形缓冲区索引值 */
data_cnt++;
if (data_cnt == 0) uart_tx('.');
/* 当接收缓冲区中存入的字符少于XOFF_THRES标志时PC机继续发送数据 */
EA = 0;
if ((tx_off == TRUE) && (nb_rx_data < XON_THRESH)) {
uart_tx(XON);
tx_off = FALSE;
}
EA = 1;
return(rx_data);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -