📄 serial.c
字号:
/*******************************/
/*C51 serial console---Csc v1.0*/
/*Author: SPECIAL */
/*E_mail: pajoke@163.com */
/*******************************/
/*
编译时会出现:"*** WARNING L15: MULTIPLE CALL TO SEGMENT"
是交叉调用引起的,可以不用理会.
是可重入的问题(reentrant),可以处理掉,不过不想管它(有点烦)!
最小系统占用资源:Program Size: data=24.0 xdata=0 code=943
*/
#include <REG52.H>
#include "Serial.h"
#define uchar unsigned char
//*********参数定义********
#define BufferLength 0x020 //定义串口字符串的缓冲区大小
#define CmdNum 0x06 //定义系统命令的个数
//*************************
#define CloseSerial SendString("\n>Serial Control System Halt...\n>Serial Close......");
//*************************
uchar S_Buffer[BufferLength];//串口缓冲区
uchar code cmd_tab[CmdNum][5]=//命令最多只能定义(5-1)个字母,否则会出乱
{
"exit",//0━┓这两个
"help",//1━┛不要改
"ghex",//2
};
//******************************
void serial_Int(void) interrupt 4 //串口中断服务子程序
{
if(RI)
{
ES=0;
switch(GetCmd())
{
case 0:CloseSerial;
ES=0;
return;
break;
case 1:SendCmdType();
break;
//***********以下为用户命令的执行区***************/
case 2:SendString("\nInput One Hex Number!\n");
SendHex(GetHex());
break;
//***********以上为用户命令的执行区***************/
default:SendString("\nInvalid command!\n");
break;
}
ES=1;
SendString("\nCsc=>");
}
}
//**************************
void InitSerial() //串口初始化,设波特率要跟据实际情况调整
{
/*
TMOD=TMOD&0x0F;
TMOD=TMOD|0x**;
TL1=0x**,TH1=0x**;
SCON=0x**;
TR1=1;
*/
SCON=0x90;//工作方式2 波特率=fosc/32(软件仿真就无所谓了)
ES=1;
EA=1;
SendString("@Serial Control System Start...\n*C51 serial console---Csc v1.0\n*Author: SPECIAL\n*E_mail:pajoke@163.com\n>Input the command...(Type\"help\"to show CMD type)\nCsc=>");
}
//**************************
uchar GetCmd()//从串口取命令 ,返回值"0xFF"用作报错的保留值
{
uchar i,j;
GetString();
for(i=0;i<CmdNum;i++)
{
for(j=0;j<5;j++)
{
if(S_Buffer[j]!=cmd_tab[i][j])
break;
if((S_Buffer[j]=='\0')&&(cmd_tab[i][j]=='\0'))
return(i);
}
}
return(0xff);
}
//**************************
void SendString(uchar *ptr)//发送字符串
{
do
{
SendChar(*(ptr++));
}while(*(ptr)!='\0');
}
//***************************
void GetString()//读取一字符串
{
uchar i=0;
do
{
S_Buffer[i]=GetChar();
if(S_Buffer[i]=='\r')
{
S_Buffer[i]='\0';
return;
}
if(S_Buffer[i]!='\b')// 用于解决退格键的输入问题
{
SendChar(S_Buffer[i]);
i++;
}
else
{
if(i>0)
{
S_Buffer[i]='\0';
i--;
S_Buffer[i]='\0';
SendChar('\b');
}
else
S_Buffer[i]='\0';
}
}while(i<BufferLength-1);
S_Buffer[i]='\0';
}
//****************************
void SendChar(uchar _char)//发送一个字节
{
F0=ES;//保护ES位
ES=0;
SBUF=_char;
while(!TI);
TI=0;
ES=F0;
}
//****************************
uchar GetChar() //读取一个字节
{
F0=ES;//保护ES位
ES=0;
while(!RI);
RI=0;
ES=F0;
return(SBUF);
}
//****************************
void SendHex(uchar ch) //发送一个字节的16进制数
{ //也适用于发送压缩BCD码
SendCh(ch>>4);
SendCh(ch&0x0f);
}
//****************************
uchar GetHex()
{
uchar temp,ret_num;
FOneErr://第一个错了可以改
do
{
temp=GetChar();
}while(temp=='\b'||temp=='\r');
SendChar(temp);
if(temp>='0'&&temp<='9')
ret_num=(temp-'0')<<4;
else
if(temp>='A'&&temp<='F')
ret_num=(temp-'A'+10)<<4;
else
if(temp>='a'&&temp<='f')
ret_num=(temp-'a'+10)<<4;
else
{
SendString("\nError Format!\n");
return 0;
}
do
{
temp=GetChar();
if(temp=='\b')
{
SendChar('\b');
goto FOneErr;
}
}while(temp=='\b'||temp=='\r');
SendChar(temp);
if(temp>='0'&&temp<='9')
ret_num+=temp-'0';
else
if(temp>='A'&&temp<='F')
ret_num+=temp-'A'+10;
else
if(temp>='a'&&temp<='f')
ret_num+=temp-'a'+10;
else
{
SendString("\nError Format!\n");
return 0;
}
return(ret_num);
}
//****************************
void SendCh(uchar ch)//内部处理函数
{
if(ch>=0&&ch<=9)
ch=ch+'0';
else
ch=ch+'A'-10;
SendChar(ch);
}
//****************************
void SendCmdType()//发送系统所识别的命令列表
{
uchar i;
SendString("\nCommand list:\n");
for(i=0;i<CmdNum;i++)
{
SendChar(' ');
SendChar(i+0x30);
SendChar(':');
SendString(cmd_tab[i]);
SendChar('\n');
}
}
//*****************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -