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

📄 ht_c51s.c

📁 本软件是单片机通讯的主程序
💻 C
字号:
#include "config.h"
#include "reg924.h"

// buffer define
//串口接收循环缓冲
extern u8_t idata recvbuf[SBUFSIZE];
extern u8_t recvtail;
extern u8_t recvstart;

//串口发送循环缓冲
extern u8_t idata sendbuf[SBUFSIZE];
extern u8_t sendtail;
extern u8_t sendstart;

//命令缓冲
u8_t	cmdbuf[PBUFSIZE];
s8_t	cmdlen;

//解析后的命令参数
s8_t PortNo, PinNo;
u16_t AbsAddr;
u8_t AbsVal;
u8_t CommandCode;

#define LOGO    "C51 Comm test V1.0"

void main()
{
	// initial GPIO at here
	// P27 -> 准双向口
	P0M1 = 0x00; P0M2 = 0x00;
	P1M1 = 0x00; P1M2 = 0x00;
	P2M1 = 0x00; P2M2 = 0x80;
	// P27 = 0;
	P27 = RS485_RL;

	Timer0_Init();
	SerialInit();

	EA = 1;

	// print LOGO
	Identify();
	CmdBufReset();

	while(1)
	{
		if(GetInput() == RECV_FINISH)
		{
			PrintReturn();
			ParseCmdSet();
		}
	}
}

//=================================================
//命令缓冲初始化
//=================================================
void Identify()
{
	PrintString(LOGO);
	SerialStart();
}


//=================================================
//回车,换行
//=================================================
void PrintReturn()
{
	PrintUnit(0xd);
	PrintUnit(0xa);
	PrintUnit('\\');
	PrintUnit('>');
}


//=================================================
//显示最小单元
//=================================================
void PrintUnit(u8_t xch)
{
	if((sendtail != (1+sendstart)) && (sendtail != (sendstart+1-SBUFSIZE)))//buffer not full
	{
		sendbuf[sendstart] = xch;
		sendstart ++;
		if(sendstart >= SBUFSIZE)
		{
			sendstart = 0;
		}
		SerialStart();
	}
}


//=================================================
//显示8位的hex数字,高位不足补0
//=================================================
u8_t PrintHexNumber(u8_t xnum)
{
	u8_t xshow, outchar;
	s8_t i;

	i = 1;
	while(i >= 0)
	{
		xshow = (xnum >> (i*4)) & 0xf;
		if((xshow >= 0) && (xshow <= 9)){
			outchar = xshow + '0';
		}
		else if((xshow >= 0xa) && (xshow <= 0xf)){
			outchar = xshow - 0xa + 'A';
		}
		else{
			return 0;
		}
		PrintUnit(outchar);
		i --;
	}
	return 1;
}


//=================================================
//显示字符串
//=================================================
void PrintString(u8_t *str)
{
	u8_t i = 0;

	while(str[i] != 0x00)
	{
		PrintUnit(str[i]);
		i ++;
	}
	PrintReturn();
}

//=================================================
//命令缓冲与命令码初始化
//=================================================
void CmdBufReset()
{
	s8_t i;
	//命令缓冲初始化
	cmdlen = 0;
	for(i = 0; i < PBUFSIZE; i ++)
	{
		cmdbuf[i] = 0x0;
	}
	//命令初始化
	AbsAddr = 0;
	AbsVal  = 0;
	CommandCode = 0;
	PortNo = -1;
	PinNo = -1;
}

//=================================================
//读端口函数
//=================================================
u8_t PortRead(s8_t port, s8_t pin)
{
	u8_t val = 0;
	switch(port)
	{
	case 0:
		val = P0;
		break;
	case 1:
		val = P1;
		break;
	case 2:
		val = P2;
		break;
	case 3:
		val = P3;
		break;
	}
	if(pin == -1){
		return val;
	}else{
		return ((val >> pin) & 1);
	}
}

//=================================================
//写端口函数
//=================================================
u8_t PortWrite(s8_t port, s8_t pin, u8_t val)
{
	switch(port)
	{
	case 0:
		if(pin == -1) P0 = val;
		else{
			if(val == 1)
				P0 = P0 | (1 << pin);
			else
				P0 = P0 & (~(1 << pin));
		}
		break;
	case 1:
		if(pin == -1) P1 = val;
		else{
			if(val == 1)
				P1 = P1 | (1 << pin);
			else
				P1 = P1 & (~(1 << pin));
		}
		break;
	case 2:
		if(pin == -1) P2 = val;
		else{
			if(val == 1)
				P2 = P2 | (1 << pin);
			else
				P2 = P2 & (~(1 << pin));
		}
		break;
	case 3:
		if(pin == -1) P3 = val;
		else{
			if(val == 1)
				P3 = P3 | (1 << pin);
			else
				P3 = P3 & (~(1 << pin));
		}
		break;
	default:
		return -1;
	}
	return 0;
}



//=================================================
//从串口接收缓冲中取数据到命令缓冲,同时回传
//=================================================
u8_t GetInput()
{
	u8_t tmp;

	while(recvtail != recvstart)
	{
		tmp = recvbuf[recvtail];
		recvtail ++;
		if(recvtail == SBUFSIZE) recvtail = 0;

		PrintUnit(tmp);

		if(tmp == 0x8)//退格键处理
		{
			cmdlen = cmdlen - 1;
                        return 0;
		}

		if((tmp == 0xd) || (tmp == 0xa))//回车换行处理
		{
			return RECV_FINISH;
		}
		cmdbuf[cmdlen] = tmp;
		cmdlen ++;
	}
	return RECV_WAITING;
}




s8_t GetCharValue(u8_t xfer)
{
	s8_t val;
	val = -1;
	if((xfer >= '0') && (xfer <= '9'))
	{
		val = xfer - '0';
	}
	else if((xfer >= 'a') && (xfer <= 'f'))
	{
		val = xfer - 'a' + 10;
	}
	else if((xfer >= 'A') && (xfer <= 'F'))
	{
		val = xfer - 'A' + 10;
	}
	return val;
}



//=================================================
//命令解析:包括(读/写,外部地址/内部地址
//=================================================
s8_t ParseCommand(s8_t idx)
{
	s8_t i;
	i = idx;

	while(cmdbuf[i] != 0x0)
	{
		switch(cmdbuf[i])
		{
		case 'R':
		case 'r':
			CommandCode |= CMD_READ;
			i ++;
			break;
		case 'W':
		case 'w':
			CommandCode |= CMD_WRITE;
			i ++;
			break;
		case 'I':
		case 'i':
			CommandCode |= ADDR_IADDR;
			i ++;
			break;
		case 'X':
		case 'x':
			CommandCode |= ADDR_XADDR;
			i ++;
			break;
		case 0x20:
			i ++;
			return i;
		default:
			PrintUnit('@');
			PrintHexNumber(cmdbuf[i]);
			return -1;
		}
	}
	if(i == 0)
	{
//		PrintUnit('#');
		return -1;
	}
	return i;
}

//=================================================
//参数1解析:参数1包括 目标类型(端口, 地址)
//=================================================
s8_t ParseParam1(s8_t idx)
{
	s8_t i, j, parstart;
	s8_t val;
	u16_t addr;

	j = 0;
	addr = 0;
	i = idx;
	while(cmdbuf[i] == 0x20) i ++;
	parstart = i;

	while(cmdbuf[i] != 0x0)
	{
		switch(cmdbuf[i])
		{
		case 'P':
		case 'p':
			CommandCode |= ADDR_PORT;
			i ++;
			break;
		case 0x20:
			i ++;
			AbsAddr = addr;
			return i;
		default:
			addr = addr << 4;
			val = GetCharValue(cmdbuf[i]);
			if(val == -1)
			{
				PrintUnit('+');
				return ERROR_INPUT;
			}
			if(CommandCode & ADDR_PORT)
			{
				switch(j)
				{
				case 0:
					PortNo = val;
					j ++;
					break;
				case 1:
					PinNo = val;
					j ++;
					break;
				default:
					PrintUnit('-');
					PrintHexNumber(cmdbuf[i]);
					return ERROR_INPUT;
				}
			}
			else
			{
				addr += val;
			}
			i ++;
			break;
		}
	}
	AbsAddr = addr;
	if((AbsAddr == 0x0) && ((CommandCode & ADDR_PORT) == 0))
	{
		PrintUnit('*');
		return ERROR_INPUT;
	}
	return i;
}

//=================================================
//参数2解析:参数2包括:赋值 或 读取的数量
//=================================================
s8_t ParseParam2(s8_t idx)
{
	s8_t i, parstart;
	s8_t ret;
	u8_t val;

	i = idx;
	val = 0;
	while(cmdbuf[i] == 0x20) i ++;
	parstart = i;

	while((i < (parstart + 2)) && (cmdbuf[i] != 0x0))
	{
		val = val << 4;

		ret = GetCharValue(cmdbuf[i]);
		if(ret == -1)
		{
			return ERROR_INPUT;
		}
		val += ret;
		i ++;
	}

	if(i == parstart)
	{
		if(CommandCode & CMD_READ)
			AbsVal = 1;
		else if(CommandCode & ADDR_PORT)
		{
			return ERROR_INPUT;
		}
	}else
		AbsVal = val;
	return i;
}

//=================================================
//命令执行
//=================================================
void ExecuteCmd()
{
	u8_t val;
	u16_t addr;
	s8_t i;
	unsigned char xdata *xin;
        unsigned char idata *iin;

	i = 0;

	if(CommandCode == 0) return;
	if(CommandCode & ADDR_PORT)
	{//读写端口
		if(PortNo == -1)return;
		if(PinNo > 7) return;
		if(CommandCode & CMD_READ)
		{
			val = PortRead(PortNo,PinNo);
			PrintHexNumber(val);
		}
		else
		{
			PortWrite(PortNo,PinNo,AbsVal);
			val = PortRead(PortNo,PinNo);
			if(val == AbsVal){
				PrintString("set io ok.");
			}
			else{
				PrintString("set io err.");
			}
		}
	}
	else
	{//读写绝对地址
		if((CommandCode & ADDR_IADDR) && (AbsAddr < 0x80))
		{
			PrintUnit('~');
			PrintHexNumber(AbsAddr);
			//PrintString("Addr low than 0x80");
			return ;
		}
		if(CommandCode & CMD_READ){
			while(i < AbsVal)
			{
				addr = AbsAddr + i;
				if(CommandCode & ADDR_IADDR){
					val = *((volatile unsigned char idata*)addr);
				}
				else if(CommandCode & ADDR_XADDR){
					val = *((volatile unsigned char xdata*)addr);
				}

				PrintHexNumber(val);
				PrintUnit(0x20);
				if(((i+1)%8) == 0) PrintReturn();
				i ++;
			}
		}else{
			addr = AbsAddr;
			if(CommandCode & ADDR_IADDR){
				iin = (volatile unsigned char idata *)addr;
				*iin = AbsVal;
				if(*iin == AbsVal){
					PrintString("set addr ok.");
				}else{
					PrintString("set addr err.");
				}
			}else{
				xin = (volatile unsigned char xdata *)addr;
				*xin = AbsVal;
				if(*xin == AbsVal){
					PrintString("set addr ok.");
				}else{
					PrintString("set addr err.");
				}
			}
		}
	}
}


//=================================================
//整条命令解析处理函数
//=================================================
s8_t ParseCmdSet()
{
	s8_t i = 0;

	i = ParseCommand(i);
	if(i == ERROR_INPUT)
	{
		PrintString("err command");
		CmdBufReset();
		PrintReturn();
		return ERROR_INPUT;
	}

	i = ParseParam1(i);
	if(i == ERROR_INPUT)
	{
		PrintString("err param 1");
		CmdBufReset();
		PrintReturn();
		return ERROR_INPUT;
	}

	i = ParseParam2(i);
	if(i == ERROR_INPUT)
	{
		PrintString("err param 2");
		CmdBufReset();
		PrintReturn();
		return ERROR_INPUT;
	}
//	PrintReturn();
/*
        i = 0;
        PrintHexNumber(sendtail);PrintHexNumber(sendstart);
	while(cmdbuf[i] != 0x0)
	{
		PrintHexNumber(cmdbuf[i]);
                i ++;
	}
*/
//	PrintReturn();
	ExecuteCmd();
	CmdBufReset();
	PrintReturn();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -