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

📄 pcm-rtx51.c

📁 单片机应用系统设计与产品开发的光盘(作者冯建华) 本代码包含了第4章~第10章案例的源程序和电路布线图(Protel布线)
💻 C
📖 第 1 页 / 共 2 页
字号:
		{
			NODE = Ascii2Hex(&BuffCOM1[13]);				//取命令节点号
		
			switch(NODE)									//按节点处相应处理
			{
				case 2:										//节点2, 均浮充转换
				{
					*PtrD++ = Ascii2Hex(&BuffCOM1[15]);		//存命令字
					for(i = 1; i < 17; i++)
					{
						p ^= BuffCmdSet[i];
						sum += BuffCmdSet[i];
					}
					*PtrD++ = p;
 				    *PtrD++ = (uchar)(sum&0xFF);
					*PtrD++ = (uchar)((sum>>8)&0xFF);
					*PtrD = 0x12;
					break;
				}
				case 56:									//模块开关机
				case 60:
				case 64:
				case 78:
				case 72:
				case 76:
				case 80:
				case 84:
				case 88:
				case 92:
				case 96:
				case 100:
				case 104:
				case 108:
				case 112:
				{
					*PtrD++ = Ascii2Hex(&BuffCOM1[15]);		//存命令字
					*PtrD++ = (NODE-52)/4;					//存模块号
					for(i = 1; i < 18; i++)
					{
						p ^= BuffCmdSet[i];
						sum += BuffCmdSet[i];
					}
					*PtrD++ = p;
 				    *PtrD++ = (uchar)(sum&0xFF);
					*PtrD++ = (uchar)((sum>>8)&0xFF);
					*PtrD = 0x12;
					break;
				}

				case 114:									//交流高压阀值
				case 115:									//交流低压阀值
				{
					a_float.c[3] = Ascii2Hex(&BuffCOM1[15]);//转换成浮点数
					a_float.c[2] = Ascii2Hex(&BuffCOM1[17]);
					a_float.c[1] = Ascii2Hex(&BuffCOM1[19]);
					a_float.c[0] = Ascii2Hex(&BuffCOM1[21]);
					a_int.i = (uint)(a_float.f);			//转换成int
					AlarmParaChar[(NODE-114)*2] = a_int.c[1];
					AlarmParaChar[(NODE-114)*2+1] = a_int.c[0];
					*PtrD++ = 0x01;
					BuffCmdSet[7] = 0x53;
					for(i = 0; i < 35; i++)
					{
						*PtrD++ = AlarmParaChar[i];					//存入命令串中
					}
					for(i = 1; i < 52; i++)										//生成校验
					{
						p ^= BuffCmdSet[i];
						sum += BuffCmdSet[i];
					}
					*PtrD++ = p;
 				    *PtrD++ = (uchar)(sum&0xFF);
					*PtrD++ = (uchar)((sum>>8)&0xFF);
					*PtrD = 0x12;
					break;
				}

				case 116:									//直流输出高压告警阀值
				case 117:									//直流输出低压告警阀值
				{	
					for(i = 0; i < 4; i++)
					{
						AlarmParaChar[(NODE-116)*4+4+i] = Ascii2Hex(&BuffCOM1[15+i*2]);
					}
					*PtrD++ = 0x01;
					BuffCmdSet[7] = 0x53;
					for(i = 0; i < 35; i++)
					{
						*PtrD++ = AlarmParaChar[i];					//存入命令串中
					}
					for(i = 1; i < 52; i++)										//生成校验
					{
						p ^= BuffCmdSet[i];
						sum += BuffCmdSet[i];
					}
					*PtrD++ = p;
 				    *PtrD++ = (uchar)(sum&0xFF);
					*PtrD++ = (uchar)((sum>>8)&0xFF);
					*PtrD = 0x12;
					break;
				}
				case 118:									//环境温度过高阀值
				{
					AlarmParaChar[12] = Ascii2Hex(&BuffCOM1[15]);
					*PtrD++ = 0x01;
					BuffCmdSet[7] = 0x53;
					for(i = 0; i < 35; i++)
					{
						*PtrD++ = AlarmParaChar[i];					//存入命令串中
					}
					for(i = 1; i < 52; i++)										//生成校验
					{
						p ^= BuffCmdSet[i];
						sum += BuffCmdSet[i];
					}
					*PtrD++ = p;
 				    *PtrD++ = (uchar)(sum&0xFF);
					*PtrD++ = (uchar)((sum>>8)&0xFF);
					*PtrD = 0x12;
					break;
				}
				case 119:
				case 120:
				case 121:
				{
					for(i = 0; i < 4; i++)
					{
						AlarmParaChar[(NODE-135)*4+13+i] = Ascii2Hex(&BuffCOM1[15+i*2]);
					}
					*PtrD++ = 0x01;
					BuffCmdSet[7] = 0x53;
					for(i = 0; i < 35; i++)
					{
						*PtrD++ = AlarmParaChar[i];					//存入命令串中
					}
					for(i = 1; i < 52; i++)										//生成校验
					{
						p ^= BuffCmdSet[i];
						sum += BuffCmdSet[i];
					}
					*PtrD++ = p;
 				    *PtrD++ = (uchar)(sum&0xFF);
					*PtrD++ = (uchar)((sum>>8)&0xFF);
					*PtrD = 0x12;
					break;					
				}
				case 122:									
				{
					AlarmParaChar[25] = Ascii2Hex(&BuffCOM1[15]);
					*PtrD++ = 0x01;
					BuffCmdSet[7] = 0x53;
					for(i = 0; i < 35; i++)
					{
						*PtrD++ = AlarmParaChar[i];					//存入命令串中
					}
					for(i = 1; i < 52; i++)										//生成校验
					{
						p ^= BuffCmdSet[i];
						sum += BuffCmdSet[i];
					}
					*PtrD++ = p;
 				    *PtrD++ = (uchar)(sum&0xFF);
					*PtrD++ = (uchar)((sum>>8)&0xFF);
					*PtrD = 0x12;
					break;
				}
				case 123:
				{
					for(i = 0; i < 4; i++)
					{
						AlarmParaChar[26+i] = Ascii2Hex(&BuffCOM1[15+i*2]);
					}
					BuffCmdSet[7] = 0x53;
					*PtrD++ = 0x01;
					for(i = 0; i < 35; i++)
					{
						*PtrD++ = AlarmParaChar[i];					//存入命令串中
					}
					for(i = 1; i < 52; i++)										//生成校验
					{
						p ^= BuffCmdSet[i];
						sum += BuffCmdSet[i];
					}
					*PtrD++ = p;
 				    *PtrD++ = (uchar)(sum&0xFF);
					*PtrD++ = (uchar)((sum>>8)&0xFF);
					*PtrD = 0x12;
					break;
				}
				case 124:
				case 125:
				case 126:
				case 127:
				case 128:
				{
					AlarmParaChar[NODE-124 + 30] = Ascii2Hex(&BuffCOM1[15]);
					BuffCmdSet[7] = 0x53;
					*PtrD++ = 0x01;
					for(i = 0; i < 35; i++)
					{
						*PtrD++ = AlarmParaChar[i];					//存入命令串中
					}
					for(i = 1; i < 52; i++)										//生成校验
					{
						p ^= BuffCmdSet[i];
						sum += BuffCmdSet[i];
					}
					*PtrD++ = p;
 				    *PtrD++ = (uchar)(sum&0xFF);
					*PtrD++ = (uchar)((sum>>8)&0xFF);
					*PtrD = 0x12;
					break;
				}
 
			}
		}
		FlagCmdSet = 1;
		os_switch_task();
	}
}

/********************************************/
/**           运行状态显示及喂狗           **/
/********************************************/
void Task_LEDWDT(void) _task_ TASK_LEDWDT
{
	while(1)
	{
		os_wait(K_TMO,50,0);
		P3_5 = !P3_5;
		P1_3 = !P1_3;
		RXDTimeOut++;
		if(RXDTimeOut > 50)									//从设备接收数据超时
		{
			TR0 = 0;										//禁止任务调度,等待复位
			ET0 = 0;
			EA = 0;
			while(1);
		}
		TXDTimeOut++;
		if(TXDTimeOut > 100)								//上传数据超时
		{
			TR0 = 0;										//禁止任务调度,等待复位
			ET0 = 0;
			EA = 0;
			while(1);
		}
		os_switch_task();
	}
}


/********************************************/
/**              串口1收发中断			   **/		
/********************************************/
void ISR_COM1(void) interrupt 2
{
	uchar i;
	static data uchar ch0,ch1,ch2,ch3,ch4;
	i = IIR;												//识别中断源
 	i = i & 0x0f;
	switch (i)
	{
		case 2:
			{
				if(FlagCOM1AllOut) 
				{
					for(i = 0; i < 100; i++);					//有必要延时之后再启动接收
					COM1_RXD_En();							
					return;
				}
				while((*PtrCOM1TXD != '\0') && (i < 16))
				{
					THR = *PtrCOM1TXD;
 				    PtrCOM1TXD++;
					i++;
				}
				if(*PtrCOM1TXD == '\0')
				{
					FlagCOM1AllOut = 1;
					TXDTimeOut = 0;							//清超时计时
				}
				break;
			}
		case 4:												//接收区满
		case 12:											//超时
			{
				for(i = 0; i < 14; i++)
				{
					ch4 = ch3;
					ch3 = ch2;
					ch2 = ch1;
					ch1 = ch0;
					ch0 = RBR;

					if((ch4 == 0x7E) && (ch3 == '2') && (ch2 == '0') && (ch1 == 'F') && (ch0 == PcmAddr[1]))  //有效命令头
					{
						FlagCmdStart = 1;					//命令开始标志
						PtrCOM1RXD = BuffCOM1;
						*PtrCOM1RXD++ = 0x7E;
						*PtrCOM1RXD++ = '2';
						*PtrCOM1RXD++ = '0';
						*PtrCOM1RXD++ = 'F';
					}
					if(ch0 == 0x0D)
					{
						if(FlagCmdStart)					
						{
							FlagCmdStart = 0;				//清命令开始标志
							isr_send_signal(TASK_COM1);		//发送收到命令信号
						}
					}
					*PtrCOM1RXD++ = ch0;
					if(PtrCOM1RXD == (BuffCOM1 + MAX_NUM_COM1))
					{
						PtrCOM1RXD = BuffCOM1;
					}

				}
				break;
			}
	}
}


/********************************************/
/**              串口2收发中断			   **/		
/********************************************/
void ISR_COM2(void) interrupt 4
{
	uchar data c;
	static FlagShift = 0;									//换码标志
	if(RI)
	{
		RI = 0;
		c = SBUF;
		if((c == 0x14) && (!FlagShift))						//收到换码标志
		{
			FlagShift = 1;
			return;
		}
		if(FlagShift)										//需要换码
		{
			FlagShift = 0;
			*PtrCOM2RXD++ = ~c;
		}
		else
		{
			if(c == 0x10)
			{
				PtrCOM2RXD = BuffCOM2;
			}
			*PtrCOM2RXD++ = c;
			if(c == 0x12)
			{
				isr_send_signal(TASK_DATA);
				RXDTimeOut = 0;								//清超时计时
			}

		}

	}
	else
	{
		TI = 0;
		if(FlagCOM2AllOut) return;							//发送完成
		if(*PtrCOM2TXD != 0x12)								//连续发送直至结束符
		{
			SBUF = *PtrCOM2TXD;
			PtrCOM2TXD++;
		}
		else 
		{
			FlagCOM2AllOut = 1;								//置发送完成标志
			SBUF = 0x12;									//发送结束符
		}
	}
}



/********************************************/
/**              COM1初始化                **/
/**	  	     1.8432MHZ 19200BPS			   **/
/********************************************/
void COM1_Init()
{
	P1_2 = 0;    		                                    //16C550完成复位

	LCR = 0x80;	  											//DLAB
	DLL = 0x06;	  											//Divisor
	DLM = 0x00;
	LCR = 0x03;	  											//字符长度为八位
	IER = 0x03;	  											//允许接收及发送中断
	FCR = 0xC7;   											//每收到14字节产生接收中断
	COM1_RXD_En();											//充许接收
}

/********************************************/
/**              COM2初始化                **/
/**	  		定时器2作波特率发生器          **/
/**			   TH2,TL2初值如下:            **/
/**    19200bps 0xFFEE, 9600bps 0xFFDC,    **/
/**    4800bps  0xFFB8, 2400bps 0xFF70,	   **/
/**    1200bps  0xFEE0,					   **/		
/********************************************/
void COM2_Init()
{
	P1_2 = 1;		 									    //此处开始复位16C550,节约时间

	SCON   = 0x58;
	RCAP2L = 0xE0;     
	RCAP2H = 0xFE;	   
	TL2    = 0xE0;	   
	TH2    = 0xFE;
    T2CON  = 0x34;
	RCLK   = 1;
	TCLK   = 1;
	TR2    = 1;
    RI 	   = 0;
    TI     = 0;
    ES     = 1;								
}

/********************************************/
/**              CPU 初始化                **/
/********************************************/
void CPU_Init()
{
	TMOD = 0x11;
 	TH0  = 0xEE;
	TL0  = 0x00;
	IP   = 0x00;
	ET0  = 1;
	IE1  = 0;
	EX1  = 1;
	IT1  = 1;
	EA   = 1;
}

/********************************************/
/**              读取PCM地址			   **/	
/** 	 低位PCM设备号,由拨码开关设置	   **/
/********************************************/
void Get_PcmAddr()
{
	uchar t;
	t = (P1 >> 4) & 0x0F;
	PcmAddr[0] = 'F';  
	if(t < 10)
		PcmAddr[1] = 0x30 + t;
	else
		PcmAddr[1] = 0x37 + t;
}


uchar code HEX_[]={"0123456789ABCDEF"};
/*********************************/
/*  转换一字节为连续的两Ascii码  */
/*       高位在前,低位在后       */
/*********************************/
void Hex2Ascii(uchar s, uchar *d)
{
	*d++ = HEX_[(s >> 4) & 0x0F];
	*d++ = HEX_[s & 0x0F];
}

void Int2Ascii(uint s, uchar *d)
{
	*d++ = HEX_[(s >> 12) & 0x0F];
	*d++ = HEX_[(s >> 8) & 0x0F];
	*d++ = HEX_[(s >> 4) & 0x0F];
	*d++ = HEX_[s & 0x0F];
}

/*********************************/
/*  连续的两Ascii码转换为一字节  */
/*       高位在前,低位在后       */
/*********************************/
uchar Ascii2Hex(uchar *pt)  
{
	uchar hex;
/********先处理高位*********/	
	if(*pt < 0x3A) //0~9
		hex = *pt++ - 0x30;
	else //A~F
		hex = *pt++ - 0x37; 
	hex = hex << 4;

/********再处理高位*********/	
	if(*pt < 0x3A) 
		hex |= *pt - 0x30;
	else
		hex |= *pt - 0x37; 

	return hex;
}

bit Chk_Sum(uchar *s)					
{
	uint sum=0;
	s++;					//跳过SOI
	while(*(s+4) != 0x0D)  	//除去chksum和EOI,其余相加
	{
		sum += *s++;
	}
	
	sum = sum % 0xFFFF;  	//生成校验码
	sum = ~sum + 1;

/*****校验码存放顺序为先高字节,后低字节;先高位,后低位*****/
/*****                    对比校验码                    *****/
	if(*s++ != HEX_[(sum >> 12) & 0x000F])  return 0;
	if(*s++ != HEX_[(sum >> 8) & 0x000F]) 	return 0;
	if(*s++ != HEX_[(sum >> 4) & 0x000F]) 	return 0;	       	
	if(*s++ != HEX_[sum & 0x000F]) 			return 0;
	return 1;	//正确		
}

⌨️ 快捷键说明

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