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

📄 sp2539 demo.c

📁 C51串口扩展5个源代码
💻 C
字号:
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!申    明!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
//本驱动程序属于成都视普科技公司所有,仅允许免费用于本公司销售的产品中,未  //
//经书面许可任何单位或个人不可将本程序用于其它用途,否则将追究其法律责任   //
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/***************************************************************************
 SP2539 demo.c source file SP2539 serial communication
 example for MCS-51 MCU  (oscillating crystal: 11.0592MHz)
 Author: Wen hua, 2006-03-18 
***************************************************************************/
/********************************上位机资源占用*****************************
****** RAM:22(BYTE,不包含子串口发送缓冲)+7(BIT),ROM:430BYTE(内核部分)  *****
****** 接收一个字节耗用15条指令(MAX),发送一个字节耗用45条指令(MAX) *****
***************************************************************************/

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

bit bdata bUartBusy;		//上位机串口发送状态标志,"1"表示上位机串口"忙"(正发送数据
							//到子串口,新数据只需送入子串口发送缓冲区即可,"0"表示上位
							//机串口"空闲",需用户程序将"TI=1"来启动子串口数据发送

bit bdata bInstructFlag;	//上位机发送指令请求标志,上位机需要发送指令时必须
							//先将待发发送指令放到"InstructBuf",之后将该
							//标志设置为"1"即可.标志变为"0"后可继续发送指令

bit bdata bUart0RFlag,bUart1RFlag,bUart2RFlag,bUart3RFlag,bUart4RFlag;	//上位机接收到子串口数据
							//标志,"1"表示上位机接收到相应子串口数据,主程序可通过查询
							//该标志的方式判断相应子串口是否接收到新数据(主程序取走刚
							//收到的新数据后,必须将该标志清"0",以便识别下一个新数据)

uchar idata Uart0Tbuf[8]; 	//子串口0数据发送缓冲区(大小可由用户随意配置)
uchar idata Uart1TBuf[8]; 	//子串口1数据发送缓冲区(大小可由用户随意配置)
uchar idata Uart2TBuf[8]; 	//子串口2数据发送缓冲区(大小可由用户随意配置)
uchar idata Uart3TBuf[8]; 	//子串口3数据发送缓冲区(大小可由用户随意配置)
uchar idata Uart4TBuf[8]; 	//子串口4数据发送缓冲区(大小可由用户随意配置)

uchar idata Uart0RBuf,Uart1RBuf,Uart2RBuf,Uart3RBuf,Uart4RBuf;	//上位机接收子串口数据缓
							//冲存储器,上位机通过判断"bUart0RFlag"等标志
							//是否为"1",来决定是否读取该寄存器的数据

uchar idata UartPointer;	//子串口发送数据指针,中断服务程序通过该指针轮询
							//发送数据到各子串口,保证各子串口的数据不丢失

uchar idata InstructBuf;	//指令缓冲(用户可将设置SP2539的指令放入
							//该寄存器,由驱动程序自动完成指令发送)

uchar idata Uart0TNum,Uart1TNum,Uart2TNum,Uart3TNum,Uart4TNum;	//等待发送到各
							//子串口的字节数,"0"表示相应子串口发送缓冲区"空"
							//主程序可以通过判断该标志是否为"0"来决定是否向
							//相应子串口发送后续数据

//如果对应子串口波特率为默认值,则不用定义对应子串口的分频系数变量
uchar idata Uart0Coef,Uart1Coef,Uart2Coef,Uart3Coef,Uart4Coef;	//子串口分频系数/波特率控制寄存
							//器,具体用法请参见设置子串口的波特率指令部分

//如果对应子串口波特率为默认值,则不用定义对应子串口的分频系数变量
uchar idata Uart0CoefBuf,Uart1CoefBuf,Uart2CoefBuf,Uart3CoefBuf,Uart4CoefBuf;//分频系数缓冲寄存器

/*****************************************************************************
功能:设定SP2539输入、输出地址,可根据实际电路修改
*****************************************************************************/
sbit 	AdrIn0 =P1^0;	/* 连接到SP2539的PIN7(ADRO0)*/
sbit	AdrIn1 =P1^1;	/* 连接到SP2539的PIN8(ADRO1)*/
sbit	AdrIn2 =P1^2;	/* 连接到SP2539的PIN9(ADRO2)*/
sbit	AdrOut0=P1^3;	/* 连接到SP2539的PIN10(ADRI0)*/
sbit	AdrOut1=P1^4;	/* 连接到SP2539的PIN11(ADRI1)*/
sbit	AdrOut2=P1^5;	/* 连接到SP2539的PIN12(ADRI2)*/

#define _DEBUG_SUB_MODULE
/****************************************************************************
功能:上位机串口中断服务函数,自动完成子串口数据发送(自动发送数据包)和数据接收
	 (单字节接收并缓存)以及自动发送上位机配置指令等
输入:Uart0Coef,Uart1Coef,Uart2Coef,Uart3Coef,Uart4Coef,Uart0TNum,Uart1TNum,
	 Uart2TNum,Uart3TNum,Uart4TNum,Uart0Tbuf[???],Uart1TBuf[???],Uart2TBuf[???],
	 Uart3TBuf[???],Uart4TBuf[???],bInstructFlag,InstructBuf,bUartBusy
输出:bUart0RFlag,bUart1RFlag,bUart2RFlag,bUart3RFlag,bUart4RFlag,Uart0RBuf,
	 Uart1RBuf,Uart2RBuf,Uart3RBuf,Uart4RBuf,bUartBusy
*****************************************************************************/
serial () interrupt 4 {
	if(RI){
		RI=0;					//准备解析刚接收到的数据来自于哪个子串口
		if(AdrIn2){				//子串口4接收到一个字节(输入地址:100)
			Uart4RBuf=SBUF;		//缓存子串口4收到的数据,以便接收后续数据
			bUart4RFlag=1;		//置子串口4收到数据标志,便于主程序查询		
		}
		else if(AdrIn1){			
			if(AdrIn0){			//子串口3接收到一个字节(输入地址:011)
				Uart3RBuf=SBUF;	//缓存子串口3收到的数据,以便接收后续数据
				bUart3RFlag=1;	//置子串口3收到数据标志,便于主程序查询
			}
			else {				//子串口2接收到一个字节(输入地址:010)
				Uart2RBuf=SBUF;	//缓存子串口2收到的数据,以便接收后续数据
				bUart2RFlag=1;	//置子串口2收到数据标志,便于主程序查询
			}
		}
		else if(AdrIn0){		//子串口1接收到一个字节(输入地址:001)
			Uart1RBuf=SBUF;		//缓存子串口1收到的数据,以便接收后续数据
			bUart1RFlag=1;		//置子串口1收到数据标志,便于主程序查询
		}
		else {					//子串口0接收到一个字节(输入地址:000)
			Uart0RBuf=SBUF;		//缓存子串口0收到的数据,以便接收后续数据
			bUart0RFlag=1;		//置子串口0收到数据标志,便于主程序查询
		}
	}

	else{
		TI=0;					//已经产生发送中断,准备解析下一个需要发送的数据
		switch(UartPointer){	//判断即将向哪个子串口发送数据?
			case 0:{			//准备向子串口0发送数据
				UartPointer++;	//下一次发送中断准备向子串口1发送数据
//				if((--Uart0CoefBuf)==0){	//由于子串口0的波特率为9600bps,
//					Uart0CoefBuf=Uart0Coef;	//所以程序中不用定义和使用这两个变量
					if(Uart0TNum){			//串口0发送缓存区是否有数据需要发送?
						AdrOut0=0;			//有数据需要发送,则选通子串口0的地址
						AdrOut1=0;
						AdrOut2=0;
						SBUF=Uart0Tbuf[--Uart0TNum];//将串口0发送缓存中的一个字节
						break;						//由子串口0发送到下位机
					}
					else goto T_NopInstruction;		//若子串口0没有数据发送则准备发送空指令
//				}
//				else goto T_NopInstruction;
			}

			case 1:{			//准备向子串口1发送数据
				UartPointer++;	//下一次发送中断准备向串口2发送数据
				if((--Uart1CoefBuf)==0){	//由于子串口1的波特率为4800,需要进行二分
					Uart1CoefBuf=Uart1Coef;	//频时序处理,只有时序到达后才可发送数据
					if(Uart1TNum){			//串口1发送缓存区是否有数据需要发送?
						AdrOut0=1;			//有数据需要发送,则选通子串口1的地址
						AdrOut1=0;
						AdrOut2=0;
						SBUF=Uart1TBuf[--Uart1TNum];//将串口1发送缓存中的一个字节
						break;						//由子串口1发送到下位机
					}
					else goto T_NopInstruction;		//若子串口1没有数据发送则准备发送空指令
				}
				else goto T_NopInstruction; //若分频时间没有到则不能向子串口1发送数据
			}								//而只能够发送一条空指令用于时序配合

			case 2:{			//准备向子串口2发送数据
				UartPointer++;	//下一次发送中断准备向串口3发送数据
				if((--Uart2CoefBuf)==0){	//由于子串口2的波特率为2400,需要进行四分
					Uart2CoefBuf=Uart2Coef;	//频时序处理,只有时序到达后才可发送数据
					if(Uart2TNum){			//串口2发送缓存区是否有数据需要发送?
						AdrOut0=0;			//有数据需要发送,则选通子串口2的地址
						AdrOut1=1;
						AdrOut2=0;
						SBUF=Uart2TBuf[--Uart2TNum];//将串口2发送缓存中的一个字节
						break;						//由子串口2发送到下位机
					}
					else goto T_NopInstruction;		//若子串口2没有数据发送则准备发送空指令
				}
				else goto T_NopInstruction; //若分频时间没有到则不能向子串口2发送数据
			}								//而只能够发送一条空指令用于时序配合

			case 3:{			//准备向子串口3发送数据
				UartPointer++;	//下一次发送中断准备向串口4发送数据
				if((--Uart3CoefBuf)==0){	//由于子串口3的波特率为1200,需要进行四分
					Uart3CoefBuf=Uart3Coef;	//频时序处理,只有时序到达后才可发送数据
					if(Uart3TNum){			//串口3发送缓存区是否有数据需要发送?
						AdrOut0=1;			//有数据需要发送,则选通子串口3的地址
						AdrOut1=1;
						AdrOut2=0;
						SBUF=Uart3TBuf[--Uart3TNum];//将串口3发送缓存中的一个字节
						break;						//由子串口3发送到下位机
					}
					else goto T_NopInstruction;		//若子串口3没有数据发送则准备发送空指令
				}
				else goto T_NopInstruction; //若分频时间没有到则不能向子串口3发送数据
			}								//而只能够发送一条空指令用于时序配合

			case 4:{			//准备向子串口4发送数据
				UartPointer++;	//下一次发送中断准备发送空指令
				if((--Uart4CoefBuf)==0){	//由于子串口4的波特率为600,需要进行四分
					Uart4CoefBuf=Uart4Coef;	//频时序处理,只有时序到达后才可发送数据
					if(Uart4TNum){			//串口4发送缓存区是否有数据需要发送?
						AdrOut0=0;			//有数据需要发送,则选通子串口2的地址
						AdrOut1=0;
						AdrOut2=1;
						SBUF=Uart4TBuf[--Uart4TNum];//将串口4发送缓存中的一个字节
						break;						//由子串口4发送到下位机
					}
					else goto T_NopInstruction;		//若子串口4没有数据发送则准备发送空指令
				}
				else goto T_NopInstruction; //若分频时间没有到则不能向子串口4发送数据
			}								//而只能够发送一条空指令用于时序配合

			default:{
				UartPointer=0;			//下一次发送中断准备向串口0发送数据
T_NopInstruction:
				AdrOut0=1;				//选通目串口准备发送空指令或者其他指令
				AdrOut1=0;
				AdrOut2=1;
				if(bInstructFlag){		//判断是否需要发送其他指令?
					bInstructFlag=0;	//清除指令发送标志
					SBUF=InstructBuf;	//将需要发送的指令发送到串口扩展IC
					break;
				}
				else if(Uart0TNum|Uart1TNum|Uart2TNum|Uart3TNum|Uart4TNum){
					SBUF=0;				//判断所有子串口是否都已发送完毕

⌨️ 快捷键说明

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