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

📄 uart.c

📁 8052串口驱动--(包括波特率计算,以及几个内存查看的shell命令)
💻 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 + -