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

📄 server.c

📁 LWIP在STM32裸机上的移植
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "i2c.h"
#include "server.h"

u8 UDPAsk[]  = "FFFFF";					//返回的应答
u8 UDPData[] = "FFFFFFFFFFFFFFFFFFFF";	//返回的数据(0x72指令)

extern u8 Cmd71_SetFlg;			//0x71指令标识符
extern u8 Cmd77_SetFlg;			//0x77指令设置标记(设置IP地址)
extern u8 Cmd79_SetFlg;			//0x79指令标识符

extern u8 InputState[20][12];	//推子模块状态(临时场景信息)
extern u8 HotFireSet[4];		//热线地址
extern u8 HotFireClear;			//"热线"按键屏蔽功能
extern u8 OutputSet[20];		//输出通道设置
extern u8 OutputGainSet[7];		//输出通道增益设置(最后还包含一个字节SyncMode)
extern u8 SyncMode;				//同步模式
extern u8 KeyDataBK[20];		//存储原来按键值
extern u8 AddVoltage[5][4];		//话筒输入板加幻想电压(5个输入板,A/B/C/D四路)

extern u8 TabTotal;				//节目列表总字节数(Tablen * 6 Byte)
extern u8 PlayTable[40][6];		//播放列表
extern u8 IPAddress[12];		//IP地址

extern u8 EffectTest[13];		//效果测试(0x74)
extern u8 EffectData[4][12]; 	//效果设置(0x75)
extern u8 EffectAddr[20][3];	//恢复效果(0x7A)(话筒输入板地址,效果编号,是否测试)

extern u8 ScenNum;				//场景编号
extern u8 ScenKeyBK;			//场景按键
extern u8 SceneSetFlag;			//场景设置标记(为了使按下"场景"键时,只发送一次)

extern u16 TuiziAddr[5];
extern u16 InputAddr[5];
extern u16 OutputAddr[5];

extern CanTxMsg TxMessage;

/**
  * @brief  Initialize the server application.
  * @param  None
  * @retval None
  */
void server_init(void)
{
   struct udp_pcb *upcb;                                 
   
   /* Create a new UDP control block  */
   upcb = udp_new();
   
   /* Bind the upcb to the UDP_PORT port */
   /* Using IP_ADDR_ANY allow the upcb to be used by any local interface */
   udp_bind(upcb, IP_ADDR_ANY, UDP_SERVER_PORT);
   
   /* Set a receive callback for the upcb */
   udp_recv(upcb, udp_server_callback, NULL);  
}

/**
  * @brief This function is called when an UDP datagrm has been received on the port UDP_PORT.
  * @param arg : user supplied argument (udp_pcb.recv_arg)
  * @param upcb: the udp_pcb which received data
  * @param p   : the packet buffer that was received
  * @param addr: the remote IP address from which the packet was received
  * @param port: the remote port from which the packet was received
  * @retval None
  */
void udp_server_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
{ 
	u16 j;
	u8 u,k;
	u8 ins = 0;				//指令字节
	u8 len = 0;				//有效数据长度	
//	u8 add = 0;				//有效数据总和
	u8 check = 0;			//校验码
	u8 askdata[5] = {0};	//指令回复数据
	u8 revdata[512]={0};	//接收的数据

	u8 *pt = (u8 *)p->payload;

////////////////////////////////////////////		
//	#define DATALEN p->len  
//	
//	printf("\nThe receive data :\n");
//	for(j=0;j<DATALEN;j++)
//	{
//		printf("0x%X ",*pt);
//		pt++;
//	}
//	printf("\n");
//	pt = (u8 *)p->payload;
////////////////////////////////////////////

	//开始处理网络接收的数据
	if(*pt == 0x55)				//第一个字节:start起始标识符
	{
		askdata[0] = 0x55;

		pt++;
		ins = *pt;				//第二个字节:指令字节
		askdata[1] = *pt;
		
		if(ins == 0x71)	//0x71指令,数据长度超过255字节,故未用第三字节表示有效数据长度
		{
			pt++;
			for(j=0;j<272;j++)
			{
				revdata[j] = *pt;
				pt++;
			}
//			printf("\nThe last data is = 0x%X\n",*pt);
//			printf("The len is = %d\n\n",j);
			askdata[2] = 0xFA;
			askdata[3] = askdata[0]+askdata[1]+askdata[2];
			if(*pt == 0xEE)
				askdata[4] = 0xEE;
		}
		else if(ins == 0x79)	//场景
		{
			pt++;
			ScenNum = *pt;		//场景编号

			pt++;
			for(j=0;j<312;j++)
			{
				revdata[j] = *pt;
				pt++;
			}
//			printf("\nThe last data is = 0x%X\n",*pt);
//			printf("The len is = %d\n\n",j);
			askdata[2] = 0xFA;
			askdata[3] = askdata[0]+askdata[1]+askdata[2];
			if(*pt == 0xEE)
				askdata[4] = 0xEE;
		}
		else
		{		
			pt++;
			len = *pt;			//第三个字节:有效数据长度

			pt++;
			for(j=0;j<len;j++)	//接收有效数据
			{	
				revdata[j] = *pt;
//				add += *pt;
				pt++;	
			}
//			check = 0x55+ins+len+add;
//			if(check == *pt)
				askdata[2] = 0xFA;
//			else
//				askdata[2] = 0xF4;

			askdata[3] = askdata[0]+askdata[1]+askdata[2];	//校验和(CheckSum)
			pt++;
			if(*pt == 0xEE)
				askdata[4] = 0xEE;
		}	
	}

	for(j=0;j<5;j++)
		UDPAsk[j] = askdata[j];

	//若接收正确,则根据不同指令,处理接收的数据
	if((askdata[0] == 0x55)&&(askdata[2] == 0xFA)&&(askdata[4] == 0xEE))
	{
		switch(ins)
		{
			//*** 设置调音台数据 ***//
			case (0x71):
				if(ScenKeyBK)	//"场景"按键有效
				{
					I2C_EE_BufferWrite(revdata,EEP_TempScene_Address,271);	//临时场景
				}
				else			//"场景"按键未按下时(临时场景)
				{			
					Cmd71_SetFlg = 1;
					I2C_EE_ByteWrite(Cmd71_SetFlg,EEP_Cmd71_Address);
					I2C_EE_BufferWrite(revdata,EEP_TempScene_Address,271);	//临时场景					

					u=0;k=0;
					for(j=0;j<240;j++)			//输入通道状态设置数据
					{	
						InputState[k][u] = revdata[j];
						u++;
						if(u%12==0)
						{	
							k++;
							u=0;
						}	
					}	

					for(u=0,j=240;j<244;j++)	//热线设置数据
					{
						HotFireSet[u] = revdata[j];
						u++;
					}
	
					for(u=0,j=244;j<264;j++)	//输出通道状态设置数据
					{
						OutputSet[u] = revdata[j];
						u++;
					}
	
					for(u=0,j=264;j<271;j++)	//输出通道增益设置数据
					{
						OutputGainSet[u] = revdata[j];
						u++;
					}
					SyncMode = OutputGainSet[6];//同步模式 revdata[270];	
//					printf("(0).SyncMode = 0x%X\n",SyncMode);
				
					//上位机每设置一次临时场景,都会保存"效果设置"信息
					for(j=0;j<20;j++)
					{
						if(InputState[j][7] == 0x03)  //与推子模块绑定的是否是话筒输入板
							EffectAddr[j][0] = InputState[j][8];//保存话筒输入板地址
						else
							EffectAddr[j][0] = 0;				//未用话筒输入板绑定,没有地址
					}
					for(k=0,j=0;j<40;j++)
					{
						revdata[j++] = EffectAddr[k++][0];
						revdata[j] = 0;		   					//默认都未设置效果
					}
					I2C_EE_PageWrite(revdata,EEP_EffectAddr_Address,40);//保存话筒输入板地址

					if(HotFireSet[2])	//处理"热线"按键
					{	
						for(j=0;j<20;j++)	
							if(HotFireSet[2] == InputState[j][8])break;	
	
						HotFireClear = (((InputState[j][0]>>4)& 0x0F)-1)*4 + ((InputState[j][0]& 0x0F)-0x0A); 	
					}
					else
						HotFireClear = 0xFF;

					//刷新"设置"按键
					TxMessage.RTR = CAN_RTR_DATA;
					TxMessage.IDE = CAN_ID_STD;
					TxMessage.DLC = 4;
					if(TuiziAddr[0] != 0) 		//地址1推子
					{
						for(j=0;j<4;j++)
						{
							if((InputState[j][7] & 0x0F)!= 0x03)
								KeyDataBK[j] &= ~(1<<3);
							if(HotFireClear == j)
								KeyDataBK[j] &= ~(1<<1);
							TxMessage.Data[j] = KeyDataBK[j];
						}
						TxMessage.StdId = 0x101;
						while(((CAN1->TSR>>26)& 0x07) == 0);
						CAN_Transmit(CAN1, &TxMessage);
					}
					if(TuiziAddr[1] != 0)		//地址2推子
					{
						for(k=0,j=4;j<8;j++)
						{
							if((InputState[j][7] & 0x0F)!= 0x03)
								KeyDataBK[j] &= ~(1<<3);
							if(HotFireClear == j)
								KeyDataBK[j] &= ~(1<<1);
							TxMessage.Data[k++] = KeyDataBK[j];
						}
						TxMessage.StdId = 0x201;
						while(((CAN1->TSR>>26)& 0x07) == 0);
						CAN_Transmit(CAN1, &TxMessage);
					}
					if(TuiziAddr[2] != 0)		//地址3推子
					{
						for(k=0,j=8;j<12;j++)
						{
							if((InputState[j][7] & 0x0F)!= 0x03)
								KeyDataBK[j] &= ~(1<<3);
							if(HotFireClear == j)
								KeyDataBK[j] &= ~(1<<1);
							TxMessage.Data[k++] = KeyDataBK[j];
						}
						TxMessage.StdId = 0x301;
						while(((CAN1->TSR>>26)& 0x07) == 0);
						CAN_Transmit(CAN1, &TxMessage);
					}
					if(TuiziAddr[3] != 0)		//地址4推子
					{
						for(k=0,j=12;j<16;j++)
						{
							if((InputState[j][7] & 0x0F)!= 0x03)
								KeyDataBK[j] &= ~(1<<3);
							if(HotFireClear == j)
								KeyDataBK[j] &= ~(1<<1);
							TxMessage.Data[k++] = KeyDataBK[j];
						}
						TxMessage.StdId = 0x401;
						while(((CAN1->TSR>>26)& 0x07) == 0);
						CAN_Transmit(CAN1, &TxMessage);
					}
					if(TuiziAddr[4] != 0)		//地址5推子
					{
						for(k=0,j=16;j<20;j++)
						{
							if((InputState[j][7] & 0x0F)!= 0x03)
								KeyDataBK[j] &= ~(1<<3);
							if(HotFireClear == j)
								KeyDataBK[j] &= ~(1<<1);
							TxMessage.Data[k++] = KeyDataBK[j];
						}
						TxMessage.StdId = 0x501;
						while(((CAN1->TSR>>26)& 0x07) == 0);
						CAN_Transmit(CAN1, &TxMessage);
					}
	
					//设置推子模块数据
					TxMessage.RTR = CAN_RTR_DATA;
					TxMessage.IDE = CAN_ID_STD;
					TxMessage.DLC = 8;	
					if(TuiziAddr[0] != 0) 		//地址1推子
					{
						TxMessage.StdId = TuiziAddr[0];
						for(j=0;j<4;j++)
						{
							TxMessage.Data[0] = (InputState[j][7]<<4)|(j+1); //高4位信号格式,低4位数据包编号
							TxMessage.Data[1] = InputState[j][8];
							for(u=2;u<8;u++)
								TxMessage.Data[u] = InputState[j][u-1];
							while(((CAN1->TSR>>26)& 0x07) == 0);
							CAN_Transmit(CAN1, &TxMessage);
						}
					}
					if(TuiziAddr[1] != 0)		//地址2推子
					{
						TxMessage.StdId = TuiziAddr[1];
						for(j=4;j<8;j++)
						{
							TxMessage.Data[0] = (InputState[j][7]<<4)|(j-3); //高4位信号格式,低4位数据包编号
							TxMessage.Data[1] = InputState[j][8];			 //输入模块地址
							for(u=2;u<8;u++)
								TxMessage.Data[u] = InputState[j][u-1];		 //6字节汉字码
							while(((CAN1->TSR>>26)& 0x07) == 0);
							CAN_Transmit(CAN1, &TxMessage);
						}
					}
					if(TuiziAddr[2] != 0)		//地址3推子
					{
						TxMessage.StdId = TuiziAddr[2];
						for(j=8;j<12;j++)
						{
							TxMessage.Data[0] = (InputState[j][7]<<4)|(j-7); //高4位信号格式,低4位数据包编号
							TxMessage.Data[1] = InputState[j][8];
							for(u=2;u<8;u++)
								TxMessage.Data[u] = InputState[j][u-1];
							while(((CAN1->TSR>>26)& 0x07) == 0);
							CAN_Transmit(CAN1, &TxMessage);
						}
					}
					if(TuiziAddr[3] != 0)		//地址4推子
					{	
						TxMessage.StdId = TuiziAddr[3];
						for(j=12;j<16;j++)
						{
							TxMessage.Data[0] = (InputState[j][7]<<4)|(j-11); //高4位信号格式,低4位数据包编号
							TxMessage.Data[1] = InputState[j][8];
							for(u=2;u<8;u++)
								TxMessage.Data[u] = InputState[j][u-1];
							while(((CAN1->TSR>>26)& 0x07) == 0);
							CAN_Transmit(CAN1, &TxMessage);
						}
					}
					if(TuiziAddr[4] != 0)		//地址5推子
					{
						TxMessage.StdId = TuiziAddr[4];
						for(j=16;j<20;j++)
						{	
							TxMessage.Data[0] = (InputState[j][7]<<4)|(j-15); //高4位信号格式,低4位数据包编号
							TxMessage.Data[1] = InputState[j][8];
							for(u=2;u<8;u++)
								TxMessage.Data[u] = InputState[j][u-1];
							while(((CAN1->TSR>>26)& 0x07) == 0);
							CAN_Transmit(CAN1, &TxMessage);
						}	
					}		
					
					//加幻相电压
					for(k=0;k<5;k++)
						for(j=0;j<4;j++)
							AddVoltage[k][j] = 0;	//清零
								
					for(j=0;j<20;j++)
					{
						if(InputState[j][7] == 0x03)  //与推子模块绑定的是否是话筒输入板
						{
							u = ((InputState[j][8]>>4)& 0x0F)-0x01;
							k = (InputState[j][8]& 0x0F)-0x0A;
	
							if((u>=0x05)||(k>=0x04))continue;
	
							if(InputState[j][10]== 0x01) //加幻相电压
							{							
								AddVoltage[u][k] = 1;
							}	
							else						 //不加幻相电压	
								AddVoltage[u][k] = 0;						
						}
					}		
	
					//设置输入通道数据
					TxMessage.RTR = CAN_RTR_DATA;
					TxMessage.IDE = CAN_ID_STD;
					TxMessage.DLC = 1;
					if(InputAddr[0] != 0)
					{
						TxMessage.Data[0] = (AddVoltage[0][0]|(AddVoltage[0][1]<<1)|
											(AddVoltage[0][2]<<2)|(AddVoltage[0][3]<<3))& 0x0F;		
						TxMessage.StdId = InputAddr[0];

⌨️ 快捷键说明

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