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

📄 serial.c

📁 适合初学者学习的UPSD的点阵LCD汉字显示
💻 C
字号:
/*
名称:main.c
日期:2005.01.12
作者:廖志凯
功能:
说明:程序使用RTX51实时多任务系统,
*/
#pragma large
#include	"serial.h"
/*------------------------------------------------------------------------------*/
//定义串口缓冲区
uchar xdata	cRecvBuff[RECV_GRUOP][RECV_LENGTH];	//接收缓冲区
uchar xdata	cRecvBuffNum;							//已接收数据的字节数
uchar xdata	cRecvBuffPtr;							//接收缓冲区有效数据起始指针
uchar xdata	cRecvBuffCnt;							//接收缓冲区有效数据总数

uchar xdata	cTranBuff[TRAN_GRUOP][TRAN_LENGTH];		//发送缓冲区
uchar xdata	cTranBuffNum;							//已发送数据的字节数
uchar xdata	cTranBuffPtr;							//发送缓冲区有效数据起始指针
uchar xdata	cTranBuffCnt;							//发送缓冲区有效数据总数
/*------------------------------------------------------------------------------*/
uchar xdata	cRecvBuff2[RECV_LENGTH2];				//接收缓冲区
uchar xdata	cRecvBuffNum2;							//已接收数据的字节数
uchar xdata	cTranBuff2[TRAN_GRUOP2][TRAN_LENGTH2];	//发送缓冲区
uchar xdata	cTranBuffNum2;							//已发送数据的字节数
uchar xdata	cTranBuffPtr2;							//发送缓冲区有效数据起始指针
uchar xdata	cTranBuffCnt2;							//发送缓冲区有效数据总数
/*===============================================================
功能:串口初始化
参数:
返回:
说明:
===============================================================*/
void Init_Serial(void)
{
	//初始化串口寄存器
	SCON = 0x50;			//模式1,8位通讯,允许接收
	SCON2 = 0x50;			//模式1,8位通讯,允许接收
	PCON = 0x00;			//SMOD,SMOD1=0;						
	TMOD |= 0x20;			//模式2,8位自载
	TH1 = 0xFA;
	TL1 = 0xFA;				//波特率9600
	TR1 = 1;				//启动Timer1
	ET1 = 0;				//禁止Timer1中断
	os_enable_isr(SIO_VECTOR);
	os_enable_isr(SI1_VECTOR);
	//os_disable_isr(SI1_VECTOR);
	//初始化缓冲区
	memset(cRecvBuff,0x00,RECV_GRUOP*RECV_LENGTH);
	cRecvBuffNum	= 0x00;
	cRecvBuffPtr		= 0x00;
	cRecvBuffCnt		= 0x00;
	memset(cTranBuff,0x00,TRAN_GRUOP*TRAN_LENGTH);
	cTranBuffNum	= 0x00;
	cTranBuffPtr		= 0x00;
	cTranBuffCnt		= 0x00;
	memset(cRecvBuff2, 0x00, RECV_LENGTH2);
	cRecvBuffNum2 = 0x00;
	memset(cTranBuff2, 0x00, TRAN_GRUOP2*TRAN_LENGTH2);
	cTranBuffNum2 = 0x00;
	cTranBuffPtr2 = 0x00;
	cTranBuffCnt2 = 0x00;
}
/*===============================================================
功能:
参数:
返回:
说明:
===============================================================*/
void Write_serial_buff(uchar *buff, uchar len)
{
	uchar _index;
	if(cTranBuffCnt < TRAN_GRUOP)
	{
		_index = (cTranBuffPtr + cTranBuffCnt) % TRAN_GRUOP;
		memcpy(cTranBuff[_index], buff, len);
		cTranBuffCnt++;
		//os_send_message(MBX_SERAIL_TRAN, 0x00, T10MS);
	}
}

/*===============================================================
功能:串口0  中断程序
参数:无
返回:无
说明:只给相应任务发送信号
===============================================================*/
void Int_Serial0(void) interrupt  SIO_VECTOR
{
	uchar xdata _index;
	uchar xdata _data;
	
	if(RI)
	{//接收中断
		RI = 0;
		_data = SBUF;
		//isr_send_message(MBX_SERAIL_RECV, SBUF);
		if(cRecvBuffCnt < RECV_GRUOP)
		{//接收缓冲区未满
			_index = (cRecvBuffPtr+cRecvBuffCnt) % RECV_GRUOP;	//缓冲区的偏移地址
			if(_data == 0xFF)
			{//如果收到起始符
				cRecvBuff[_index][0] = 0xFF;	
				cRecvBuffNum = 0x01;
			}
			else if( (cRecvBuffNum > 0x00)  && (cRecvBuffNum < RECV_LENGTH) )
			{//其他数据
				cRecvBuff[_index][cRecvBuffNum] = _data;
				cRecvBuffNum++;
				if(cRecvBuffNum == (cRecvBuff[_index][1] + 3) )
				{//接收完毕
					cRecvBuffCnt++;
					cRecvBuffNum = 0x00;
				}
			}
			else if(cRecvBuffNum >= RECV_LENGTH)
			{//接收的数据超过缓冲区容量清除当前接收的数据
			cRecvBuffNum = 0x00;
			memset(&cRecvBuff[_index][0],0x00,RECV_LENGTH);
			}
		}
	}
	if(TI)
	{//发送中断
		TI = 0;
		isr_send_signal(STRAN_TASK_ID);
	}
}
/*===============================================================
功能:串口1  中断程序
参数:无
返回:无
说明:只给相应任务发送信号
===============================================================*/
void Int_Serial1(void) interrupt  SI1_VECTOR
{
	if(SCON2&0x01)
	{//接收中断
		SCON2 &= 0xFE;
		cRecvBuff2[cRecvBuffNum2] = SBUF2;
		if( ((cRecvBuff2[cRecvBuffNum2] == 'D') || (cRecvBuff2[cRecvBuffNum2] == 'W'))
			&& (cRecvBuff2[cRecvBuffNum2-1] == 'D') )
		{//接收到数据头
			cRecvBuff2[0] = 'D';
			cRecvBuff2[1] = cRecvBuff2[cRecvBuffNum2];
			cRecvBuffNum2 = 1;
		}
		else if( (cRecvBuff2[cRecvBuffNum2] == 0x0A) && (cRecvBuff2[cRecvBuffNum2-1] == 0x0D) )
		{//接收完毕
			isr_send_signal(CONFIG_TASK_ID);
		}
		cRecvBuffNum2++;
	}
	if(SCON2&0x02)
	{//发送中断
		SCON2 &= 0xFD;
		isr_send_signal(DEBUG_TASK_ID);
	}
}
/*===============================================================
功能:串口接收任务
参数:无
返回:无
说明:缓冲区采用先进先出的原则,当缓冲区已满则停止接收
		邮件的参数是接收数据的长度。只有接收到数据头才开始接收数据
===============================================================*/
void Serial_RECV_Task(void)	_task_ SRECV_TASK_ID
{
	static uchar xdata _index;
	static uint xdata _data;
	while(1)
	{
		//os_wait(K_SIG,0x00,0x00);					//等待串口接收数据
		os_wait(K_MBX+MBX_SERAIL_RECV, 0x00, &_data);
		if(cRecvBuffCnt < RECV_GRUOP)
		{//接收缓冲区未满
			_index = (cRecvBuffPtr+cRecvBuffCnt) % RECV_GRUOP;	//缓冲区的偏移地址
			if((uchar)_data == 0xFF)
			{//如果收到起始符
				cRecvBuff[_index][0] = 0xFF;	
				cRecvBuffNum = 0x01;
			}
			else if( (cRecvBuffNum > 0x00)  && (cRecvBuffNum < RECV_LENGTH) )
			{//其他数据
				cRecvBuff[_index][cRecvBuffNum] = (uchar)_data;
				cRecvBuffNum++;
				if(cRecvBuffNum == (cRecvBuff[_index][1] + 3) )
				{//接收完毕
					cRecvBuffCnt++;
					cRecvBuffNum = 0x00;
				}
			}
			else if(cRecvBuffNum > RECV_LENGTH)
			{//接收的数据超过缓冲区容量清除当前接收的数据
			cRecvBuffNum = 0x00;
			memset(&cRecvBuff[_index][0],0x00,RECV_LENGTH);
			}
		}
	}
}

/*===============================================================
功能:串口发送任务
参数:无
返回:无
说明:发送
		邮件的参数是要发送数据的长度
===============================================================*/
void Serial_Tran_Task(void) _task_ STRAN_TASK_ID
{
	static uchar xdata _sendNum;
	while(1)
	{
		if( (cTranBuffCnt != 0x00) && (cTranBuffPtr < TRAN_GRUOP) )
		{//有数据要发送
			_sendNum = 0x00;
			while(_sendNum < cTranBuff[cTranBuffPtr][1]+3)
			{//数据是否发送完毕
				SBUF = cTranBuff[cTranBuffPtr][_sendNum];
				os_wait(K_SIG,0x00,0x00);					//等待数据发送完毕
				_sendNum++;
			}
			//清除发送完毕的数据
			memset(&cTranBuff[cTranBuffPtr][0], 0x00, TRAN_LENGTH);
			cTranBuffPtr = (cTranBuffPtr+1) % TRAN_GRUOP;
			cTranBuffCnt --;			
		}
		os_wait(K_TMO, T10MS, 0x00);
	}
}
/*===============================================================
功能:调试任务
参数:无
返回:无
说明:发送调试信息,第一个字节为发送长度,后面为协议
===============================================================*/
void Debug_Task(void) _task_ DEBUG_TASK_ID
{
	while(1)
	{
		if( (cTranBuffPtr2<TRAN_GRUOP2) && (cTranBuffCnt2 != 0x00) )
		{
			cTranBuffNum2 = 0x01;
			while(cTranBuffNum2 < cTranBuff2[cTranBuffPtr2][0])
			{
				SBUF2 = cTranBuff2[cTranBuffPtr2][cTranBuffNum2];
				cTranBuffNum2++;
				os_wait(K_SIG, 0x00, 0x00);
			}
			//清除发送完毕的数据
			memset(&cTranBuff2[cTranBuffPtr2][0], 0x00, TRAN_LENGTH2);
			cTranBuffPtr2 = (cTranBuffPtr2+1) % TRAN_GRUOP2;
			cTranBuffCnt2 --;
		}
		else 
			os_wait(K_TMO, T10MS, 0x00);
	}
}

/*===============================================================
功能:写入调试信息
参数:type-类型;buff-数据;
返回:无
说明:
===============================================================*/
void	Write_Debug_Info(uchar* buff, uchar len)
{
	uchar _tmp;
	if( (cTranBuffCnt2 < TRAN_GRUOP2) && ((len+3) <TRAN_LENGTH2) )
	{//缓冲区还有空间
		_tmp = (cTranBuffPtr2+cTranBuffCnt2)%TRAN_GRUOP2;		//计算偏移地址
		memset(cTranBuff2[_tmp], 0x00, TRAN_LENGTH2);
		cTranBuff2[_tmp][0] = len+3;
		memcpy(&cTranBuff2[_tmp][1], buff, len);
		cTranBuff2[_tmp][len+1] = 0x0D;
		cTranBuff2[_tmp][len+2] = 0x0A;
		cTranBuffCnt2++;
	}
}
/*===============================================================
功能:设置任务,完成组号的设定和读取
参数:
返回:
说明:组号从地址0x8000开始放置,每个组号共五个汉字
		总共16组
===============================================================*/
void Config_Task(void) _task_ CONFIG_TASK_ID
{
	static uchar xdata _tmp;
	static uchar xdata _buff[160];
	while(1)
	{
		os_wait(K_SIG, 0x00, 0x00);
		//去除回车符
		cRecvBuff2[cRecvBuffNum2-1] = 0x00;
		cRecvBuff2[cRecvBuffNum2-2] = 0x00;
		
		_tmp = (cRecvBuff2[2]-'0')*10 +cRecvBuff2[3] - '0';
		
	}
}

/*===============================================================
功能:
参数:
返回:
说明:
===============================================================*/

⌨️ 快捷键说明

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