📄 中断方式.c
字号:
/* CONSOLE.C -- serial I/O code */
/* Initialize serial port hardware and variables */
#include "serint.h"
void SerInitialize() //串口初始化函数
{
SerFlags = 0;
FlagTransIdle = 1; //声明可以发送
FlagCvtInCR = 1; /* want to turn CRs into LFs */
RR_iHead = RR_iTail = RR_cLev = RR_cMax = 0;
TR_iHead = TR_iTail = TR_cLev = TR_cMax = 0;
UnGotCh = -1; //EOF
/* 设置定时器1,用来生产串口的波特率 */
TCON &= 0x3F; /* clear run & interrupt flags */
TMOD &= 0x0F; /* flush existing Timer 1 setup */
TMOD |= 0x20; /* flush existing Timer 1 setup */
SCON = 0x50; /* flush existing Timer 1 setup */
PCON |= 0x00;
TH1 = TL1 = T1RELOAD & 0x00FF; /* flush existing Timer 1 setup */
TR1 = 1; /* start the timer */
ES = 1; /* enable serial interrupts */
}
/*---------------------------------------------------------------------------*/
/* Serial console interrupt handler */
/* If transmitter output is disabled, we fake trans interrupts until empty */
void SerInt() interrupt 4 //串口中断处理函数
{
if(RI) //如果是接收中断
{
if(RR_cLev) //如果接收缓冲计数器不为零
{
RRing[RR_iHead] = SBUF; //接收数据,并写入接收缓冲区
RR_iHead++; //头指针++
RR_cLev++; //接收计数器++
if(RR_iHead == INRINGSIZE) RR_iHead = 0; //如果缓冲区满,则头指针回0
}
RI = 0; //清中断标志
}
if(TI) //如果是发送中断
{
if(TR_cLev) //如果计数器不为零(有数据发送)
{
SBUF = TRing[TR_iTail]; //将发送缓冲区内数据写入串口
TR_cLev--; //计数器--
TR_iTail++; //尾指针指向下一个数据
if(TR_iTail==OUTRINGSIZE) TR_iTail = 0; //如果缓冲区内的数据都已发送完,尾指针赋初值(0)
}
else //如果缓冲区内无数据
{
FlagTransIdle = 1; //声明缓冲区空
}
TI = 0; //清中断标志
}
}
/*---------------------------------------------------------------------------*/
/* Send character to console */
/* Can strip LFs, in which case you get CR instead of LF/CR */
int putch(int TransChar) //输出1个字符
{
putc(TransChar); /* if not LF, handle normally */
if(TransChar == '\n') //如果输出换行符
{
putc('\r'); //
}
}
int putc(int TransChar)
{
while(TR_cLev >= OUTRINGSIZE); /* wait for space in ring */
ES = 0; //关中断
TRing[TR_iHead] = TransChar; /* point to char slot */
TR_iHead++; /* tick counter & index */
TR_cLev++;
if(TR_iHead == OUTRINGSIZE) TR_iHead = 0; //如果缓冲区满,指针循环
if(FlagTransIdle) //如果可以发送
{
FlagTransIdle = 0; //声明正在发送
TI = 1; //置发送中断标志
}
ES = 1; //开中断
return(TransChar);
}
/*---------------------------------------------------------------------------*/
/* 查看是否接收到数据,并将缓冲区内数据长度返回 */
int chkch()
{
return(RR_cLev); /* tack on current level */
}
/*---------------------------------------------------------------------------*/
/* Wait for the serial transmitter to go idle */
/* If the transmitter is disabled, that's considered to be the same thing */
void SerWaitOutDone()
{
while (TR_cLev); //等待发送缓冲区空
while(!FlagTransIdle); //等待最后1个数据发送完
}
/*---------------------------------------------------------------------------*/
/* Flush the input buffer */
/* Returns number of chars flushed */
int SerFlushIn()
{
ES = 0; /* turn off serial interrupts */
RR_iTail = 0; /* reset ring variables */
RR_iHead = 0;
RR_cLev = 0;
ES = 1; /* turn on serial interrupts */
}
/*---------------------------------------------------------------------------*/
/* Get character from console */
/* CRs turn into LFs unless we're not doing that... */
int getch()
{
int RetVal;
ES = 0; //关中断
if(RR_cLev) //如果接收缓冲区内有数据
{
RetVal = RRing[RR_iTail];
if(RetVal == '\r') RetVal = '\n'; //转换换行符
RR_iTail++; /* tick size index & counter */
RR_cLev--;
if(RR_iTail == INRINGSIZE) RR_iTail = 0; /* hit end of array yet? */
}
else
{
RetVal = -1;
}
ES = 1;
return(RetVal);
}
/*---------------------------------------------------------------------------*/
/* Send string to console */
/* putstr(char *pString); */
/* The ?putstr entry point has *pString in DPTR */
int putstr (char *pstring)
{
while(*pstring) //如果不是空字符
{
putch(*pstring);
pstring++; /* continue... */
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -