DHCP
1 /********************************** (C) COPYRIGHT ****************************** 2 * File Name : DHCP_Client.C 3 * Author : WCH 4 * Version : V1.0 5 * Date : 2018/12/01 6 * Description : CH57xNET库演示文件 7 * (1)、CH579 Examples by KEIL; 8 * (2)、串口1输出监控信息,115200bps; 9 * (3)、本程序用于演示DHCP客户端从网关获取IP地址 10 *******************************************************************************/ 11 12 13 14 /******************************************************************************/ 15 /* 头文件包含*/ 16 #include <stdio.h> 17 #include <string.h> 18 #include "CH57x_common.h" 19 #include "core_cm0.h" 20 #include "CH57xNET.H" 21 22 #define KEEPLIVE_ENABLE 1 // 开启KEEPLIVE功能 23 24 /* 下面的缓冲区和全局变量必须要定义,库中调用 */ 25 __align(16)UINT8 CH57xMACRxDesBuf[(RX_QUEUE_ENTRIES )*16]; //MAC接收描述符缓冲区,16字节对齐 26 __align(4) UINT8 CH57xMACRxBuf[RX_QUEUE_ENTRIES*RX_BUF_SIZE]; //MAC接收缓冲区,4字节对齐 27 __align(4) SOCK_INF SocketInf[CH57xNET_MAX_SOCKET_NUM]; //Socket信息表,4字节对齐 28 29 UINT16 MemNum[8] = {CH57xNET_NUM_IPRAW, 30 CH57xNET_NUM_UDP, 31 CH57xNET_NUM_TCP, 32 CH57xNET_NUM_TCP_LISTEN, 33 CH57xNET_NUM_TCP_SEG, 34 CH57xNET_NUM_IP_REASSDATA, 35 CH57xNET_NUM_PBUF, 36 CH57xNET_NUM_POOL_BUF 37 }; 38 UINT16 MemSize[8] = {CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IPRAW_PCB), 39 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_UDP_PCB), 40 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB), 41 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB_LISTEN), 42 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_SEG), 43 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IP_REASSDATA), 44 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(0), 45 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_POOL_BUF) 46 }; 47 __align(4)UINT8 Memp_Memory[CH57xNET_MEMP_SIZE]; 48 __align(4)UINT8 Mem_Heap_Memory[CH57xNET_RAM_HEAP_SIZE]; 49 __align(4)UINT8 Mem_ArpTable[CH57xNET_RAM_ARP_TABLE_SIZE]; 50 /******************************************************************************/ 51 /* 本演示程序的相关宏 */ 52 #define RECE_BUF_LEN 536 //接收缓冲区的大小 53 /* CH57xNET库TCP的MSS长度为536字节,即一个TCP包里的数据部分最长为536字节 */ 54 /* TCP协议栈采用滑动窗口进行流控,窗口最大值为socket的接收缓冲区长度。在设定 */ 55 /* RX_QUEUE_ENTRIES时要考虑MSS和窗口之间的关系,例如窗口值为4*MSS,则远端一次会发送 */ 56 /* 4个TCP包,如果RX_QUEUE_ENTRIES小于4,则必然会导致数据包丢失,从而导致通讯效率降低 */ 57 /* 建议RX_QUEUE_ENTRIES要大于( 窗口/MSS ),如果多个socket同时进行大批量发送数据,则 */ 58 /* 建议RX_QUEUE_ENTRIES要大于(( 窗口/MSS )*socket个数) 在多个socket同时进行大批数据收发时 */ 59 /* 为了节约RAM,请将接收缓冲区的长度设置为MSS */ 60 61 /* CH579相关定义 */ 62 UINT8 MACAddr[6] = {0x84,0xc2,0xe4,0x02,0x03,0x04}; //CH579MAC地址 63 UINT8 IPAddr[4] = {0}; //CH579IP地址 64 UINT8 GWIPAddr[4] = {192,168,1,1}; //CH579网关 65 UINT8 IPMask[4] = {255,255,255,0}; //CH579子网掩码 66 UINT8 DESIP[4] = {192,168,1,100}; //目的IP地址 67 68 UINT8 SocketId; //保存socket索引,可以不用定义 69 UINT8 SocketRecvBuf[RECE_BUF_LEN]; //socket接收缓冲区 70 UINT8 MyBuf[RECE_BUF_LEN]; //定义一个临时缓冲区 71 72 73 //extern const UINT16 *memp_num; 74 75 /******************************************************************************* 76 * Function Name : IRQ_Handler 77 * Description : IRQ中断服务函数 78 * Input : None 79 * Output : None 80 * Return : None 81 *******************************************************************************/ 82 void ETH_IRQHandler( void ) //以太网中断 83 { 84 CH57xNET_ETHIsr(); //以太网中断中断服务函数 85 } 86 87 void TMR0_IRQHandler( void ) //定时器中断 88 { 89 CH57xNET_TimeIsr(CH57xNETTIMEPERIOD); //定时器中断服务函数 90 R8_TMR0_INT_FLAG |= 0xff; //清除定时器中断标志 91 } 92 93 94 95 /******************************************************************************* 96 * Function Name : mStopIfError 97 * Description : 调试使用,显示错误代码 98 * Input : iError 错误代码 99 * Output : None 100 * Return : None 101 *******************************************************************************/ 102 void mStopIfError(UINT8 iError) 103 { 104 if (iError == CH57xNET_ERR_SUCCESS) return; //操作成功 105 PRINT("mStopIfError: %02X\r\n", (UINT16)iError); //显示错误 106 } 107 108 109 /******************************************************************************* 110 * Function Name : CH57xNET_CreatTcpSocket 111 * Description : 创建TCP Client socket 112 * Input : None 113 * Output : None 114 * Return : None 115 *******************************************************************************/ 116 void CH57xNET_CreatTcpSocket(void) 117 { 118 UINT8 i; 119 SOCK_INF TmpSocketInf;//创建临时socket变量 */ 120 121 memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF)); //库内部会将此变量复制,所以最好将临时变量先全部清零 122 memcpy((void *)TmpSocketInf.IPAddr,DESIP,4); //设置目的IP地址 123 TmpSocketInf.DesPort = 1000; 124 TmpSocketInf.SourPort = 2000; //设置源端口 125 TmpSocketInf.ProtoType = PROTO_TYPE_TCP; //设置socekt类型 126 TmpSocketInf.RecvStartPoint = (UINT32)SocketRecvBuf; //设置接收缓冲区的接收缓冲区 127 TmpSocketInf.RecvBufLen = RECE_BUF_LEN;//设置接收缓冲区的接收长度 128 i = CH57xNET_SocketCreat(&SocketId,&TmpSocketInf);//创建socket,将返回的socket索引保存在SocketId中 129 mStopIfError(i);//检查错误 130 #ifdef KEEPLIVE_ENABLE 131 CH57xNET_SocketSetKeepLive( SocketId, 1 ); //开启socket的KEEPLIVE功能(V06版本支持) 132 #endif 133 134 i = CH57xNET_SocketConnect(SocketId); //TCP连接 135 mStopIfError(i); // 检查错误 136 i = CH57xNET_SetSocketTTL( SocketId,10 ); 137 mStopIfError(i); //检查错误 138 } 139 140 141 /******************************************************************************* 142 * Function Name : net_initkeeplive 143 * Description : keeplive初始化 144 * Input : None 145 * Output : None 146 * Return : None 147 *******************************************************************************/ 148 #ifdef KEEPLIVE_ENABLE 149 void net_initkeeplive(void) 150 { 151 struct _KEEP_CFG klcfg; 152 klcfg.KLIdle = 20000; //空闲 153 klcfg.KLIntvl = 10000; //间隔 154 klcfg.KLCount = 5; //次数 155 CH57xNET_ConfigKeepLive(&klcfg); 156 } 157 #endif 158 159 /******************************************************************************* 160 * Function Name : CH57xNET_LibInit 161 * Description : 库初始化操作 162 * Input : ip ip地址指针 163 * :gwip 网关ip地址指针 164 * : mask 掩码指针 165 * : macaddr MAC地址指针 166 * Output : None 167 * Return : 执行状态 168 *******************************************************************************/ 169 UINT8 CH57xNET_LibInit(UINT8 *ip,UINT8 *gwip,UINT8 *mask,UINT8 *macaddr) 170 { 171 UINT8 i; 172 struct _CH57x_CFG cfg; 173 174 if(CH57xNET_GetVer() != CH57xNET_LIB_VER)return 0xfc; //获取库的版本号,检查是否和头文件一致 175 CH57xNETConfig = LIB_CFG_VALUE; //将配置信息传递给库的配置变量 176 cfg.RxBufSize = RX_BUF_SIZE; 177 cfg.TCPMss = CH57xNET_TCP_MSS; 178 cfg.HeapSize = CH57x_MEM_HEAP_SIZE; 179 cfg.ARPTableNum = CH57xNET_NUM_ARP_TABLE; 180 cfg.MiscConfig0 = CH57xNET_MISC_CONFIG0; 181 CH57xNET_ConfigLIB(&cfg); 182 i = CH57xNET_Init(ip,gwip,mask,macaddr); 183 #ifdef KEEPLIVE_ENABLE 184 net_initkeeplive( ); 185 #endif 186 return (i); 187 } 188 189 /******************************************************************************* 190 * Function Name : CH57xNET_HandleSockInt 191 * Description : Socket中断处理函数 192 * Input : sockeid socket索引 193 * :initstat 中断状态 194 * Output : None 195 * Return : None 196 *******************************************************************************/ 197 void CH57xNET_HandleSockInt(UINT8 sockeid,UINT8 initstat) 198 { 199 UINT32 len; 200 UINT32 totallen; 201 UINT8 *p = MyBuf; 202 203 if(initstat & SINT_STAT_RECV) //接收中断 204 { 205 len = CH57xNET_SocketRecvLen(sockeid,NULL); //查询长度 206 PRINT("Receive Len = %d\r\n",len); 207 totallen = len; 208 CH57xNET_SocketRecv(sockeid,MyBuf,&len); //将接收缓冲区的数据读到MyBuf中 209 while(1) 210 { 211 len = totallen; 212 CH57xNET_SocketSend(sockeid,p,&len); //将MyBuf中的数据发送 213 totallen -= len; //将总长度减去以及发送完毕的长度 214 p += len; //将缓冲区指针偏移 215 if(totallen)continue; //如果数据未发送完毕,则继续发送 216 break; //发送完毕,退出 217 } 218 } 219 if(initstat & SINT_STAT_CONNECT) //TCP连接中断 220 { //产生此中断表示TCP已经连接,可以进行收发数据 221 PRINT("TCP Connect Success\n"); 222 } 223 if(initstat & SINT_STAT_DISCONNECT)//TCP断开中断 224 { //产生此中断,CH579库内部会将此socket清除,置为关闭 225 PRINT("TCP Disconnect\n"); //应用曾需可以重新创建连接 226 } 227 if(initstat & SINT_STAT_TIM_OUT) //TCP超时中断 228 { //产生此中断,CH579库内部会将此socket清除,置为关闭 229 PRINT("TCP Timout\n"); //应用曾需可以重新创建连接 230 } 231 } 232 233 234 /******************************************************************************* 235 * Function Name : CH57xNET_HandleGloableInt 236 * Description : 全局中断处理函数 237 * Input : None 238 * Output : None 239 * Return : None 240 *******************************************************************************/ 241 void CH57xNET_HandleGlobalInt(void) 242 { 243 UINT8 initstat; 244 UINT8 i; 245 UINT8 socketinit; 246 initstat = CH57xNET_GetGlobalInt(); //读全局中断状态并清除 247 if(initstat & GINT_STAT_UNREACH) //不可达中断 248 { 249 PRINT("UnreachCode :%d\n",CH57xInf.UnreachCode); //查看不可达代码 250 PRINT("UnreachProto :%d\n",CH57xInf.UnreachProto);//查看不可达协议类型 251 PRINT("UnreachPort :%d\n",CH57xInf.UnreachPort); //查询不可达端口 252 } 253 if(initstat & GINT_STAT_IP_CONFLI) //IP冲突中断 254 { 255 256 } 257 if(initstat & GINT_STAT_PHY_CHANGE) //PHY改变中断 258 { 259 i = CH57xNET_GetPHYStatus(); //获取PHY状态 260 PRINT("GINT_STAT_PHY_CHANGE %02x\n",i); 261 } 262 if(initstat & GINT_STAT_SOCKET) //Socket中断 263 { 264 for(i = 0; i < CH57xNET_MAX_SOCKET_NUM; i ++) 265 { 266 socketinit = CH57xNET_GetSocketInt(i); //读socket中断并清零 267 if(socketinit)CH57xNET_HandleSockInt(i,socketinit); //如果有中断则清零 268 } 269 } 270 } 271 272 /******************************************************************************* 273 * Function Name : Timer0Init 274 * Description : 定时器1初始化 275 * Input : time 定时时间 276 * Output : None 277 * Return : None 278 *******************************************************************************/ 279 void Timer0Init(UINT32 time) 280 { 281 R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;//清除所有计数值 282 R8_TMR0_CTRL_MOD = 0; //设置定时器模式 283 R32_TMR0_CNT_END = FREQ_SYS/1000000*time; //设置定时时间 284 R8_TMR0_INT_FLAG = R8_TMR0_INT_FLAG;//清除标志 285 R8_TMR0_INTER_EN = RB_TMR_IE_CYC_END;//定时中断 286 R8_TMR0_CTRL_MOD |= RB_TMR_COUNT_EN; 287 NVIC_EnableIRQ(TMR0_IRQn); 288 } 289 290 291 /******************************************************************************* 292 * Function Name : CH57xNET_DHCPCallBack 293 * Description : DHCP回调函数 294 * Input : None 295 * Output : None 296 * Return : 执行状态 297 *******************************************************************************/ 298 UINT8 CH57xNET_DHCPCallBack(UINT8 status,void *arg) 299 { 300 UINT8 *p; 301 302 if(!status){ //成功 303 p = arg; //产生此中断,CH57xNET库内部会将此socket清除,置为关闭 304 PRINT("DHCP Success\n"); 305 memcpy(IPAddr,p,4); 306 memcpy(GWIPAddr,&p[4],4); 307 memcpy(IPMask,&p[8],4); //产生此中断,CH57xNET库内部会将此socket清除,置为关闭 308 PRINT("IPAddr = %d.%d.%d.%d \n",(UINT16)IPAddr[0],(UINT16)IPAddr[1], 309 (UINT16)IPAddr[2],(UINT16)IPAddr[3]); 310 PRINT("GWIPAddr = %d.%d.%d.%d \n",(UINT16)GWIPAddr[0],(UINT16)GWIPAddr[1], 311 (UINT16)GWIPAddr[2],(UINT16)GWIPAddr[3]); 312 PRINT("IPAddr = %d.%d.%d.%d \n",(UINT16)IPMask[0],(UINT16)IPMask[1], 313 (UINT16)IPMask[2],(UINT16)IPMask[3]); 314 PRINT("DNS1: %d.%d.%d.%d\n",p[12],p[13],p[14],p[15]); 315 PRINT("DNS2: %d.%d.%d.%d\n",p[16],p[17],p[18],p[19]); 316 // CH57xNET_CreatTcpSocket(); //可以在此处,在DHCP完成后进行TCP连接 317 // PRINT("creat tcp sockrt!\r\n"); 318 } 319 else{ //产生此中断,CH57xNET库内部会将此socket清除,置为关闭 320 PRINT("DHCP Fail %02x\n",status); 321 } 322 return 0; 323 } 324 325 /******************************************************************************* 326 * Function Name : SystemClock_UART1_init 327 * Description : 系统时钟和串口1初始化,串口1用于打印输出 328 * Input : None 329 * Output : None 330 * Return : None 331 *******************************************************************************/ 332 void SystemClock_UART1_init(void) 333 { 334 PWR_UnitModCfg(ENABLE, UNIT_SYS_PLL); //PLL上电 335 DelsyMs(3); 336 SetSysClock(CLK_SOURCE_HSE_32MHz); //外部晶振 PLL 输出32MHz 337 GPIOA_SetBits( GPIO_Pin_9 ); 338 GPIOA_ModeCfg( GPIO_Pin_9, GPIO_ModeOut_PP_5mA ); //串口1的IO口设置 339 UART1_DefInit( ); //串口1初始化 340 } 341 342 /******************************************************************************* 343 * Function Name : main 344 * Description : 主函数 345 * Input : None 346 * Output : None 347 * Return : None 348 *******************************************************************************/ 349 int main(void) 350 { 351 UINT8 i = 0; 352 353 SystemClock_UART1_init(); 354 i = CH57xNET_LibInit(IPAddr,GWIPAddr,IPMask,MACAddr); //库初始化 355 mStopIfError(i); //检查错误 356 PRINT("CH57xNETLibInit Success\r\n"); 357 Timer0Init( 10000 ); //初始化定时器:10ms 358 NVIC_EnableIRQ(ETH_IRQn); 359 while ( CH57xInf.PHYStat < 2 ) DelsyMs(50); 360 if(!i)CH57xNET_DHCPStart(CH57xNET_DHCPCallBack); //启动DHCP 361 PRINT("CH579 dhcp client create!\r\n"); 362 while(1) 363 { 364 CH57xNET_MainTask();//CH57xNET库主任务函数,需要在主循环中不断调用 365 if(CH57xNET_QueryGlobalInt())CH57xNET_HandleGlobalInt(); //查询中断,如果有中断,则调用全局中断处理函数 366 } 367 } 368 /*********************************** endfile **********************************/
CH57xNETLibInit Success CH579 dhcp client create! GINT_STAT_PHY_CHANGE 02 DHCP Success IPAddr = 192.168.1.11 GWIPAddr = 192.168.1.1 IPAddr = 255.255.255.0 DNS1: 168.126.63.1 DNS2: 168.126.63.2
TCP_Client
1 /********************************** (C) COPYRIGHT ****************************** 2 * File Name : TCP_Client.c 3 * Author : WCH 4 * Version : V1.0 5 * Date : 2018/12/01 6 * Description : CH57xNET库演示文件 7 * (1)、CH579 Examples by KEIL; 8 * (2)、串口1输出监控信息,115200bps,打开或者关闭调试信息输出在IDE宏定义中设置; 9 * (3)、本程序用于演示TCP 客户端通讯,单片机收到数据后,回传给目标IP上位机 10 *******************************************************************************/ 11 12 13 14 /******************************************************************************/ 15 /* 头文件包含*/ 16 #include <stdio.h> 17 #include <string.h> 18 #include "CH57x_common.h" 19 #include "core_cm0.h" 20 #include "CH57xNET.h" 21 22 #define KEEPLIVE_ENABLE 1 //开启KEEPLIVE功能 23 24 /* 下面的缓冲区和全局变量必须要定义,库中调用 */ 25 __align(16)UINT8 CH57xMACRxDesBuf[(RX_QUEUE_ENTRIES )*16]; //MAC接收描述符缓冲区,16字节对齐 26 __align(4) UINT8 CH57xMACRxBuf[RX_QUEUE_ENTRIES*RX_BUF_SIZE]; //MAC接收缓冲区,4字节对齐 27 __align(4) SOCK_INF SocketInf[CH57xNET_MAX_SOCKET_NUM]; //Socket信息表,4字节对齐 28 29 UINT16 MemNum[8] = {CH57xNET_NUM_IPRAW, 30 CH57xNET_NUM_UDP, 31 CH57xNET_NUM_TCP, 32 CH57xNET_NUM_TCP_LISTEN, 33 CH57xNET_NUM_TCP_SEG, 34 CH57xNET_NUM_IP_REASSDATA, 35 CH57xNET_NUM_PBUF, 36 CH57xNET_NUM_POOL_BUF 37 }; 38 UINT16 MemSize[8] = {CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IPRAW_PCB), 39 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_UDP_PCB), 40 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB), 41 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB_LISTEN), 42 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_SEG), 43 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IP_REASSDATA), 44 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(0), 45 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_POOL_BUF) 46 }; 47 __align(4)UINT8 Memp_Memory[CH57xNET_MEMP_SIZE]; 48 __align(4)UINT8 Mem_Heap_Memory[CH57xNET_RAM_HEAP_SIZE]; 49 __align(4)UINT8 Mem_ArpTable[CH57xNET_RAM_ARP_TABLE_SIZE]; 50 /******************************************************************************/ 51 /* 本演示程序的相关宏 */ 52 #define RECE_BUF_LEN 536 // 接收缓冲区的大小 53 /* CH57xNET库TCP的MSS长度为536字节,即一个TCP包里的数据部分最长为536字节 */ 54 /* TCP协议栈采用滑动窗口进行流控,窗口最大值为socket的接收缓冲区长度。在设定 */ 55 /* RX_QUEUE_ENTRIES时要考虑MSS和窗口之间的关系,例如窗口值为4*MSS,则远端一次会发送 */ 56 /* 4个TCP包,如果RX_QUEUE_ENTRIES小于4,则必然会导致数据包丢失,从而导致通讯效率降低 */ 57 /* 建议RX_QUEUE_ENTRIES要大于( 窗口/MSS ),如果多个socket同时进行大批量发送数据,则 */ 58 /* 建议RX_QUEUE_ENTRIES要大于(( 窗口/MSS )*socket个数) 在多个socket同时进行大批数据收发时 */ 59 /* 为了节约RAM,请将接收缓冲区的长度设置为MSS */ 60 61 /* CH579相关定义 */ 62 UINT8 MACAddr[6] ={0x84,0xc2,0xe4,0x02,0x03,0x04}; //CH579MAC地址 63 UINT8 IPAddr[4] = {192,168,1,200}; //CH579IP地址 64 UINT8 GWIPAddr[4]={192,168,1,1}; //CH579网关 65 UINT8 IPMask[4] = {255,255,255,0}; //CH579子网掩码 66 UINT8 DESIP[4] = {192,168,1,19}; //目的IP地址 67 68 UINT8 SocketId; //保存socket索引,可以不用定义 69 UINT8 SocketRecvBuf[RECE_BUF_LEN]; //socket接收缓冲区 70 UINT8 MyBuf[RECE_BUF_LEN]; //定义一个临时缓冲区 71 72 73 //extern const UINT16 *memp_num; 74 75 /******************************************************************************* 76 * Function Name : IRQ_Handler 77 * Description : IRQ中断服务函数 78 * Input : None 79 * Output : None 80 * Return : None 81 *******************************************************************************/ 82 void ETH_IRQHandler( void ) //以太网中断 83 { 84 CH57xNET_ETHIsr(); //以太网中断中断服务函数 85 } 86 87 void TMR0_IRQHandler( void ) //定时器中断 88 { 89 CH57xNET_TimeIsr(CH57xNETTIMEPERIOD); //定时器中断服务函数 90 R8_TMR0_INT_FLAG |= 0xff; //清除定时器中断标志 91 } 92 93 94 95 /******************************************************************************* 96 * Function Name : mStopIfError 97 * Description : 调试使用,显示错误代码 98 * Input : iError 错误代码 99 * Output : None 100 * Return : None 101 *******************************************************************************/ 102 void mStopIfError(UINT8 iError) 103 { 104 if (iError == CH57xNET_ERR_SUCCESS) return; //操作成功 105 PRINT("mStopIfError: %02X\r\n", (UINT16)iError); //显示错误 106 } 107 108 /******************************************************************************* 109 * Function Name : CH57xNET_CreatTcpSocket 110 * Description : 创建TCP Client socket 111 * Input : None 112 * Output : None 113 * Return : None 114 *******************************************************************************/ 115 void CH57xNET_CreatTcpSocket(void) 116 { 117 UINT8 i; 118 SOCK_INF TmpSocketInf; //创建临时socket变量 119 memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF)); //库内部会将此变量复制,所以最好将临时变量先全部清零 120 memcpy((void *)TmpSocketInf.IPAddr,DESIP,4); //设置目的IP地址 121 TmpSocketInf.DesPort = 1000; 122 TmpSocketInf.SourPort = 2000; //设置源端口 123 TmpSocketInf.ProtoType = PROTO_TYPE_TCP; //设置socekt类型 124 TmpSocketInf.RecvStartPoint = (UINT32)SocketRecvBuf;//设置接收缓冲区的接收缓冲区 125 TmpSocketInf.RecvBufLen = RECE_BUF_LEN ; //设置接收缓冲区的接收长度 126 i = CH57xNET_SocketCreat(&SocketId,&TmpSocketInf); //创建socket,将返回的socket索引保存在SocketId中 127 mStopIfError(i); //检查错误 128 #ifdef KEEPLIVE_ENABLE 129 CH57xNET_SocketSetKeepLive( SocketId, 1 ); //开启socket的KEEPLIVE功能(V06版本支持) 130 #endif 131 132 i = CH57xNET_SocketConnect(SocketId); //TCP连接 133 mStopIfError(i); //检查错误 134 i = CH57xNET_SetSocketTTL( SocketId,10 ); 135 mStopIfError(i); //检查错误 136 } 137 138 139 /******************************************************************************* 140 * Function Name : net_initkeeplive 141 * Description : keeplive初始化 142 * Input : None 143 * Output : None 144 * Return : None 145 *******************************************************************************/ 146 #ifdef KEEPLIVE_ENABLE 147 void net_initkeeplive(void) 148 { 149 struct _KEEP_CFG klcfg; 150 151 klcfg.KLIdle = 20000; //空闲 152 klcfg.KLIntvl = 10000; //间隔 153 klcfg.KLCount = 5; //次数 154 CH57xNET_ConfigKeepLive(&klcfg); 155 } 156 #endif 157 158 /******************************************************************************* 159 * Function Name : CH57xNET_LibInit 160 * Description : 库初始化操作 161 * Input : ip ip地址指针 162 * :gwip 网关ip地址指针 163 * : mask 掩码指针 164 * : macaddr MAC地址指针 165 * Output : None 166 * Return : 执行状态 167 *******************************************************************************/ 168 UINT8 CH57xNET_LibInit(UINT8 *ip,UINT8 *gwip,UINT8 *mask, UINT8 *macaddr) 169 { 170 UINT8 i; 171 struct _CH57x_CFG cfg; 172 173 if(CH57xNET_GetVer() != CH57xNET_LIB_VER)return 0xfc; //获取库的版本号,检查是否和头文件一致 174 CH57xNETConfig = LIB_CFG_VALUE; //将配置信息传递给库的配置变量 175 cfg.RxBufSize = RX_BUF_SIZE; 176 cfg.TCPMss = CH57xNET_TCP_MSS; 177 cfg.HeapSize = CH57x_MEM_HEAP_SIZE; 178 cfg.ARPTableNum = CH57xNET_NUM_ARP_TABLE; 179 cfg.MiscConfig0 = CH57xNET_MISC_CONFIG0; 180 CH57xNET_ConfigLIB(&cfg); 181 i = CH57xNET_Init(ip,gwip,mask,macaddr); 182 #ifdef KEEPLIVE_ENABLE 183 net_initkeeplive( ); 184 #endif 185 return (i); 186 } 187 188 /******************************************************************************* 189 * Function Name : CH57xNET_HandleSockInt 190 * Description : Socket中断处理函数 191 * Input : sockeid socket索引 192 * :initstat 中断状态 193 * Output : None 194 * Return : None 195 *******************************************************************************/ 196 void CH57xNET_HandleSockInt(UINT8 sockeid,UINT8 initstat) 197 { 198 UINT32 len; 199 UINT32 totallen; 200 UINT8 *p = MyBuf; 201 202 if(initstat & SINT_STAT_RECV) //接收中断 203 { 204 len = CH57xNET_SocketRecvLen(sockeid,NULL); //查询长度 205 PRINT("Receive Len = %d\r\n",len); 206 totallen = len; 207 CH57xNET_SocketRecv(sockeid,MyBuf,&len); //将接收缓冲区的数据读到MyBuf中 208 while(1) 209 { 210 len = totallen; 211 CH57xNET_SocketSend(sockeid,p,&len); //将MyBuf中的数据发送 212 totallen -= len; //将总长度减去以及发送完毕的长度 213 p += len; //将缓冲区指针偏移 214 if(totallen)continue; //如果数据未发送完毕,则继续发送 215 break; //发送完毕,退出 216 } 217 } 218 if(initstat & SINT_STAT_CONNECT) //TCP连接中断 219 { //产生此中断表示TCP已经连接,可以进行收发数据 220 PRINT("TCP Connect Success\n"); 221 } 222 if(initstat & SINT_STAT_DISCONNECT) //TCP断开中断 223 { //产生此中断,CH579库内部会将此socket清除,置为关闭 224 PRINT("TCP Disconnect\n"); //应用曾需可以重新创建连接 225 226 } 227 if(initstat & SINT_STAT_TIM_OUT) //TCP超时中断 228 { //产生此中断,CH579库内部会将此socket清除,置为关闭 229 PRINT("TCP Timout\n"); //应用曾需可以重新创建连接 230 231 } 232 } 233 234 235 /******************************************************************************* 236 * Function Name : CH57xNET_HandleGloableInt 237 * Description : 全局中断处理函数 238 * Input : None 239 * Output : None 240 * Return : None 241 *******************************************************************************/ 242 void CH57xNET_HandleGlobalInt(void) 243 { 244 UINT8 initstat; 245 UINT8 i; 246 UINT8 socketinit; 247 initstat = CH57xNET_GetGlobalInt(); //读全局中断状态并清除 248 if(initstat & GINT_STAT_UNREACH) //不可达中断 249 { 250 PRINT("UnreachCode :%d\n",CH57xInf.UnreachCode); //查看不可达代码 251 PRINT("UnreachProto :%d\n",CH57xInf.UnreachProto); //查看不可达协议类型 252 PRINT("UnreachPort :%d\n",CH57xInf.UnreachPort); //查询不可达端口 253 } 254 if(initstat & GINT_STAT_IP_CONFLI) //IP冲突中断 255 { 256 257 } 258 if(initstat & GINT_STAT_PHY_CHANGE) //PHY改变中断 259 { 260 i = CH57xNET_GetPHYStatus(); //获取PHY状态 261 PRINT("GINT_STAT_PHY_CHANGE %02x\n",i); 262 } 263 if(initstat & GINT_STAT_SOCKET) //Socket中断 264 { 265 for(i = 0; i < CH57xNET_MAX_SOCKET_NUM; i ++) 266 { 267 socketinit = CH57xNET_GetSocketInt(i); //读socket中断并清零 268 if(socketinit)CH57xNET_HandleSockInt(i,socketinit);//如果有中断则清零 269 } 270 } 271 } 272 273 /******************************************************************************* 274 * Function Name : Timer0Init 275 * Description : 定时器1初始化 276 * Input : time 定时时间 277 * Output : None 278 * Return : None 279 *******************************************************************************/ 280 void Timer0Init(UINT32 time) 281 { 282 R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR; //清除所有计数值 283 R8_TMR0_CTRL_MOD = 0; //设置定时器模式 284 R32_TMR0_CNT_END = FREQ_SYS/1000000*time; //设置定时时间 285 R8_TMR0_INT_FLAG = R8_TMR0_INT_FLAG; //清除标志 286 R8_TMR0_INTER_EN = RB_TMR_IE_CYC_END; //定时中断 287 R8_TMR0_CTRL_MOD |= RB_TMR_COUNT_EN; 288 NVIC_EnableIRQ(TMR0_IRQn); 289 } 290 291 /******************************************************************************* 292 * Function Name : SystemClock_UART1_init 293 * Description : 系统时钟和串口1初始化,串口1用于打印输出 294 * Input : None 295 * Output : None 296 * Return : None 297 *******************************************************************************/ 298 void SystemClock_UART1_init(void) 299 { 300 PWR_UnitModCfg(ENABLE, UNIT_SYS_PLL); //PLL上电 301 DelsyMs(3); 302 SetSysClock(CLK_SOURCE_HSE_32MHz); //外部晶振 PLL 输出32MHz 303 GPIOA_SetBits( GPIO_Pin_9 ); 304 GPIOA_ModeCfg( GPIO_Pin_9, GPIO_ModeOut_PP_5mA );//串口1的IO口设置 305 UART1_DefInit( ); //串口1初始化 306 } 307 308 /******************************************************************************* 309 * Function Name : main 310 * Description : 主函数 311 * Input : None 312 * Output : None 313 * Return : None 314 *******************************************************************************/ 315 int main(void) 316 { 317 UINT8 i = 0; 318 319 SystemClock_UART1_init(); 320 i = CH57xNET_LibInit(IPAddr,GWIPAddr,IPMask,MACAddr); //库初始化 321 mStopIfError(i); //检查错误 322 PRINT("CH57xNETLibInit Success\r\n"); 323 Timer0Init( 10000 ); //初始化定时器:10ms 324 NVIC_EnableIRQ(ETH_IRQn); 325 while ( CH57xInf.PHYStat < 2 ) { 326 DelsyMs(50); 327 } 328 CH57xNET_CreatTcpSocket(); //创建TCP Socket 329 PRINT("CH579 TCP client create!\r\n"); 330 while(1) 331 { 332 CH57xNET_MainTask(); //CH57xNET库主任务函数,需要在主循环中不断调用 333 if(CH57xNET_QueryGlobalInt())CH57xNET_HandleGlobalInt();//查询中断,如果有中断,则调用全局中断处理函数 334 } 335 } 336 337 /*********************************** endfile **********************************/
TCP_MultipleClients
4个单片机的Socket 同时连接到 电脑服务端
1 /********************************** (C) COPYRIGHT ****************************** 2 * File Name : TCP_Client_X.c 3 * Author : WCH 4 * Version : V1.0 5 * Date : 2018/12/01 6 * Description : CH57xNET库演示文件 7 * (1)、CH579 Examples by KEIL; 8 * (2)、串口1输出监控信息,115200bps,打开或者关闭调试打印信息输出请修改CH57xNET_DBG宏定义; 9 * (3)、本程序用于演示TCP 多客户端通讯(示例为4个),单片机收到数据后,回传给目标IP上位机 10 *******************************************************************************/ 11 12 13 14 /******************************************************************************/ 15 /* 头文件包含*/ 16 #include <stdio.h> 17 #include <string.h> 18 #include "CH57x_common.h" 19 #include "core_cm0.h" 20 #include "CH57xNET.H" 21 22 #define CH57xNET_DBG 1 23 #define KEEPLIVE_ENABLE 1 //开启KEEPLIVE功能 24 25 /* 下面的缓冲区和全局变量必须要定义,库中调用 */ 26 __align(16)UINT8 CH57xMACRxDesBuf[(RX_QUEUE_ENTRIES )*16]; //MAC接收描述符缓冲区,16字节对齐 27 __align(4) UINT8 CH57xMACRxBuf[RX_QUEUE_ENTRIES*RX_BUF_SIZE];//MAC接收缓冲区,4字节对齐 28 __align(4) SOCK_INF SocketInf[CH57xNET_MAX_SOCKET_NUM]; //Socket信息表,4字节对齐 29 30 UINT16 MemNum[8] = {CH57xNET_NUM_IPRAW, 31 CH57xNET_NUM_UDP, 32 CH57xNET_NUM_TCP, 33 CH57xNET_NUM_TCP_LISTEN, 34 CH57xNET_NUM_TCP_SEG, 35 CH57xNET_NUM_IP_REASSDATA, 36 CH57xNET_NUM_PBUF, 37 CH57xNET_NUM_POOL_BUF 38 }; 39 UINT16 MemSize[8] = {CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IPRAW_PCB), 40 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_UDP_PCB), 41 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB), 42 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB_LISTEN), 43 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_SEG), 44 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IP_REASSDATA), 45 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(0), 46 CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_POOL_BUF) 47 }; 48 __align(4)UINT8 Memp_Memory[CH57xNET_MEMP_SIZE]; 49 __align(4)UINT8 Mem_Heap_Memory[CH57xNET_RAM_HEAP_SIZE]; 50 __align(4)UINT8 Mem_ArpTable[CH57xNET_RAM_ARP_TABLE_SIZE]; 51 /******************************************************************************/ 52 /* 本演示程序的相关宏 */ 53 #define RECE_BUF_LEN 536 //接收缓冲区的大小 54 /* CH57xNET库TCP的MSS长度为536字节,即一个TCP包里的数据部分最长为536字节 */ 55 /* TCP协议栈采用滑动窗口进行流控,窗口最大值为socket的接收缓冲区长度。在设定 */ 56 /* RX_QUEUE_ENTRIES时要考虑MSS和窗口之间的关系,例如窗口值为4*MSS,则远端一次会发送 */ 57 /* 4个TCP包,如果RX_QUEUE_ENTRIES小于4,则必然会导致数据包丢失,从而导致通讯效率降低 */ 58 /* 建议RX_QUEUE_ENTRIES要大于( 窗口/MSS ),如果多个socket同时进行大批量发送数据,则 */ 59 /* 建议RX_QUEUE_ENTRIES要大于(( 窗口/MSS )*socket个数) 在多个socket同时进行大批数据收发时 */ 60 /* 为了节约RAM,请将接收缓冲区的长度设置为MSS */ 61 62 /* CH579相关定义 */ 63 UINT8 MACAddr[6]= {0x84,0xc2,0xe4,0x02,0x03,0x04};//CH579MAC地址 64 UINT8 IPAddr[4] = {192,168,1,200};//CH579IP地址 65 UINT8 GWIPAddr[4]={192,168,1,1}; //CH579网关 66 UINT8 IPMask[4] = {255,255,255,0};// CH579子网掩码 67 UINT8 DESIP[4] = {192,168,1,19}; //目的IP地址 68 69 UINT8 SocketId1;//保存socket索引,可以不用定义 70 UINT8 SocketId2;//保存socket索引,可以不用定义 71 UINT8 SocketId3;//保存socket索引,可以不用定义 72 UINT8 SocketId4; 73 74 UINT8 Socket1RecvBuf[RECE_BUF_LEN];//socket1接收缓冲区 75 UINT8 Socket2RecvBuf[RECE_BUF_LEN];//socket2接收缓冲区 76 UINT8 Socket3RecvBuf[RECE_BUF_LEN];//socket3接收缓冲区 77 UINT8 Socket4RecvBuf[RECE_BUF_LEN];//socket4接收缓冲区 78 UINT8 MyBuf[RECE_BUF_LEN];//定义一个临时缓冲区 79 80 81 82 /******************************************************************************* 83 * Function Name : IRQ_Handler 84 * Description : IRQ中断服务函数 85 * Input : None 86 * Output : None 87 * Return : None 88 *******************************************************************************/ 89 void ETH_IRQHandler( void )//以太网中断 90 { 91 CH57xNET_ETHIsr();//以太网中断中断服务函数 92 } 93 94 void TMR0_IRQHandler( void ) //定时器中断 95 { 96 CH57xNET_TimeIsr(CH57xNETTIMEPERIOD);//定时器中断服务函数 97 R8_TMR0_INT_FLAG |= 0xff;//清除定时器中断标志 98 } 99 100 101 102 /******************************************************************************* 103 * Function Name : mStopIfError 104 * Description : 调试使用,显示错误代码 105 * Input : iError 错误代码 106 * Output : None 107 * Return : None 108 *******************************************************************************/ 109 void mStopIfError(UINT8 iError) 110 { 111 if (iError == CH57xNET_ERR_SUCCESS) return; // 操作成功 112 #if CH57xNET_DBG 113 printf("mStopIfError: %02X\r\n", (UINT16)iError); //显示错误 114 #endif 115 } 116 117 118 /******************************************************************************* 119 * Function Name : CH57xNET_CreatTcpSocket 120 * Description : 创建第一个TCP Client socket 121 * Input : None 122 * Output : None 123 * Return : None 124 *******************************************************************************/ 125 void CH57xNET_CreatTcpSocket1(void) 126 { 127 UINT8 i; 128 SOCK_INF TmpSocketInf;//创建临时socket变量 129 130 memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF)); //库内部会将此变量复制,所以最好将临时变量先全部清零 131 memcpy((void *)TmpSocketInf.IPAddr,DESIP,4); //设置目的IP地址 132 TmpSocketInf.DesPort = 1000; 133 TmpSocketInf.SourPort = 2000; //设置源端口 134 TmpSocketInf.ProtoType = PROTO_TYPE_TCP;//设置socekt类型 135 TmpSocketInf.RecvStartPoint = (UINT32)Socket1RecvBuf; //设置接收缓冲区的接收缓冲区 136 TmpSocketInf.RecvBufLen = RECE_BUF_LEN ; //设置接收缓冲区的接收长度 137 i = CH57xNET_SocketCreat(&SocketId1,&TmpSocketInf);//创建socket,将返回的socket索引保存在SocketId中 138 mStopIfError(i); // 检查错误 */ 139 #ifdef KEEPLIVE_ENABLE 140 CH57xNET_SocketSetKeepLive( SocketId1, 1 ); //开启socket的KEEPLIVE功能(V06版本支持) 141 #endif 142 143 i = CH57xNET_SocketConnect(SocketId1); //TCP连接 144 mStopIfError(i); //检查错误 145 i = CH57xNET_SetSocketTTL( SocketId1,10 ); 146 mStopIfError(i); //检查错误 147 } 148 149 /******************************************************************************* 150 * Function Name : CH57xNET_CreatTcpSocket 151 * Description : 创建第二个TCP Client socket 152 * Input : None 153 * Output : None 154 * Return : None 155 *******************************************************************************/ 156 void CH57xNET_CreatTcpSocket2(void) 157 { 158 UINT8 i; 159 SOCK_INF TmpSocketInf; //创建临时socket变量 */ 160 161 memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF)); //库内部会将此变量复制,所以最好将临时变量先全部清零 162 memcpy((void *)TmpSocketInf.IPAddr,DESIP,4); //设置目的IP地址 163 TmpSocketInf.DesPort = 1000; 164 TmpSocketInf.SourPort = 4000; //设置源端口 165 TmpSocketInf.ProtoType = PROTO_TYPE_TCP; //设置socekt类型 166 TmpSocketInf.RecvStartPoint = (UINT32)Socket2RecvBuf;//设置接收缓冲区的接收缓冲区 167 TmpSocketInf.RecvBufLen = RECE_BUF_LEN ;//设置接收缓冲区的接收长度 168 i = CH57xNET_SocketCreat(&SocketId2,&TmpSocketInf); // 创建socket,将返回的socket索引保存在SocketId中 169 mStopIfError(i);// 检查错误 */ 170 #ifdef KEEPLIVE_ENABLE 171 CH57xNET_SocketSetKeepLive( SocketId2, 1 ); //开启socket的KEEPLIVE功能 172 #endif 173 i = CH57xNET_SocketConnect(SocketId2); //TCP连接 174 mStopIfError(i); //检查错误 175 i = CH57xNET_SetSocketTTL( SocketId2,10 ); 176 mStopIfError(i);//检查错误 177 } 178 179 180 /******************************************************************************* 181 * Function Name : CH57xNET_CreatTcpSocket 182 * Description : 创建第二个TCP Client socket 183 * Input : None 184 * Output : None 185 * Return : None 186 *******************************************************************************/ 187 void CH57xNET_CreatTcpSocket3(void) 188 { 189 UINT8 i; 190 SOCK_INF TmpSocketInf; //创建临时socket变量 191 192 memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF)); //库内部会将此变量复制,所以最好将临时变量先全部清零 193 memcpy((void *)TmpSocketInf.IPAddr,DESIP,4); //设置目的IP地址 194 TmpSocketInf.DesPort = 1000; 195 TmpSocketInf.SourPort = 6000; //设置源端口 196 TmpSocketInf.ProtoType = PROTO_TYPE_TCP;//设置socekt类型 197 TmpSocketInf.RecvStartPoint = (UINT32)Socket3RecvBuf; //设置接收缓冲区的接收缓冲区 198 TmpSocketInf.RecvBufLen = RECE_BUF_LEN ; //设置接收缓冲区的接收长度 199 i = CH57xNET_SocketCreat(&SocketId3,&TmpSocketInf); //创建socket,将返回的socket索引保存在SocketId中 200 mStopIfError(i); //检查错误 */ 201 #ifdef KEEPLIVE_ENABLE 202 CH57xNET_SocketSetKeepLive( SocketId3, 1 ); //开启socket的KEEPLIVE功能 203 #endif 204 205 i = CH57xNET_SocketConnect(SocketId3); //TCP连接 206 mStopIfError(i); //检查错误 207 i = CH57xNET_SetSocketTTL( SocketId3,10 ); 208 mStopIfError(i);//检查错误 209 } 210 211 void CH57xNET_CreatTcpSocket4(void) 212 { 213 UINT8 i; 214 SOCK_INF TmpSocketInf; //创建临时socket变量 */ 215 216 memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF));//库内部会将此变量复制,所以最好将临时变量先全部清零 217 memcpy((void *)TmpSocketInf.IPAddr,DESIP,4); //设置目的IP地址 218 TmpSocketInf.DesPort = 1000; 219 TmpSocketInf.SourPort = 8000; //设置源端口 220 TmpSocketInf.ProtoType = PROTO_TYPE_TCP; //设置socekt类型 221 TmpSocketInf.RecvStartPoint = (UINT32)Socket3RecvBuf; //设置接收缓冲区的接收缓冲区 222 TmpSocketInf.RecvBufLen = RECE_BUF_LEN ; //设置接收缓冲区的接收长度 223 i = CH57xNET_SocketCreat(&SocketId4,&TmpSocketInf); //创建socket,将返回的socket索引保存在SocketId中 224 mStopIfError(i); //检查错误 */ 225 #ifdef KEEPLIVE_ENABLE 226 CH57xNET_SocketSetKeepLive( SocketId4, 1 ); //开启socket的KEEPLIVE功能 227 #endif 228 229 i = CH57xNET_SocketConnect(SocketId4); // TCP连接 230 mStopIfError(i); //检查错误 231 i = CH57xNET_SetSocketTTL( SocketId4,10 ); 232 mStopIfError(i); //检查错误 233 } 234 235 /******************************************************************************* 236 * Function Name : net_initkeeplive 237 * Description : keeplive初始化 238 * Input : None 239 * Output : None 240 * Return : None 241 *******************************************************************************/ 242 #ifdef KEEPLIVE_ENABLE 243 void net_initkeeplive(void) 244 { 245 struct _KEEP_CFG klcfg; 246 247 klcfg.KLIdle = 20000;//空闲 248 klcfg.KLIntvl = 10000;//间隔 249 klcfg.KLCount = 5; //次数 250 CH57xNET_ConfigKeepLive(&klcfg); 251 } 252 #endif 253 254 /******************************************************************************* 255 * Function Name : CH57xNET_LibInit 256 * Description : 库初始化操作 257 * Input : ip ip地址指针 258 * :gwip 网关ip地址指针 259 * : mask 掩码指针 260 * : macaddr MAC地址指针 261 * Output : None 262 * Return : 执行状态 263 *******************************************************************************/ 264 UINT8 CH57xNET_LibInit(UINT8 *ip, UINT8 *gwip, UINT8 *mask, UINT8 *macaddr) 265 { 266 UINT8 i; 267 struct _CH57x_CFG cfg; 268 269 if(CH57xNET_GetVer() != CH57xNET_LIB_VER)return 0xfc;//获取库的版本号,检查是否和头文件一致 270 CH57xNETConfig = LIB_CFG_VALUE;//将配置信息传递给库的配置变量 271 cfg.RxBufSize = RX_BUF_SIZE; 272 cfg.TCPMss = CH57xNET_TCP_MSS; 273 cfg.HeapSize = CH57x_MEM_HEAP_SIZE; 274 cfg.ARPTableNum = CH57xNET_NUM_ARP_TABLE; 275 cfg.MiscConfig0 = CH57xNET_MISC_CONFIG0; 276 CH57xNET_ConfigLIB(&cfg); 277 i = CH57xNET_Init(ip,gwip,mask,macaddr); 278 #ifdef KEEPLIVE_ENABLE 279 net_initkeeplive( ); 280 #endif 281 return (i); //库初始化 282 } 283 284 /******************************************************************************* 285 * Function Name : CH57xNET_HandleSockInt 286 * Description : Socket中断处理函数 287 * Input : sockeid socket索引 288 * :initstat 中断状态 289 * Output : None 290 * Return : None 291 *******************************************************************************/ 292 void CH57xNET_HandleSockInt(UINT8 sockeid,UINT8 initstat) 293 { 294 UINT32 len; 295 UINT32 totallen; 296 UINT8 *p = MyBuf; 297 298 if(initstat & SINT_STAT_RECV)//接收中断 299 { 300 len = CH57xNET_SocketRecvLen(sockeid,NULL);//查询长度 301 #if CH57xNET_DBG 302 printf("Receive Len = %d\r\n",len); 303 #endif 304 totallen = len; 305 CH57xNET_SocketRecv(sockeid,MyBuf,&len);//将接收缓冲区的数据读到MyBuf中 306 while(1) 307 { 308 len = totallen; 309 CH57xNET_SocketSend(sockeid,p,&len); //将MyBuf中的数据发送 310 totallen -= len; //将总长度减去以及发送完毕的长度 311 p += len; //将缓冲区指针偏移 312 if(totallen)continue;//如果数据未发送完毕,则继续发送 313 break; //发送完毕,退出 314 } 315 } 316 if(initstat & SINT_STAT_CONNECT) //TCP连接中断 317 {//产生此中断表示TCP已经连接,可以进行收发数据 318 #if CH57xNET_DBG 319 printf("TCP Connect Success\n"); 320 #endif 321 } 322 if(initstat & SINT_STAT_DISCONNECT)//TCP断开中断 323 {//产生此中断,CH579库内部会将此socket清除,置为关闭 324 #if CH57xNET_DBG 325 printf("TCP Disconnect\n"); // 应用曾需可以重新创建连接 326 #endif 327 } 328 if(initstat & SINT_STAT_TIM_OUT) //TCP超时中断 329 {//产生此中断,CH579库内部会将此socket清除,置为关闭 330 #if CH57xNET_DBG 331 printf("TCP Timout\n"); //应用曾需可以重新创建连接 332 #endif 333 // if(sockeid==SocketId1) 334 // CH57xNET_CreatTcpSocket1(); 335 // if(sockeid==SocketId2) 336 // CH57xNET_CreatTcpSocket2(); 337 // if(sockeid==SocketId3) 338 // CH57xNET_CreatTcpSocket3(); 339 // 340 } 341 } 342 343 344 /******************************************************************************* 345 * Function Name : CH57xNET_HandleGloableInt 346 * Description : 全局中断处理函数 347 * Input : None 348 * Output : None 349 * Return : None 350 *******************************************************************************/ 351 void CH57xNET_HandleGlobalInt(void) 352 { 353 UINT8 initstat; 354 UINT8 i; 355 UINT8 socketinit; 356 initstat = CH57xNET_GetGlobalInt(); //读全局中断状态并清除 357 if(initstat & GINT_STAT_UNREACH) //不可达中断 358 { 359 #if CH57xNET_DBG 360 printf("UnreachCode :%d\n",CH57xInf.UnreachCode); //查看不可达代码 361 printf("UnreachProto :%d\n",CH57xInf.UnreachProto);//查看不可达协议类型 362 printf("UnreachPort :%d\n",CH57xInf.UnreachPort); //查询不可达端口 363 #endif 364 } 365 if(initstat & GINT_STAT_IP_CONFLI)//IP冲突中断 366 { 367 368 } 369 if(initstat & GINT_STAT_PHY_CHANGE)//PHY改变中断 370 { 371 i = CH57xNET_GetPHYStatus();//获取PHY状态 372 #if CH57xNET_DBG 373 printf("GINT_STAT_PHY_CHANGE %02x\n",i); 374 #endif 375 } 376 if(initstat & GINT_STAT_SOCKET) //Socket中断 377 { 378 for(i = 0; i < CH57xNET_MAX_SOCKET_NUM; i ++) 379 { 380 socketinit = CH57xNET_GetSocketInt(i);//读socket中断并清零 381 if(socketinit)CH57xNET_HandleSockInt(i,socketinit);//如果有中断则清零 382 } 383 } 384 } 385 386 387 /******************************************************************************* 388 * Function Name : Timer0Init 389 * Description : 定时器1初始化 390 * Input : time 定时时间 391 * Output : None 392 * Return : None 393 *******************************************************************************/ 394 void Timer0Init(UINT32 time) 395 { 396 R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR; //清除所有计数值 397 R8_TMR0_CTRL_MOD = 0; //设置定时器模式 398 R32_TMR0_CNT_END = FREQ_SYS/1000000*time; //设置定时时间 399 R8_TMR0_INT_FLAG = R8_TMR0_INT_FLAG; //清除标志 400 R8_TMR0_INTER_EN = RB_TMR_IE_CYC_END; //定时中断 401 R8_TMR0_CTRL_MOD |= RB_TMR_COUNT_EN; 402 NVIC_EnableIRQ(TMR0_IRQn); 403 } 404 405 /******************************************************************************* 406 * Function Name : Timer0Init 407 * Description : 系统时钟和串口1初始化,串口1用于打印输出 408 * Input : None 409 * Output : None 410 * Return : None 411 *******************************************************************************/ 412 void SystemClock_UART1_init(void) 413 { 414 PWR_UnitModCfg(ENABLE, UNIT_SYS_PLL); //PLL上电 415 DelsyMs(3); 416 SetSysClock(CLK_SOURCE_HSE_32MHz);//外部晶振 PLL 输出32MHz 417 GPIOA_SetBits( GPIO_Pin_9 ); 418 GPIOA_ModeCfg( GPIO_Pin_9, GPIO_ModeOut_PP_5mA );//串口1的IO口设置 419 UART1_DefInit( ); //串口1初始化 420 } 421 422 423 /******************************************************************************* 424 * Function Name : main 425 * Description : 主函数 426 * Input : None 427 * Output : None 428 * Return : None 429 *******************************************************************************/ 430 int main(void) 431 { 432 UINT8 i = 0; 433 434 SystemClock_UART1_init(); 435 i = CH57xNET_LibInit(IPAddr,GWIPAddr,IPMask,MACAddr); //库初始化 436 mStopIfError(i); //检查错误 437 438 #if CH57xNET_DBG 439 printf("CH57xNETLibInit Success\r\n"); 440 #endif 441 Timer0Init( 10000 ); //初始化定时器:10ms 442 NVIC_EnableIRQ(ETH_IRQn); //打开以太网中断 443 while ( CH57xInf.PHYStat < 2 ) DelsyMs(50); 444 CH57xNET_CreatTcpSocket1(); //创建第一个TCP Socket 445 CH57xNET_CreatTcpSocket2(); //创建第二个TCP Socket 446 CH57xNET_CreatTcpSocket3(); 447 CH57xNET_CreatTcpSocket4(); 448 449 #if CH57xNET_DBG 450 printf("CH579 TCP clients created!\r\n"); 451 #endif 452 while(1) 453 { 454 CH57xNET_MainTask(); //CH57xNET库主任务函数,需要在主循环中不断调用 455 if(CH57xNET_QueryGlobalInt())CH57xNET_HandleGlobalInt(); //查询中断,如果有中断,则调用全局中断处理函数 456 } 457 } 458 459 /*********************************** endfile **********************************/
原文:https://www.cnblogs.com/kingboy100/p/12419877.html