📄 w5100.c
字号:
Write_W5100((W5100_S0_CR+s*0x100),S_CR_CONNECT); /*设置Socket为Connect模式*/
return TRUE;
/*至此完成了Socket的打开连接工作,至于它是否与远程服务器建立连接,则需要等待Socket中断,
以判断Socket的连接是否成功。参考W5100数据手册的Socket中断状态*/
}
/*-----------------------------------------------------------------------------
设置Socket作为服务器等待远程主机的连接
当本机Socket工作在服务器模式时,引用该程序,等等远程主机的连接
如果设置成功则返回true, 否则返回false
该程序只调用一次,就使W5100设置为服务器模式
-----------------------------------------------------------------------------*/
unsigned char Socket_Listen(SOCKET s)
{
Write_W5100((W5100_S0_MR+s*0x100), S_MR_TCP); /*设置socket为TCP模式 */
Write_W5100((W5100_S0_CR+s*0x100), S_CR_OPEN); /*打开Socket*/
if(Read_W5100(W5100_S0_SSR+s*0x100)!=S_SSR_INIT)
{
Write_W5100((W5100_S0_CR+s*0x100),S_CR_CLOSE); /*打开不成功,关闭Socket,然后返回*/
return FALSE;
}
Write_W5100((W5100_S0_CR+s*0x100), S_CR_LISTEN); /*设置Socket为侦听模式*/
if(Read_W5100(W5100_S0_SSR+s*0x100)!=S_SSR_LISTEN)
{
Write_W5100((W5100_S0_CR+s*0x100), S_CR_CLOSE); /*设置不成功,关闭Socket,然后返回*/
return FALSE;
}
return TRUE;
/*至此完成了Socket的打开和设置侦听工作,至于远程客户端是否与它建立连接,则需要等待Socket中断,
以判断Socket的连接是否成功。参考W5100数据手册的Socket中断状态
在服务器侦听模式不需要设置目的IP和目的端口号*/
}
/*-----------------------------------------------------------------------------
设置Socket为UDP模式
如果Socket工作在UDP模式,引用该程序。在UDP模式下,Socket通信不需要建立连接
如果设置成功则返回true, 否则返回false
该程序只调用一次,就使W5100设置为UDP模式
-----------------------------------------------------------------------------*/
unsigned char Socket_UDP(SOCKET s)
{
Write_W5100((W5100_S0_MR+s*0x100), S_MR_UDP); /*设置Socket为UDP模式*/
Write_W5100((W5100_S0_CR+s*0x100), S_CR_OPEN); /*打开Socket*/
if(Read_W5100(W5100_S0_SSR+s*0x100)!=S_SSR_UDP)
{
Write_W5100((W5100_S0_CR+s*0x100), S_CR_CLOSE); /*打开不成功,关闭Socket,然后返回*/
return FALSE;
}
else
return TRUE;
/*至此完成了Socket的打开和UDP模式设置,在这种模式下它不需要与远程主机建立连接
因为Socket不需要建立连接,所以在发送数据前都可以设置目的主机IP和目的Socket的端口号
如果目的主机IP和目的Socket的端口号是固定的,在运行过程中没有改变,那么也可以在这里设置*/
}
/******************************************************************************
处理Socket接收和发送的数据
******************************************************************************/
/*-----------------------------------------------------------------------------
如果Socket产生接收数据的中断,则引用该程序进行处理
该程序将Socket的接收到的数据缓存到Rx_buffer数组中,并返回接收的数据字节数
-----------------------------------------------------------------------------*/
unsigned short S_rx_process(SOCKET s)
{
unsigned short i,j;
unsigned short rx_size,rx_offset;
/*读取接收数据的字节数*/
rx_size=Read_W5100(W5100_S0_RX_RSR+s*0x100);
rx_size*=256;
rx_size+=Read_W5100(W5100_S0_RX_RSR+s*0x100+1);
/*读取接收缓冲区的偏移量*/
rx_offset=Read_W5100(W5100_S0_RX_RR+s*0x100);
rx_offset*=256;
rx_offset+=Read_W5100(W5100_S0_RX_RR+s*0x100+1);
i=rx_offset/S_RX_SIZE; /*计算实际的物理偏移量,S0_RX_SIZE需要在前面#define中定义*/
/*注意S_RX_SIZE的值在W5100_Init()函数的W5100_RMSR中确定*/
rx_offset=rx_offset-i*S_RX_SIZE;
j=W5100_RX+s*S_RX_SIZE+rx_offset; /*实际物理地址为W5100_RX+rx_offset*/
for(i=0;i<rx_size;i++)
{
if(rx_offset>=S_RX_SIZE)
{
j=W5100_RX+s*S_RX_SIZE;
rx_offset=0;
}
Rx_Buffer[i]=Read_W5100(j); /*将数据缓存到Rx_buffer数组中*/
j++;
rx_offset++;
}
/*计算下一次偏移量*/
rx_offset=Read_W5100(W5100_S0_RX_RR+s*0x100);
rx_offset*=256;
rx_offset+=Read_W5100(W5100_S0_RX_RR+s*0x100+1);
rx_offset+=rx_size;
Write_W5100((W5100_S0_RX_RR+s*0x100), (rx_offset/256));
Write_W5100((W5100_S0_RX_RR+s*0x100+1), rx_offset);
Write_W5100((W5100_S0_CR+s*0x100), S_CR_RECV); /*设置RECV命令,等等下一次接收*/
return rx_size; /*返回接收的数据字节数*/
}
/*-----------------------------------------------------------------------------
如果要通过Socket发送数据,则引用该程序
要发送的数据缓存在Tx_buffer中, size则是要发送的字节长度
-----------------------------------------------------------------------------*/
unsigned char S_tx_process(SOCKET s, unsigned int size)
{
unsigned short i,j;
unsigned short tx_free_size,tx_offset;
/*如果是UDP模式,可以在此设置目的主机的IP和端口号*/
if((Read_W5100(W5100_S0_MR+s*0x100)&0x0f)==0x02)
{
for(i=0;i<4;i++) /* 设置目的主机IP*/
Write_W5100((W5100_S0_DIPR+s*0x100+i), UDP_DIPR[i]);
Write_W5100((W5100_S0_DPORT+s*0x100), UDP_DPORT[0]);
Write_W5100((W5100_S0_DPORT+s*0x100+1), UDP_DPORT[1]);
}
/*读取缓冲区剩余的长度*/
tx_free_size=Read_W5100(W5100_S0_TX_FSR+s*0x100);
tx_free_size*=256;
tx_free_size+=Read_W5100(W5100_S0_TX_FSR+s*0x100+1);
if(tx_free_size<size) /*如果剩余的字节长度小于发送字节长度,则返回*/
return FALSE;
/*读取发送缓冲区的偏移量*/
tx_offset=Read_W5100(W5100_S0_TX_WR+s*0x100);
tx_offset*=256;
tx_offset+=Read_W5100(W5100_S0_TX_WR+s*0x100+1);
i=tx_offset/S_TX_SIZE; /*计算实际的物理偏移量,S0_TX_SIZE需要在前面#define中定义*/
/*注意S0_TX_SIZE的值在W5100_Init()函数的W5100_TMSR中确定*/
tx_offset=tx_offset-i*S_TX_SIZE;
j=W5100_TX+s*S_TX_SIZE+tx_offset; /*实际物理地址为W5100_TX+tx_offset*/
for(i=0;i<size;i++)
{
if(tx_offset>=S_TX_SIZE)
{
j=W5100_TX+s*S_TX_SIZE;
tx_offset=0;
}
Write_W5100(j,Tx_Buffer[i]); /*将Tx_buffer缓冲区中的数据写入到发送缓冲区*/
j++;
tx_offset++;
}
/*计算下一次的偏移量*/
tx_offset=Read_W5100(W5100_S0_TX_WR+s*0x100);
tx_offset*=256;
tx_offset+=Read_W5100(W5100_S0_TX_WR+s*0x100+1);
tx_offset+=size;
Write_W5100((W5100_S0_TX_WR+s*0x100),(tx_offset/256));
Write_W5100((W5100_S0_TX_WR+s*0x100+1),tx_offset);
Write_W5100((W5100_S0_CR+s*0x100), S_CR_SEND); /*设置SEND命令,启动发送*/
return TRUE; /*返回成功*/
}
/******************************************************************************
W5100中断处理程序框架
******************************************************************************/
void W5100_Interrupt_Process(void)
{
unsigned char i,j;
W5100_Interrupt=0;
i=Read_W5100(W5100_IR);
Write_W5100(W5100_IR, (i&0xf0)); /*回写清除中断标志*/
if((i & IR_CONFLICT) == IR_CONFLICT) /*IP地址冲突异常处理,自己添加代码*/
{
}
if((i & IR_UNREACH) == IR_UNREACH) /*UDP模式下地址无法到达异常处理,自己添加代码*/
{
}
/* Socket事件处理 */
if((i & IR_S0_INT) == IR_S0_INT)
{
j=Read_W5100(W5100_S0_IR);
Write_W5100(W5100_S0_IR, j); /* 回写清中断标志 */
if(j&S_IR_CON) /* 在TCP模式下,Socket0成功连接 */
{
S0_State|=S_CONN;
}
if(j&S_IR_DISCON) /* 在TCP模式下Socket断开连接处理,自己添加代码 */
{
Write_W5100(W5100_S0_CR, S_CR_CLOSE); /* 关闭端口,等待重新打开连接 */
S0_State=0;
}
if(j&S_IR_SENDOK) /* Socket0数据发送完成,可以再次启动S_tx_process()函数发送数据 */
{
S0_Data|=S_TRANSMITOK;
}
if(j&S_IR_RECV) /* Socket接收到数据,可以启动S_rx_process()函数 */
{
S0_Data|=S_RECEIVE;
}
if(j&S_IR_TIMEOUT) /* Socket连接或数据传输超时处理 */
{
Write_W5100(W5100_S0_CR, S_CR_CLOSE); /* 关闭端口,等待重新打开连接 */
S0_State=0;
}
}
/* Socket1事件处理 */
if((i&IR_S1_INT)==IR_S1_INT)
{
j=Read_W5100(W5100_S1_IR);
Write_W5100(W5100_S1_IR, j); /* 回写清中断标志 */
if(j&S_IR_CON) /* 在TCP模式下,Socket1成功连接 */
{
S1_State|=S_CONN;
}
if(j&S_IR_DISCON) /* 在TCP模式下Socket1断开连接处理,自己添加代码 */
{
Write_W5100(W5100_S1_CR, S_CR_CLOSE); /* 关闭端口,等待重新打开连接 */
S1_State=0;
}
if(j&S_IR_SENDOK) /* Socket1数据发送完成,可以再次启动S_tx_process()函数发送数据 */
{
S1_Data|=S_TRANSMITOK;
}
if(j&S_IR_RECV) /* Socket1接收到数据,可以启动S_rx_process()函数 */
{
S1_Data|=S_RECEIVE;
}
if(j&S_IR_TIMEOUT) /* Socket1连接或数据传输超时处理 */
{
Write_W5100(W5100_S1_CR, S_CR_CLOSE); /*关闭端口,等待重新打开连接 */
S1_State=0;
}
}
/* Socket2事件处理 */
if((i&IR_S2_INT)==IR_S2_INT)
{
j=Read_W5100(W5100_S2_IR);
Write_W5100(W5100_S2_IR, j); /*回写清中断标志 */
if(j&S_IR_CON) /* 在TCP模式下,Socket2成功连接 */
{
S2_State|=S_CONN;
}
if(j&S_IR_DISCON) /* 在TCP模式下Socket2断开连接处理,自己添加代码 */
{
Write_W5100(W5100_S2_CR, S_CR_CLOSE); /* 关闭端口,等待重新打开连接 */
S2_State=0;
}
if(j&S_IR_SENDOK) /* Socket2数据发送完成,可以再次启动S_tx_process()函 数发送数据 */
{
S2_Data|=S_TRANSMITOK;
}
if(j&S_IR_RECV) /* Socket2接收到数据,可以启动S_rx_process()函数 */
{
S2_Data|=S_RECEIVE;
}
if(j&S_IR_TIMEOUT) /* Socket2连接或数据传输超时处理 */
{
Write_W5100(W5100_S2_CR, S_CR_CLOSE); /*关闭端口,等待重新打开连接 */
S2_State=0;
}
}
/* Socket3事件处理 */
if((i&IR_S3_INT)==IR_S3_INT)
{
j=Read_W5100(W5100_S3_IR);
Write_W5100(W5100_S3_IR, j); /* 回写清中断标志 */
if(j&S_IR_CON) /* 在TCP模式下,Socket3成功连接 */
{
S3_State|=S_CONN;
}
if(j&S_IR_DISCON) /* 在TCP模式下Socket3断开连接处理,自己添加代码 */
{
Write_W5100(W5100_S3_CR, S_CR_CLOSE); /* 关闭端口,等待重新打开连接 */
S3_State=0;
}
if(j&S_IR_SENDOK) /* Socket3数据发送完成,可以再次启动S_tx_process()函数发送数据 */
{
S3_Data|=S_TRANSMITOK;
}
if(j&S_IR_RECV) /* Socket3接收到数据,可以启动S_rx_process()函数 */
{
S3_Data|=S_RECEIVE;
}
if(j&S_IR_TIMEOUT) /* Socket3连接或数据传输超时处理 */
{
Write_W5100(W5100_S3_CR, S_CR_CLOSE); /*关闭端口,等待重新打开连接 */
S3_State=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -