⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hyperterminal.c

📁 串口协议
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -