📄 serial.c
字号:
//波特率计算公式:
// TH1=256-(2^SMOD/32*Fosc/12*1/Bound)
// 其中:SMOD=0,1;Fosc=晶体或晶振频率;Bound=波特率
// 本例中,SMOD=0;Fosc=20*10E6;Bound=300,所以TH1=0x52。
//Baud rate(20Mhz)
//300(52);1200(D5);2400(EA);4800(F5);9600(FB);19200(FD);38400(FF);
//应用举例:(可在KEIL仿真环境下运行)
//源程序文件:serial.h/serial.c/main.c
//main.c内容:
#include <general.h>
sbit P10=P1^0;
unsigned char xdata TxBuf[LenTxBuf],RxBuf[LenRxBuf];//收发缓冲区实体
unsigned char xdata *inTxBuf,*outTxBuf, *inRxBuf,*outRxBuf;//收发缓冲区读写指针
//inRxBuf指向收的收,outRxBuf指向收缓冲区的读。
bit TIflag=1;//Note:It must be 1.
unsigned char xdata bRxFull; //标志收缓冲区是否溢出
unsigned char xdata bFullSend; //收缓冲区是否溢出是否已发送满命令
unsigned char xdata bEptSend; //收缓冲区空时是否已发空命令
void InitSerial()//串口初始化
{
TMOD=TMOD&0x0F;
TMOD=TMOD|0x20;
TL1=0xF7,TH1=0xF7;//19200 , 32MHz
SCON=0x50;PCON=0x80;
TR1=1;
}
void InitSerialBuffer(void)//串口缓冲区初始化
{
inTxBuf = TxBuf;
outTxBuf = TxBuf;
inRxBuf = RxBuf;
outRxBuf = RxBuf;
bRxFull = FALSE; //收缓冲区非满
bFullSend = FALSE;
bEptSend = TRUE;
EA=1;
ES=1;
}
/************************************************/
void serial(void) interrupt 4
{//串口中断服务子程序
unsigned char *t;
if(TI)
{
TI=0;
if(inTxBuf==outTxBuf)
{
TIflag=1;
}//TxBuf Empty
else
{
SBUF=*outTxBuf; outTxBuf++;
if(outTxBuf==TxBuf+LenTxBuf)
outTxBuf=TxBuf;
}
}
if(RI)
{
//这里,缓冲区的读写方式跟8019as的ram区一样,是循环读,而且也用了
//两个指针,一个用来收,一个用来读
RI=0;
t=inRxBuf;
t++; //保留指针位置
if(t==RxBuf+LenRxBuf)
t=RxBuf; //如果到缓冲区末尾,则返回缓冲区头
if(t!=outRxBuf)
{
//如果相等,说明缓冲区满了,RxBuf Full
*inRxBuf=SBUF;
inRxBuf=t;
}
else
{
bEptSend = FALSE; //在满了之后,需等待发送空信号
bFullSend =FALSE;
bRxFull = TRUE; //收缓冲区满
}
}
}
//------------------------------------------------------------------------
//函数功能://从串口缓冲区读1字节数据,并对缓冲区状态进行检查。如果满了,则
// 发送缓冲区满信号,如果为空,则发送缓冲区为空信号。
//
//入参:发送区指针,TCP包的长度(包括头部)
//
//
//
//
//作者:
//
//注意:
//
//
//注释: Mingtree
//日期: 2004-11-10
//修改: 2005-12-01 为了实现接收串口的数据,对缓冲区溢出情况进行处理
//------------------------------------------------------------------------
bit Mygetch(unsigned char xdata *ch)
{
ES = 0;
//接收缓冲区满,则发送full信号
if(bRxFull && !bFullSend)
{
bFullSend = TRUE;
PrintStr("full");
}
if(inRxBuf == outRxBuf)
{
//为空
ES = 1;
bRxFull = FALSE;
if(!bEptSend)
{
bEptSend = TRUE;
PrintStr("empty");
}
return 0;
} //RxBuf Empty
*ch=*outRxBuf;
outRxBuf++; //数据被读走,读指针加1
if(outRxBuf == RxBuf+LenRxBuf)
{
outRxBuf = RxBuf; //如果读指针到缓冲区尾部,则返回到头部
}
ES = 1;
return 1;
}
void PrintChar(unsigned char ch)//显示字符
{
unsigned char *t;
ES = 0;
if(TIflag)
{
TIflag = 0;
TI = 1;
}
t = inTxBuf;t++;
if(t == TxBuf+LenTxBuf) t = TxBuf;
if(t == outTxBuf)
{
ES = 1;
return;
}//TxBuf Full
*inTxBuf = ch;
inTxBuf = t;
ES=1;
}
void PrintCh(unsigned char ch)//内部使用,不建议用户看到。
{
if(ch>=0&&ch<=9) ch=ch+'0';
else if(ch>=10&&ch<=15) ch=ch+'A'-10;
PrintChar(ch);
}
void PrintByte(unsigned char Byte)//以十六进制格式显示1个字节数据
{
unsigned char c;
c=Byte;
c=c>>4;PrintCh(c);
c=Byte;c=c&0x0F;PrintCh(c);
}
void PrintWord(unsigned int Word)//以十六进制格式显示1个字数据
{
PrintByte(Word>>8);
PrintByte(Word&0xFF);
}
void PrintLong(unsigned long LongWord)//以十六进制格式显示1个长字数据
{
PrintWord(LongWord>>16);
PrintWord(LongWord&0xFFFF);
}
void PrintStr(unsigned char *str)//显示字符串
{
int i;
unsigned char j;
unsigned char ch;
for(i=0;i<MaxLenStr;i++){
ch=*(str+i);
if(ch=='\0') break;
else if(ch=='\n'){PrintChar(10);PrintChar(13);}
else if(ch=='\t'){
for(j=0;j<TABNum;j++)
PrintChar(' ');
}
else PrintChar(ch);
}
}
void PrintRec(unsigned char xdata *str)//显示字符串
{
int i;
unsigned char ch;
for(i=0;i<MaxLenStr;i++){
ch=*(str+i);
if(ch=='\0') break;
else PrintChar(ch);
}
}
void Mystrlwr(unsigned char xdata *str)//将字符串全部转换成小写格式
{
int i;
unsigned char ch;
for(i=0;1;i++){
ch=*(str+i);
if(ch=='\0') break;
else if(ch>='A'&&ch<='Z') *(str+i)=ch-'A'+'a';
}
}
//------------------------------------------------------------------------
//函数功能:把收到的命令进行数字和字母的分离,之间用空格隔开
//
//入参: 接收命令缓冲区指针ComBuf,分离后缓冲区指针WordTable
//
//返回值: 分离成功1,失败0
//
//作者: Mingtree
//
//注释: Mingtree
//日期: 2004-09-29
//------------------------------------------------------------------------
bit GetWord(unsigned char xdata * ComBuf,WORDTABLE xdata * WordTable)
{
unsigned char i=0; /*ComBuf String pointer*/
unsigned char j;
//对命令包进行调整,去掉数据类型字段和有效数据长度字段
for(i = 0 ; i < CMDLEN ; i++)
ComBuf[i] = ComBuf[i+2];
//找到空格的位置
i = 0;
while(i<MaxLenComBuf)
{
if(ComBuf[i]==32)
break;
i++;
}
if(i!=0)
{
//进行分离
//取得命令
for(j=0;j<i;j++)
WordTable->wt[0].Str[j]=ComBuf[j];
WordTable->wt[0].Length=i;
WordTable->wt[0].Str[j]='\0';
//取得数字
j++;
for(i=0;i<MaxCmd-WordTable->wt[0].Length;i++)
{
WordTable->wt[1].Str[i]=ComBuf[j];
j++;
}
WordTable->wt[1].Length=i;
WordTable->wt[1].Str[i]='\0';
return 1;
}
else
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -