📄 uart.c
字号:
#include <reg51.h>
#include <stdio.h>
#define SYSCLK 12000000
#define BAUDRATE 4800
//收发缓冲区长度
#define LenTxBuf 1024 //不要太小
#define LenRxBuf 32
#define MaxLenStr 80 //显示字符串的最大长度
#define TABNum 4 //TAB键移动长度
unsigned char RxBuf[LenRxBuf], TxBuf[LenTxBuf]; //收发缓冲区实体
unsigned char *rRxBuf, *wRxBuf, *rTxBuf, *wTxBuf; //收发缓冲区读写指针
unsigned char Cmd[16]; //分析处理后的命令
bit TIflag = 1; //发送标志
bit RIflag = 0; //接收标志
/****************************************************************************************
* 功能: 串口初始化,缓冲区初始化
* 参数: 无
****************************************************************************************/
void uartInit(void)
{
SCON = 0x50; //方式1
PCON = 0x80; //SMOD=1;
TMOD = 0x20; //定时器1为自动重装载的8 位计数器/定时器
TH1 = 256 - (SYSCLK/12/16/BAUDRATE);
TL1 = TH1;
TR1 = 1; //启动定时器1
rTxBuf = TxBuf; //串口缓冲区初始化
wTxBuf = TxBuf;
rRxBuf = RxBuf;
wRxBuf = RxBuf;
EA = 1;
ES = 1;
}
/****************************************************************************************
* 功能: 串口中断服务程序
* 参数: 无
****************************************************************************************/
void uartISR(void) interrupt 4
{
unsigned char *t;
if (TI)
{
TI = 0;
if (rTxBuf == wTxBuf) //TxBuf为空
{
TIflag = 1;
return;
}
SBUF = *rTxBuf;
rTxBuf++;
if (rTxBuf == TxBuf + LenTxBuf)
rTxBuf = TxBuf;
}
if (RI)
{
RI = 0;
t = wRxBuf;
t++;
if (t == RxBuf + LenRxBuf)
t = RxBuf;
if (t == rRxBuf) //RxBuf满
{
RIflag = 1;
return;
}
*wRxBuf = SBUF;
if (*(wRxBuf - 1) == '\r') // 判断接收到回车否
{
RIflag = 1;
return;
}
else
{
wRxBuf = t;
}
}
}
/****************************************************************************************
* 功能: 显示单个字符
* 参数: 单个字符
****************************************************************************************/
void PrintChar(unsigned char ch)
{
unsigned char *t;
ES = 0;
if (TIflag)
{
TIflag = 0;
TI = 1;
}
t = wTxBuf;
t++;
if (t == TxBuf + LenTxBuf)
t = TxBuf;
if (t == rTxBuf) //TxBuf满
{
ES = 1;
return;
}
*wTxBuf = ch;
wTxBuf = t;
ES = 1;
}
/****************************************************************************************
* 功能: 显示字符串
* 参数: 字符串指针
****************************************************************************************/
void PrintStr(unsigned char *str)
{
int i;
unsigned char j;
unsigned char ch;
EA = 0;
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);
}
EA=1;
}
/****************************************************************************************
* 功能: 从串口缓冲区读一个字节数据
* 参数: 单个字符指针
****************************************************************************************/
bit mygetch(unsigned char *ch)
{
ES = 0;
if (rRxBuf == wRxBuf) //RxBuf为空
{
ES = 1;
return 0;
}
*ch = *rRxBuf;
rRxBuf++;
if (rRxBuf == RxBuf + LenRxBuf)
rRxBuf = RxBuf;
ES = 1;
return 1;
}
/****************************************************************************************
* 功能: 读取串口缓冲区的数据
* 参数: 字符串指针
****************************************************************************************/
bit readRxBuf(unsigned char *str)
{
unsigned char ch, i;
EA = 0;
if (RIflag)
{
RIflag = 0;
}
if (rRxBuf == wRxBuf) //RxBuf为空
{
EA = 1;
return 0;
}
for (i=0; i<LenRxBuf; i++)
{
if (mygetch(&ch))
{
if (ch == '\r')
{
*str = '\0';
break;
}
else
{
*str = ch;
str++;
}
}
else
{
return 0;
}
}
rRxBuf = RxBuf;
wRxBuf = RxBuf;
EA = 1;
return 1;
}
/****************************************************************************************
* 功能: 去除接收缓冲区字符串ComBuf中的空格,并处理退格,形成命令字符串cmd
* 参数: ComBuf--串口缓冲区字符串指针
* cmd--命令字符串指针
****************************************************************************************/
void parse(unsigned char *ComBuf, unsigned char *cmd)
{
int i, j;
for (i=0, j=0; 1; i++)
{
if (ComBuf[i] == '\0') //结束
{
cmd[j] = '\0';
break;
}
if (ComBuf[i] == ' ') //空格
{
continue;
}
else
if (ComBuf[i] == 0x08) //退格
{
j--;
}
else
{
cmd[j++] = ComBuf[i];
}
}
}
/****************************************************************************************
* 功能: 显示的欢迎信息
* 参数: 无
****************************************************************************************/
void Welcome(void)
{
PrintStr("\n\n\n\n");
PrintStr("\n/************************* C51 shell ***********************************/\n");
PrintStr("\n Welcome to the command mode!\n");
PrintStr("\n/**********************************************************************/\n");
}
/****************************************************************************************
* 功能: 显示命令行提示符
* 参数: 无
****************************************************************************************/
void CmdLine(void)
{
PrintStr("\n\n>");
}
/****************************************************************************************
* 功能: 命令不匹配时的功能函数
* 参数: 无
****************************************************************************************/
void CmdError(void)
{
PrintStr("Command error!\nPlease input 'help' or '?' to get for help.\n");
}
/****************************************************************************************
* 功能: D命令功能函数,读memeory内容
* CmdDI(): 读内部RAM
* CmdDC(): 读程序存储器ROM
* CmdDX(): 读外部RAM
* 参数: 无
****************************************************************************************/
void CmdDI(void);
void CmdDC(void);
void CmdDX(void);
void CmdD(void)
{
switch (Cmd[1])
{
case 'i' :
CmdDI();
break;
case 'c' :
CmdDC();
break;
case 'x' :
CmdDX();
break;
default :
CmdError();
}
}
void CmdDI(void)
{
int i, j;
unsigned char idata * pchar; // memory access pointer
unsigned char ch;
unsigned char buffer[100];
if (Cmd[4] != '\0')
{
CmdError();
return;
}
for (i=2; i<=3; i++)
{
if ((Cmd[i] >= '0' && Cmd[i] <='9') || (Cmd[i] >= 'a' && Cmd[i] <='f')
|| (Cmd[i] >= 'A' && Cmd[i] <='F'))
{
if ((Cmd[i] >= 'a' && Cmd[i] <='f') || (Cmd[i] >= 'A' && Cmd[i] <='F'))
Cmd[i] += 9;
}
else
{
CmdError();
return;
}
}
Cmd[2] = (Cmd[2] << 4) & 0xf0;
Cmd[3] = Cmd[3] & 0x0f;
ch = Cmd[2] | Cmd[3];
pchar = ch;
for (j=0; j<8; j++)
{
sprintf(buffer, "0x%02x: ", (unsigned) ch);
PrintStr(buffer);
for (i = 0; i < 16; i++)
{
sprintf(buffer, "%02x ", (unsigned) *pchar++);
PrintStr(buffer);
}
PrintStr("\n");
ch = (ch + 16) % 256;
}
}
void CmdDC()
{
int i, j;
unsigned char code * pchar; // memory access pointer
unsigned int ch;
unsigned char buffer[100];
if (Cmd[6] != '\0')
{
CmdError();
return;
}
for (i=2; i<=5; i++)
{
if ((Cmd[i] >= '0' && Cmd[i] <='9') || (Cmd[i] >= 'a' && Cmd[i] <='f')
|| (Cmd[i] >= 'A' && Cmd[i] <='F'))
{
if ((Cmd[i] >= 'a' && Cmd[i] <='f') || (Cmd[i] >= 'A' && Cmd[i] <='F'))
Cmd[i] += 9;
}
else
{
CmdError();
return;
}
}
Cmd[2] = (Cmd[2] << 4) & 0xf0;
Cmd[3] = Cmd[3] & 0x0f;
Cmd[4] = (Cmd[4] << 4) & 0xf0;
Cmd[5] = Cmd[5] & 0x0f;
Cmd[2] = Cmd[2] | Cmd[3];
Cmd[4] = Cmd[4] | Cmd[5];
ch = (unsigned int)Cmd[2] & 0x00ff;
ch = (ch << 8) | ((unsigned int)Cmd[4] & 0x00ff);
pchar = ch;
for (j=0; j<8; j++)
{
sprintf(buffer, "0x%04x: ", (unsigned) ch);
PrintStr(buffer);
for (i = 0; i < 16; i++)
{
sprintf(buffer, "%02x ", (unsigned) *pchar++);
PrintStr(buffer);
}
PrintStr("\n");
ch = (ch + 16) % 0xffff;
}
}
void CmdDX()
{
int i, j;
unsigned char xdata * pchar; // memory access pointer
unsigned int ch;
unsigned char buffer[100];
if (Cmd[5] != '\0')
{
CmdError();
return;
}
for (i=2; i<=4; i++)
{
if ((Cmd[i] >= '0' && Cmd[i] <='9') || (Cmd[i] >= 'a' && Cmd[i] <='f')
|| (Cmd[i] >= 'A' && Cmd[i] <='F'))
{
if ((Cmd[i] >= 'a' && Cmd[i] <='f') || (Cmd[i] >= 'A' && Cmd[i] <='F'))
Cmd[i] += 9;
}
else
{
CmdError();
return;
}
}
Cmd[2] = Cmd[2] & 0x0f;
Cmd[3] = (Cmd[3] << 4) & 0xf0;
Cmd[4] = Cmd[4] & 0x0f;
Cmd[3] = Cmd[3] | Cmd[4];
ch = (unsigned int)Cmd[2] & 0x00ff;
ch = (ch << 8) | ((unsigned int)Cmd[3] & 0x00ff);
pchar = ch;
for (j=0; j<8; j++)
{
sprintf(buffer, "0x%03x: ", (unsigned) ch);
PrintStr(buffer);
for (i = 0; i < 16; i++)
{
sprintf(buffer, "%02x ", (unsigned) *pchar++);
PrintStr(buffer);
}
PrintStr("\n");
ch = (ch + 16) % 0xfff;
}
}
/****************************************************************************************
* 功能: M命令功能函数,修改memory内容
* CmdMI(): 修改内部RAM
** CmdMX(): 修改外部RAM
* 参数: 无
****************************************************************************************/
void CmdMI();
void CmdMX();
void CmdM()
{
switch (Cmd[1])
{
case 'i' :
CmdMI();
break;
case 'x' :
CmdMX();
break;
default :
CmdError();
break;
}
}
void CmdMI()
{
int i;
unsigned char idata * pchar; // memory access pointer
unsigned char ch1, ch2, ch3;
if (Cmd[8] != '\0')
{
CmdError();
return;
}
for (i=2; i<=7; i++)
{
if ((Cmd[i] >= '0' && Cmd[i] <='9') || (Cmd[i] >= 'a' && Cmd[i] <='f')
|| (Cmd[i] >= 'A' && Cmd[i] <='F'))
{
if ((Cmd[i] >= 'a' && Cmd[i] <='f') || (Cmd[i] >= 'A' && Cmd[i] <='F'))
Cmd[i] += 9;
}
else
{
CmdError();
return;
}
}
Cmd[2] = (Cmd[2] << 4) & 0xf0;
Cmd[3] = Cmd[3] & 0x0f;
ch1 = Cmd[2] | Cmd[3];
Cmd[4] = (Cmd[4] << 4) & 0xf0;
Cmd[5] = Cmd[5] & 0x0f;
ch2 = Cmd[4] | Cmd[5];
Cmd[6] = (Cmd[6] << 4) & 0xf0;
Cmd[7] = Cmd[7] & 0x0f;
ch3 = Cmd[6] | Cmd[7];
for (pchar=ch1; pchar<=ch2; pchar++)
{
*pchar = ch3;
}
PrintStr("Momery modify successful!\n");
}
void CmdMX()
{
int i;
unsigned char xdata * pchar; // memory access pointer
unsigned int ch1, ch2;
unsigned char ch3;
if (Cmd[10] != '\0')
{
CmdError();
return;
}
for (i=2; i<=9; i++)
{
if ((Cmd[i] >= '0' && Cmd[i] <='9') || (Cmd[i] >= 'a' && Cmd[i] <='f')
|| (Cmd[i] >= 'A' && Cmd[i] <='F'))
{
if ((Cmd[i] >= 'a' && Cmd[i] <='f') || (Cmd[i] >= 'A' && Cmd[i] <='F'))
Cmd[i] += 9;
}
else
{
CmdError();
return;
}
}
Cmd[2] = Cmd[2] & 0x0f;
Cmd[3] = (Cmd[3] << 4) & 0xf0;
Cmd[4] = Cmd[4] & 0x0f;
Cmd[3] = Cmd[3] | Cmd[4];
ch1 = (unsigned int)Cmd[2] & 0x00ff;
ch1 = (ch1 << 8) | ((unsigned int)Cmd[3] & 0x00ff);
Cmd[5] = Cmd[5] & 0x0f;
Cmd[6] = (Cmd[6] << 4) & 0xf0;
Cmd[7] = Cmd[7] & 0x0f;
Cmd[6] = Cmd[6] | Cmd[7];
ch2 = (unsigned int)Cmd[5] & 0x00ff;
ch2 = (ch2 << 8) | ((unsigned int)Cmd[6] & 0x00ff);
Cmd[8] = (Cmd[8] << 4) & 0xf0;
Cmd[9] = Cmd[9] & 0x0f;
ch3 = Cmd[8] | Cmd[9];
for (pchar=ch1; pchar<=ch2; pchar++)
{
*pchar = ch3;
}
PrintStr("Momery modify successful!\n");
}
/****************************************************************************************
* 功能: 帮助命令
* 参数: 无
****************************************************************************************/
void CmdH(void)
{
if ((Cmd[0] == '?' && Cmd[1] == '\0')
|| (Cmd[1] == 'e' && Cmd[2] == 'l' && Cmd[3] == 'p' && Cmd[4] == '\0'))
{
PrintStr(" di [adr] 读idata内容,adr为2位16进制数\n");
PrintStr(" dc [adr] 读code内容,adr为4位16进制数\n");
PrintStr(" dx [adr] 读xdata内容,adr为3位16进制数\n");
PrintStr(" mi [adr] [adr] [data] 修改idata内容,adr,data为2位16进制数\n");
PrintStr(" mc [adr] [adr] [data] 修改code内容,adr为4位16进制数\n");
PrintStr(" mx [adr] [adr] [data] 修改xdata内容,adr为3位16进制数\n");
PrintStr(" help / ? 列出帮助信息\n");
}
else
CmdError();
}
main()
{
unsigned char combuf[32];
uartInit();
Welcome();
Cmd[0] = '?';
Cmd[1] = '\0';
CmdH();
CmdLine();
while(1)
{
while(!RIflag);
if(readRxBuf(combuf))
{
parse(combuf, Cmd);
switch(Cmd[0])
{
case 'd':
CmdD();
break;
case 'm':
CmdM();
break;
case 'h':
case '?':
CmdH();
break;
default:
CmdError();
break;
}
CmdLine();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -