📄 hyperterminal.c
字号:
j=ADC0831_read();
i = j;
voltage = 5*(i/256); //电压值小数点前的值
voltmp = voltage;
str[0] = voltmp + 0x30;
str[1] = '.';
vol = voltage *10; //乘10将小数点右移一位,强制类型转换
voltmp = vol;
voltmp = voltmp%10;
str[2] = voltmp + 0x30;
vol = voltage *100; //乘100将小数点右移两位,强制类型转换
voltmp = vol;
voltmp = voltmp%10;
str[3] = voltmp + 0x30;
str[4] = 'V';
str[5] = '\r';
str[6] = '\n';
/*
str[0]=(j/100) +0x30;
j=(j % 100);
str[1]=(j/10) +0x30;
j=(j % 10);
str[2]=j +0x30;
str[3]='\n';
*/
SerialSendStr(str);
SerialSendStr("\r\n");
break;
default:
SerialSendStr(" Invalid 'reboot' command: too many arguments\r\n");
break;
}
}
void IR(char argc, const char **argv)
{
argv = argv;
switch(argc)
{
case 1:
// SerialSendStr(gIrArr);
SerialSendStr("\r\n");
break;
default:
SerialSendStr(" Invalid 'ir' command: too many arguments\r\n");
break;
}
}
void WriteE2prom(char argc, const char **argv)
{
//unsigned char i,j;
argv = argv;
switch(argc)
{
case 3:
/*
i=atoi(argv[1]);
j=atoi(argv[2]);
Write2402(i,j);
*/
SerialSendStr("\r\n");
break;
default:
SerialSendStr(" Invalid 'writee2prom' command: too many arguments\r\n");
break;
}
}
void ReadE2prom(char argc, const char **argv)
{
//unsigned char i,j;
//char str[20];
argv = argv;
switch(argc)
{
case 2:
/*
i=atoi(argv[1]);
j=Read2402(i);
str[0]=(j/100) +0x30;
j=(j % 100);
str[1]=(j/10) +0x30;
j=(j % 10);
str[2]=j +0x30;
str[3]='\n';
SerialSendStr(str);
*/
SerialSendStr("\r\n");
break;
default:
SerialSendStr(" Invalid 'reade2prom' command: too many arguments\r\n");
break;
}
}
/*****************************************************************************/
void Help(char argc, const char **argv)
{
char i;
argv = argv; // 不让编译告警
switch(argc)
{
case 1:
for(i = 0; i < MAX_COMMAND_NUM; i++)
{
SerialSendStr(CommandList[i].HelpString);
SerialSendStr("\r\n");
}
SerialSendStr("\r\n");
break;
default:
SerialSendStr(" Invalid 'help' command: too many arguments\r\n");
break;
}
}
void Prompt(char argc, const char **argv)
{
switch(argc)
{
case 2:
if(strlen(argv[1]) >= MAX_PROMPT_BUFFER_SIZE)
{
SerialSendStr(" Warnning:Your argument is too long!\r\n\r\n");
break;
}
memcpy(PromptBuffer,argv[1],MAX_PROMPT_BUFFER_SIZE);
SerialSendStr(" Prompt is chagned to \"");
sprintf(&SerialBuffer[0],"%s\"\r\n\r\n",&PromptBuffer[0]);
SerialSendStr(&SerialBuffer[0]);
break;
default:
SerialSendStr(" Invalid 'prompt' command\r\n");
break;
}
}
void Clear(char argc, const char **argv)
{
argv = argv;
switch(argc)
{
case 1:
SerialSendStr(CLEARSCREEN);
break;
default:
SerialSendStr(" Invalid 'clear' command\r\n");
break;
}
}
void Reboot(char argc, const char **argv)
{
argv = argv;
switch(argc)
{
case 1:
(*(void(*)())0)();
break;
default:
SerialSendStr(" Invalid 'reboot' command: too many arguments\r\n");
SerialSendStr(" Usage:\r\n");
SerialSendStr(" reboot\r\n");
break;
}
}
/*****************************************************************************/
void InitHyperTerminal(void)
{
TMOD |= 0x21; /* timer1, mode 2, 8 bit reload */
SCON = 0x50; /* serial mode 1, 8 bit uart, enable receive */
PCON = 0x80; /* SMOD = 1, double baud */
TH1 = 0xFF; /* baud = 57600, fosc = 11.0592MHZ */
TL1 = 0xFF;
RI = 0; /* clear receive flag */
TI = 0; /* clear send flag */
TR1 = 1; /* start timer1 */
ES = 1; /* enable serial interrupt */
EA = 1; /* enable all interrupt */
IT1=1;
TR0=1;
EX1=0;
XBYTE[BUZZERADDR]=0x00;
CursorPosion = 0;
ExecCommandFlag = 0;
memset(&SerialBuffer[0],'\0',MAX_SERIAL_BUFFER_SIZE); //清除缓冲区
memcpy(&PromptBuffer[0],"TW>>",MAX_PROMPT_BUFFER_SIZE); //命令提示行为"TW>>"
// SerialSendStr(F_LIGHTGREEN);
// SerialSendStr(B_BLACK);
SerialSendStr(CLEARSCREEN);
SerialSendStr("-----------------------------\r\n");
SerialSendStr(" ToWin Hyper Terminal,by yurongcheng\r\n");
SerialSendStr(" http://www.towintec.cn \r\n");
SerialSendStr("-----------------------------\r\n");
SerialSendStr("\r\n");
SerialSendStr(&PromptBuffer[0]);
}
void SerialSendByte(char dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
void SerialSendStr(char *str)
{
while(*str != '\0') //发送不为空,ASCI码的null
{
SerialSendByte(*str);
str++;
}
}
/*******************************************************************************
** 串行中断服务程序
**输入:
**描述:如果有串口接收中断标志,代表收到一个字符,清RI标志,
** 缓存至局部变量SbufTemp,判断字符,退格键,删除键,则将缓冲区指针减一,
** 再更新屏幕显示,回车键,代表输入结束,置全局变量标志,有待解析字符,
** 其余的则就是用户输入的有效字符了,注意,这里有个缓冲区溢出判断,很关键。
*******************************************************************************/
void SerialInterrupt(void) interrupt 4 using 3
{
char SbufTemp;
if(RI)
{
RI = 0;
SbufTemp = SBUF;
switch(SbufTemp) //在switch-case语句中,多个case可以共用一条执行语句
{
case 0x08: //8是退格
case 0x06: //应答
case 0x07: //7定义为bell就是控制发声的,用于有些需要报警或响铃的场合
case 0x7E: // ~ 符号
case 0x7F: //删除
if(CursorPosion > 0)
{
CursorPosion--;
SerialSendByte(0x08);
SerialSendByte(' ');
SerialSendByte(0x08);
}
SerialBuffer[CursorPosion] = '\0'; //赋值0,即(null)清除缓冲区
break;
case '\r': //回车
case '\n': //回车换行
case '\0': //为空
SerialSendByte('\r');
SerialSendByte('\n');
ExecCommandFlag = 1;
break;
case '\t': //横向跳到下一制表位 即tab键
break;
default:
if(CursorPosion < MAX_SERIAL_BUFFER_SIZE)
{
SerialBuffer[CursorPosion] = SbufTemp;
SerialSendByte(SbufTemp);
CursorPosion++;
}
else
{
CursorPosion = 0;
memset(&SerialBuffer[0],'\0',MAX_SERIAL_BUFFER_SIZE);
SerialSendStr("\r\n Warnning:Your command string is too long!\r\n\r\n");
SerialSendStr(&PromptBuffer[0]);
}
break;
}
}
}
/*******************************************************************************
**
**
**描述:这段代码是分析参数,即将用户输入的字符串比如“prompt 8051>>”分析出参数的个
** 数,以及将每个参数分别存在数组里,一个二维数组,这段代码是借鉴VIVI里面的,
** 涉及到编译原理里的一些知识。
**
**形参描述:
** char **argv:指向char *的指针,指向字符指针的指针
** argc - 1是参数的数目,第一个参数是程序名,所以argc至少有1,如果argc大于1的话,说明有参数输入
** argv是参数列表,argv[1]是第一个参数的名字
**
typedef enum {
PS_WHITESPACE, //空白
PS_TOKEN, //使能
PS_STRING, //字符串
PS_ESCAPE //退出
}PARSESTATE;
//枚举是指将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。
*******************************************************************************/
//ParseArgs(buf, &argc, argv, &resid);
void ParseArgs(char *argstr,char *argc_p,char **argv, char **resid)
{
char argc = 0;
char c;
PARSESTATE stackedState,lastState = PS_WHITESPACE;
while ((c = *argstr) != 0) //接收缓冲区不为空
{
PARSESTATE newState; //新的状态
if (c == ';' && lastState != PS_STRING && lastState != PS_ESCAPE) //为c语言语句,且部位字符串状态和退出状态
break;
if (lastState == PS_ESCAPE) //最近状态为取消状态
{
newState = stackedState;
}
else if (lastState == PS_STRING) //最近状态为字符串状态
{
if (c == '"')
{
newState = PS_WHITESPACE; //字符串完成,新状态为空白状态
*argstr = 0;
}
else
{
newState = PS_STRING; //否则新状态为字符串状态
}
}
else if ((c == ' ') || (c == '\t')) //命令与后面的参数间隔''空格或'\t'(横向跳到下一制表位置tab键.)
{
*argstr = 0; //
newState = PS_WHITESPACE; //又来了一个新的参数 ,清除状态为空白
}
else if (c == '"') //碰到双引号则为字符串状态
{
newState = PS_STRING; //新的状态为字符串
*argstr++ = 0;
argv[argc++] = argstr;
}
else if (c == '\\') // 反斜线符"\",不知道是什么意思?
{
stackedState = lastState; //保留最近状态
newState = PS_ESCAPE; //新状态改为取消状态
}
else
{
if (lastState == PS_WHITESPACE) //如果状态为空白
{
argv[argc++] = argstr; //argc先赋值后++
}
newState = PS_TOKEN; //新状态为占用状态
}
lastState = newState; //最后状态为新的状态
argstr++; //继续检测后面的字符
}
argv[argc] = NULL; //清空后面的指针
if (argc_p != NULL) //指针地址不为空
{
*argc_p = argc; //help命令参数为1
}
if (*argstr == ';')
{
*argstr++ = '\0';
}
*resid = argstr; //缓冲区边缘为argstr,是第一个参数后的缓冲区地址。
}
/*******************************************************************************
** 执行命令函数
**输入:串行缓冲区
**
**函数描述:
********************************************************************************
原型:extern int stricmp(char *s1,char * s2);
用法:#include <string.h>
功能:比较字符串s1和s2,但不区分字母的大小写。
说明:strcmpi是到stricmp的宏定义,实际未提供此函数。
当s1<s2时,返回值<0
当s1=s2时,返回值=0
当s1>s2时,返回值>0
********************************************************************************
原型:extern int strcmp(char *s1,char * s2,int n);
用法:#include <string.h>
功能:比较字符串s1和s2的前n个字符。
说明:
当s1<s2时,返回值<0
当s1=s2时,返回值=0
当s1>s2时,返回值>0
********************************************************************************
原型:extern void *memset(void *buffer, int c, int count);
用法:#include <string.h>
功能:把buffer所指内存区域的前count个字节设置成字符c。
说明:返回指向buffer的指针。
********************************************************************************
原型:extern int strlen(char *s);
用法:#include <string.h>
功能:计算字符串s的长度
说明:返回s的长度,不包括结束符NULL。
int n1 = strlen(ghost); //字符数组中字符的实际长度
int n2 = strlen(str); //指针指向的字符数组的实际长度
int n3 = strlen("galloping"); //字符串中字符的实际长度
int n4 = sizeof(ghost); //字符数组分配空间大小
int n5 = sizeof(str); //指针分配的空间大小
int n6 = sizeof("galloping"); //字符串分配空间大小,注意最后一位要加上'\0'
********************************************************************************
char * line[5]; //指针数组
表示line是一个5个元素的数组,每个元素是一个指向字符型数据的一个指针。若设指向的字符型数据
(字符串)分别是"ONE"、"TWO"、…、"FIVE",则数组line的结构如图10-11所示。
而:char (*line)[5];
表示line是指向一个长度为5的字符数组的指针。
*******************************************************************************/
void ExecCommand(char *buf)
{
char argc,*argv[8],*resid,i;
COMMAND *Command = 0;
unsigned char flg=0;
while(*buf)
{
memset(argv,0,sizeof(argv)); //将指针数组清零,每个指针指向的地址都清除了。
ParseArgs(buf, &argc, argv, &resid); //命令参数分析,参数个数为argc;参数内容放在argv[8]指针数组指向的地址内。
//每个参数一个地址
if(argc > 0)
{
for(i = 0; i < MAX_COMMAND_NUM; i++) //循环比较命令,如果查到就跳出循环,执行命令;否则返回错误。
{
Command = &CommandList[i]; // X:0000H PUBLIC CommandList 导致第一条命令总是有问题。
if(strncmp(Command->CommandName,argv[0],strlen(argv[0])) == 0)//比较命令
// if(strcmp(Command->CommandName,argv[0]) == 0)
{
flg = 1;
break;
}
else
{
flg = 0;
// Command = 0;
}
}
if(flg/*Command*/ == 0)
{
SerialSendStr(" Could not found \"");
SerialSendStr(argv[0]);
SerialSendStr("\" command\r\n");
SerialSendStr(" If you want to konw available commands, type 'help'\r\n\r\n");
}
else
{
Command->CommandFunc(argc,argv); //执行具体功能函数
}
}
buf = resid;
}
}
/*******************************************************************************
** 运行超级终端函数
**输入:执行命令标示ExecCommandFlag
**
*******************************************************************************/
void RunHyperTerminal(void)
{
if(ExecCommandFlag) //如果有命令需要执行
{
ExecCommand(&SerialBuffer[0]); //执行命令,传递串行缓冲数组地址
SerialSendStr(&PromptBuffer[0]); //发送串行提示字符,传递串行提示符缓冲区地址
memset(&SerialBuffer[0],'\0',MAX_SERIAL_BUFFER_SIZE); //清空缓冲区,没什么可以解释的,为了下次正确执行必须这样做
CursorPosion = 0; //清除串行数据计数变量
ExecCommandFlag = 0; //清除命令标识
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -