OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 14925|回复: 10

W5500同时用两个SOCKET

[复制链接]

5

主题

20

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
241
金钱
241
注册时间
2015-12-9
在线时间
84 小时
发表于 2016-12-3 12:04:08 | 显示全部楼层 |阅读模式
    就是socket0和socket1同时做客户端   有一个进不了中断,单独的时候是可以的。
  /**********************************************************************************
* @file           usr/bsp/src/w5500.c
* @author   泥人通信模块开发团队
* @revise   cyq
* @version  v1.0
* @date                 2016.01.16
* @brief    本文件进行W5500的驱动工作
**********************************************************************************/


#include "inc.h"
#include <stdarg.h>
/* #include "w5500.h" */


/**
  * 接口
  */
/* INT RST _GPIO */
#define w55INT_INT              vB0_NVIC(); vB0_Init()
#define w55RST_INT              vB1_Init()
#define w55RST_LOW              GPIO_ResetBits(GPIOB, GPIO_Pin_1)
#define w55RST_HIGH             GPIO_SetBits(GPIOB, GPIO_Pin_1)
/* INT中端屏蔽,line0 */
#define w55INT_OFF              EXTI->IMR &=~(1<<0)
/* INT中端开启,关闭过程中的中断不需要放弃,故不清标记 */
#define w55INT_ON               /* EXTI->PR=1<<11; */ EXTI->IMR |= (1<<0)


/* SPI通信相关 */
#define w55SPI_INIT             vSPI3_cfg()
#define w55CS_LOW               GPIO_ResetBits(GPIOA, GPIO_Pin_15)         
#define w55CS_HIGH              GPIO_SetBits(GPIOA, GPIO_Pin_15)
#define w55SPI_SEND_BYTE(d)     ucSPI3_SendByte(d)
/* 毫秒延时 所需延时时间很短且在初始操作时使用 不要用RTOS的等待 */
#define w55DELAY_MS(t)          vDelay_ms(t)


/**
  * 数据变量类型
  */
/* 运行状态 */
u8 ucSocketState[w55USE_SOCKET_NUM] = {0,0,};
u8 Socket_SendOK[w55USE_SOCKET_NUM] = {0,0};
u8 Socket_SendTimeOut[w55USE_SOCKET_NUM] = {0,0};


/**
  * 函数声明
  */
static void prvSetCache(void);
static void prvSetLocalNet(void);
#if 0
static u8 prvDetectGateway(void);
#endif
static void prvSocket0Handle(void);
static void prvSocket1Handle(void);
void prvWriteSocketByte(SOCKET s, u16 reg, u8 dat);
static void prvWriteSocket2Byte(SOCKET s, u16 reg, u16 dat);
static u16 prvReadSocket2Byte(SOCKET s, u16 reg);
static void prvWriteSocket4Byte(SOCKET s, u16 reg, u8 *dat_ptr);
static void prvSendShort(u16 dat);


/**
  * W5500初始化,进行通信接口初始化以及一些必要的寄存器操作
  */
void vW5500Init(void)
{
  w55SPI_INIT;  /* SPI初始化里的时序部分两版本不一致,参考官方资料看一下 */
  w55INT_INT;
  w55RST_INT;

  vW5500Rst();

  prvSetCache();
  prvSetLocalNet();
  /* prvDetectGateway(); */   /* 经测试,该语句不运行无影响 */
}


/**
  * 硬件复位
  */
void vW5500Rst(void)
{
        w55RST_LOW;
        vDelay_ms(2);  
        w55RST_HIGH;       
        vDelay_ms(1000);         /* 原1600 */

  /* vWriteRegByte(MR, RST); */   /* 软件复位W5500 */
  /* vDelay_ms(10); */
}


/**
  * 设置Tx Rx缓存区域大小
  */
void prvSetCache(void)
{
  u8 i;  

  for (i = 0;i < 8;i++) {
    prvWriteSocketByte(i,Sn_RXBUF_SIZE, 0x02);  /* Socket Rx memory size=2k */
    prvWriteSocketByte(i,Sn_TXBUF_SIZE, 0x02);  /* Socket Tx mempry size=2k */
  }
}


/**
  * 设置本地网络参数
  */
void prvSetLocalNet(void)
{
  u8 mac[6] = w55MAC_ADDR;
  u8 gate[4];
//  u8 gate1[4];
  u8 mask[4] = {255,255,255,0};

  gate[0] = 192;
  gate[1] = 168;   
  gate[2] = 254;   
  gate[3] = 1;            


vWriteRegByteBuf(GAR, gate, 4);
vWriteRegByteBuf(SUBR,mask,4);       
// vWriteRegByteBuf(GAR, gate1, 4);
//  vWriteRegByteBuf(SUBR,mask,4);               
  /* 设置物理地址,PHY_ADDR为6字节unsigned char数组,自己定义,唯一标识 */
  /* 该地址需要到IEEE申请,按照OUI的规定,前三个字节为厂商代码,后三个字节为产品序号 */
  /* 如果自己定义物理地址,注意第一个字节必须为偶数 */
  vWriteRegByteBuf(SHAR,mac,6);               
  vWriteRegByteBuf(SIPR,w55LOCAL_IP,4);       
//vWriteRegByteBuf(SHAR,mac,6);       
//  vWriteRegByteBuf(SIPR,w55SERLOCAL_IP,4);       
}


/**
  * 启动指定端口的中断
  * 根据实际需求开启需要工作的中断
  */
void vEnSocketInterrupt(void)
{
  /* 启动中断,参考w5500数据手册确定自己需要的中断类型 */
  /* IMR_CONFLICT是IP地址冲突异常中断,IMR_UNREACH是UDP通信时,地址无法到达的异常中断 */
  /* 其它是Socket事件中断,根据需要添加 */
  vWriteRegByte(wIMR,IM_IR7 | IM_IR6|IM_IR5|IM_IR4);
  vWriteRegByte(SIMR,S0_IMR);
  prvWriteSocketByte(0, Sn_IMR, IMR_TIMEOUT |IMR_RECV | IMR_DISCON | IMR_CON);   /* IMR_SENDOK 发送数据完成中断 */
        vWriteRegByte(SIMR,S1_IMR);
        prvWriteSocketByte(1, Sn_IMR, IMR_TIMEOUT |IMR_RECV | IMR_DISCON | IMR_CON);
}


#if 0
/**
  * 检查端口网关服务器打开端口
  * 成功返回0xff,失败返回0x00
  */
u8 prvDetectGateway(void)
{
  u8 ip_adde[4];
  ip_adde[0] = w55LOCAL_IP[0]+1;
  ip_adde[1] = w55LOCAL_IP[1]+1;
  ip_adde[2] = w55LOCAL_IP[2]+1;
  ip_adde[3] = w55LOCAL_IP[3]+1;

  /* 检查网关及获取网关的物理地址 */
  prvWriteSocket4Byte(0,Sn_DIPR,ip_adde);  /* 向目的地址寄存器写入与本机Ip不同的Ip值 */
  prvWriteSocketByte(0,Sn_MR,MR_TCP);      /* 设置socket为tcp模式 */
  prvWriteSocketByte(0,Sn_CR,OPEN);        /* 打开socket */
  w55DELAY_MS(5);

  /* 如果socket打开失败 */       
  if(vReadSocketByte(0,Sn_SR) != SOCK_INIT) {
    prvWriteSocketByte(0,Sn_CR,CLOSE);     /* 打开不成功,关闭socket */
    return 0x00;
  }

  prvWriteSocketByte(0,Sn_CR,CONNECT);     /* 设置socket为connect模式 */                               

  do
  {
    u8 j=0;
    j = vReadSocketByte(0,Sn_IR);          /* 读取socket0中断标志寄存器 */
    if (j!=0)
      prvWriteSocketByte(0,Sn_IR,j);
    w55DELAY_MS(5);
    if ((j&IR_TIMEOUT) == IR_TIMEOUT) {
      return 0x00;       
    }
    else if(vReadSocketByte(0,Sn_DHAR) != 0xff) {
      prvWriteSocketByte(0,Sn_CR,CLOSE);   /* 关闭socket */
      return 0xff;                                                       
    }
  }while(1);
}
#endif


/**
  * 设置工作在客户端模式的端口的本地端口号及目标网络参数
  */
void vSocketClientSet(SOCKET s,u16 locport,u8* serip,u16 serport)
{
  /* 设置分片长度,W5500数据手册,改值可以不修改 */
  prvWriteSocket2Byte(s, Sn_MSSR, 1460);   /* 最大分片字节数=1460(0x5b4) */
        /* 设置端口的端口号 */
        prvWriteSocket2Byte(s, Sn_PORT, locport);
        /* 设置端口目的端口号 */
        prvWriteSocket2Byte(s, Sn_DPORTR, serport);
        /* 设置端口目的Ip地址 */
        prvWriteSocket4Byte(s, Sn_DIPR, serip);
}


/**
  * 设置工作在服务端模式下的端口的本地端口号
  */
void vSocketServerSet(SOCKET s,u16 locport)
{
  /* 设置分片长度,W5500数据手册,改值可以不修改 */
        prvWriteSocket2Byte(s, Sn_MSSR, 1460);   /* 最大分片字节数=1460(0x5b4) */
        /* 设置端口0的端口号 */
        prvWriteSocket2Byte(s, Sn_PORT, locport);
}


/**
  * 设置指定端口为UDP模式,并且设置本地端口
  */
u8 ucSocketUDPSet(SOCKET s,u16 locport)
{
  prvWriteSocket2Byte(s, Sn_PORT, locport);

  prvWriteSocketByte(s,Sn_MR,MR_UDP);  /* 设置为UDP模式 */
        prvWriteSocketByte(s,Sn_CR,OPEN);    /* 打开端口 */
        w55DELAY_MS(5);
        if(vReadSocketByte(s,Sn_SR) != SOCK_UDP)  /* 如果打开失败 */
        {
                prvWriteSocketByte(s,Sn_CR,CLOSE);      /* 关闭端口 */
                 return 0x00;
        }

  ucSocketState[s] = w55S_CONN;
  return 0xff;
}


/**
  * 指定端口与远程服务器连接
  * 成功返回TRUE(0xFF),失败返回FALSE(0x00)
  * 当本机Socket工作在客户端时,引用该程序,与远程服务器建立连接
  * 如果启动连接后出现超时中断,则与服务器连接失败,需要重新调用该程序连接
  * 该程序每调用一次,就与服务器产生一次连接
  */
u8 vSocketConnect(SOCKET s)
{
  prvWriteSocketByte(s,Sn_MR,MR_TCP);  /* 设置socket为tcp模式 */
  prvWriteSocketByte(s,Sn_CR,OPEN);    /* 打开socket */
  w55DELAY_MS(5);
  /* 如果socket打开失败 */
  if(vReadSocketByte(s,Sn_SR)!=SOCK_INIT) {
    prvWriteSocketByte(s,Sn_CR,CLOSE); /* 打开不成功,关闭socket */
    return FALSE;
  }
  prvWriteSocketByte(s,Sn_CR,CONNECT); /* 设置socket为connect模式 */
  return TRUE;
}



/**
  * 设置指定socket(0-7)作为服务器等待远程主机的连接
  * 当本机socket工作在服务器模式时,引用该程序,等待远程主机的连接
  * 该程序只调用一次,就使w5500设置为服务器模式
  */
u8 vSocketListen(SOCKET s)
{
  prvWriteSocketByte(s,Sn_MR,MR_TCP);   /* 设置socket为tcp模式 */
  prvWriteSocketByte(s,Sn_CR,OPEN);     /* 打开socket */       
  w55DELAY_MS(5);
  /* 如果socket打开失败 */
  if(vReadSocketByte(s,Sn_SR)!=SOCK_INIT) {
    prvWriteSocketByte(s,Sn_CR,CLOSE);  /* 打开不成功,关闭socket */
    return 0x00;
  }       
  prvWriteSocketByte(s,Sn_CR,LISTEN);   /* 设置socket为侦听模式 */       
  w55DELAY_MS(5);
  /* 如果socket设置失败 */
  if(vReadSocketByte(s,Sn_SR)!=SOCK_LISTEN) {
    prvWriteSocketByte(s,Sn_CR,CLOSE);  /* 设置不成功,关闭socket */
    return 0x00;
  }
  return 0xff;

  /* 至此完成了socket的打开和设置侦听工作,至于远程客户端是否与它建立连接,则需要等待socket中断
   * 以判断socket的连接是否成功,参考w5500数据手册的socket中断状态
   * 在服务器侦听模式下不需要设置目的IP和端口 */
}


/**
  * 将数据写入w5500的数据发送缓存区
  */
void vWriteSocketDataBuffer(SOCKET s, u8 *dat_ptr, u16 size)
{
  u16 offset,offset1;
  u16 i;

  if (ucSocketState[s] != w55S_CONN) {
    return;
  }

  w55INT_OFF;

  offset = prvReadSocket2Byte(s,Sn_TX_WR);
  offset1 = offset;
  offset &= (S_TX_SIZE - 1);   /* 计算实际的物理地址 */

  w55CS_LOW;

  prvSendShort(offset);        /* 写16位地址 */
  w55SPI_SEND_BYTE(VDM|RWB_WRITE|(s * 0x20 + 0x10)); /* 写控制字节,N个字节数据长度,写数据,选择端口s的寄存器 */
  /* 如果最大地址未超过w5500发送缓存区的最大地址 */
  if ((offset+size) < S_TX_SIZE) {
    /* 循环写入size各字节数据 */
    for (i = 0;i < size;i++) {
      w55SPI_SEND_BYTE(*dat_ptr++);  /* 写入一个字节的数据 */
    }
  }
  /* 如果最大地址超过w5500发送缓存区的最大地址 */
  else {
    offset = S_TX_SIZE - offset;
    /* 循环写入前offest个字节数据 */
    for (i = 0;i < offset;i++) {
      w55SPI_SEND_BYTE(*dat_ptr++);  /* 写入一个字节的数据 */
    }

    w55CS_HIGH;

    w55CS_LOW;

    prvSendShort(0x00);  /* 写16位地址 */
    w55SPI_SEND_BYTE(VDM | RWB_WRITE | (s * 0x20 + 0x10));  /* 写控制字节,N个字节数据长度,写数据,选择端口S的寄存器 */
    /* 循环写入size-offest个字节数据 */
    for(;i < size;i++) {
      w55SPI_SEND_BYTE(*dat_ptr++);  /* 写入一个字节的数据 */
    }
  }

  w55CS_HIGH;

  offset1 += size;  /* 更新实际物理地址,即下次写带发送数据到发送缓存区的起始地址 */
  prvWriteSocket2Byte(s, Sn_TX_WR, offset1);
  prvWriteSocketByte(s, Sn_CR, SEND);  /* 启动发送命令 */

  w55INT_ON;
}


/**
  * 将数据写入w5500的数据发送缓存区
  * UDP模式专用,指定IP和端口
  * 返回 1 - 成功发送
  *      2 - 发送超时
  */
u8 ucUDPSendDataBuffer(SOCKET s, u8 *dat_ptr, u16 size,u8* ip,u16 port)
{
  /* 设置端口目的端口号 */
        prvWriteSocket2Byte(s, Sn_DPORTR, port);
        /* 设置端口目的Ip地址 */
        prvWriteSocket4Byte(s, Sn_DIPR, ip);

  Socket_SendTimeOut[s] = 0;
  Socket_SendOK[s] = 0;
  vWriteSocketDataBuffer(s,dat_ptr,size);

  while(1) {
    if (Socket_SendOK[s] == 1) {
      return 1;
    }
    else if(Socket_SendTimeOut[s] == 1) {
      return 2;
    }
  }
}


/**
  * 从w5500接收数据缓存区中读取数据
  * 返回值:读取到的数据长度,rx_size个字节
  */
u16 vReadSocketDataBuffer(SOCKET s, void (*rec)(u8 d))
{
  u16 rx_size;
  u16 offset, offset1;
  u16 i;

  rx_size = prvReadSocket2Byte(s,Sn_RX_RSR);
  if(rx_size==0)
    return 0;       /* 没接收到数据则返回 */
  if(rx_size>1460)
    rx_size=1460;

  offset = prvReadSocket2Byte(s,Sn_RX_RD);
  offset1 = offset;
  offset &= (S_RX_SIZE-1);  /* 计算实际的物理地址 */

  w55CS_LOW;

  prvSendShort(offset);     /* 写16位地址 */
  w55SPI_SEND_BYTE(VDM|RWB_READ|(s*0x20+0x18)); /* 写控制字节,N个字节数据长度,读数据,选择端口S的寄存器 */
       
  /* 如果最大地址未超过W5500接收缓存区的最大地址 */
  if ((offset + rx_size) < S_RX_SIZE) {
    /* 选换读取rx_size个字节数据 */
    for(i = 0;i < rx_size;i++) {  
      rec(w55SPI_SEND_BYTE(0x00));  /* 发送一个哑数据读取数据 */
    }
  }
  /* 如果最大地址超过w5500接收缓存区的最大地址 */
  else {
    offset = S_RX_SIZE - offset;
    for(i = 0;i < offset;i++) {
      rec(w55SPI_SEND_BYTE(0x00));
    }

    w55CS_HIGH;

    w55CS_LOW;

    prvSendShort(0x00);    /* 写16位地址 */
    w55SPI_SEND_BYTE(VDM|RWB_READ|(s*0x20+0x18));  /* 写控制字节,N个字节数据长度,读数据,选择端口s的寄存器 */
    /* 循环读取后rx_size-offset个字节数据 */
    for(;i < rx_size;i++) {
      rec(w55SPI_SEND_BYTE(0x00));
    }
  }

  w55CS_HIGH;

  offset1 += rx_size; /* 更新实际物理地址,即下次读取接收到的数据的起始地址 */
  prvWriteSocket2Byte(s, Sn_RX_RD, offset1);
  prvWriteSocketByte(s, Sn_CR, RECV);  /* 发送启动接收命令 */

  return rx_size;     /* 返回接收到数据的长度 */
}


/**
  * Socket0中断处理
  * 根据实际需求修改内部各种情况发生的处理代码
  */
void prvSocket0Handle(void)
{
  u8 j;

  j = vReadSocketByte(0,Sn_IR);   /* 读取Socket0中断标志寄存器 */
        prvWriteSocketByte(0,Sn_IR,j);
        /* 在tcp模式下socket成功连接 */
        if (j & IR_CON) {
                ucSocketState[0] = w55S_CONN;
        }
        /* 在tcp模式下 断开连接 */
        if (j & IR_DISCON) {
    vSocketConnect(0);
                ucSocketState[0] = w55S_INIT;
        }
#if 1
        /* Socket0数据发送完成 */
        if (j & IR_SEND_OK) {
                // Socket_SendOK[0] = 1;
               
        }

#endif
        /* Socket接收到数据 */
        if (j & IR_RECV) {
    xServerRx.path = 0X04;
    vReadSocketDataBuffer(0,vRecUpperDat);
        }                              
        /* Socket连接或数据传输超时处理 */
        if (j & IR_TIMEOUT) {
        //         Socket_SendOK[0] = 1;
                prvWriteSocketByte(0,Sn_CR,CLOSE);   /* 关闭端口 */      
    ucSocketState[0] = w55S_INIT;
           vSocketConnect(0);
        }
}
/**
  * Socket1中断处理
  * 根据实际需求修改内部各种情况发生的处理代码
  */
void prvSocket1Handle(void)
{
  u8 k;
  k = vReadSocketByte(1,Sn_IR);   /* 读取Socket1中断标志寄存器 */
        prvWriteSocketByte(1,Sn_IR,k);
        /* 在tcp模式下socket成功连接 */
        if (k & IR_CON) {
                ucSocketState[1] = w55S_CONN;
        }
        /* 在tcp模式下 客户端主动断开 */
        if (k & IR_DISCON) {
                vSocketConnect(1);
                ucSocketState[1] = w55S_INIT;
        }
#if 0
        /* Socket0数据发送完成 */
        if (k & IR_SEND_OK) {
          Socket_SendOK[1] = 1;
        }
#endif
        /* Socket接收到数据 */
        if (k & IR_RECV) {
                xServerRx.path = PATH_NET;
    vReadSocketDataBuffer(1,vRecUpperDat);
        }                              
        /* Socket连接或数据传输超时处理 */
        if (k & IR_TIMEOUT) {
          prvWriteSocketByte(1,Sn_CR,CLOSE);   /* 关闭端口 */      
    ucSocketState[1] = w55S_INIT;
     vSocketConnect(1);
        }
}


/**
  * W5500中断处理框架
  */
void vW5500InterruptProcess(void)
{
  u8 i;

IntDispose:
  i = vReadRegByte(IR);        /* 读取中断标志寄存器 */  
  vWriteRegByte(IR, (i&0xf0)); /* 回写清除中断标志 */
#if 0
  /* 以下两个中断没有使能 */
  /* IP地址冲突异常处理 */
  if ((i & CONFLICT) == CONFLICT) {
    ;
  }
  /* UDP模式下地址无法到达异常处 */
  if ((i & UNREACH) == UNREACH) {
    ;
  }
#endif
  i = vReadRegByte(SIR);         /* 读取端口中断标志寄存器 */
  /* Socket0事件处理 */
  if((i & S0_INT) == S0_INT) {
    prvSocket0Handle();
  }
                if ((i & S1_INT) == S1_INT) {
    prvSocket1Handle();
   }
               
  /* 处理完当前中断后如果又有中断发生 */
  if(vReadRegByte(SIR) != 0) {
    goto IntDispose;
  }
}



/**
  * 通过SPI接口向W5500指定端口,指定寄存器中写入指定的一个字节数据
  */
void prvWriteSocketByte(SOCKET s, u16 reg, u8 dat)
{
  w55CS_LOW;
               
  prvSendShort(reg);        /* 通过SPI1写16位寄存器地址 */
  w55SPI_SEND_BYTE(FDM1 | RWB_WRITE | (s * 0x20 + 0x08));   /* 通过SPI1写控制字节,1个字节数据长度,写数据,选择端口s的寄存器 */
  w55SPI_SEND_BYTE(dat);    /* 写1个字节数据 */

  w55CS_HIGH;
}


/**
  * 读取w5500指定端口指定寄存器的一个字节数据
  */
u8 vReadSocketByte(SOCKET s, u16 reg)
{
        u8 i;

        w55CS_LOW;
                       
        prvSendShort(reg);           /* 通过SPI1写16位寄存器地址 */
        w55SPI_SEND_BYTE(FDM1|RWB_READ|(s*0x20+0x08));    /* 通过SPI1写控制字节,1个字节数据长度,读数据,选择端口s的寄存器 */
        i = w55SPI_SEND_BYTE(0x00);  /* 发送一个哑数据 */

        w55CS_HIGH;

        return i;
}


/**
  * 通过SPI接口向指定端口指定寄存器写入两个字节数据
  */
void prvWriteSocket2Byte(SOCKET s, u16 reg, u16 dat)
{
  w55CS_LOW;
                       
  prvSendShort(reg);  /* 通过SPI1写16位寄存器地址 */
  w55SPI_SEND_BYTE(FDM2|RWB_WRITE|(s*0x20+0x08));   /* 通过SPI1写控制字节,2个字节数据长度,写数据,选择端口s的寄存器 */
  prvSendShort(dat);  /* 写16位数据 */

  w55CS_HIGH;
}


/**
  * 读指定端口寄存器的2个字节数据
  */
u16 prvReadSocket2Byte(SOCKET s, u16 reg)
{
  u16 i;

  w55CS_LOW;
                       
  prvSendShort(reg);  /* 通过SPI写16位寄存器地址 */
  w55SPI_SEND_BYTE(FDM2|RWB_READ|(s*0x20+0x08));   /* 通过SPI1写控制字节,2个字节数据长度,读数据,选择端口s的寄存器 */

  i= w55SPI_SEND_BYTE(0x00);     /* 发送一个哑数据 */
  i*=256;
  i += w55SPI_SEND_BYTE(0x00);  

  w55CS_HIGH;

  return i;
}


/**
  * 通过SPI接口向W5500指定端口,指定寄存器中写入指定的四个字节数据
  */
void prvWriteSocket4Byte(SOCKET s, u16 reg, u8 *dat_ptr)
{
  w55CS_LOW;
                       
  prvSendShort(reg);  /* 通过SPI1写16位寄存器地址 */
  w55SPI_SEND_BYTE(FDM4 | RWB_WRITE | (s * 0x20 + 0x08));  /* 通过SPI1写控制字节,4个字节数据长度,写数据,选择端口s的寄存器 */

  w55SPI_SEND_BYTE(*dat_ptr++);  /* 写第1个字节数据 */
  w55SPI_SEND_BYTE(*dat_ptr++);  /* 写第2个字节数 */
  w55SPI_SEND_BYTE(*dat_ptr++);  /* 写第3个字节数据 */
  w55SPI_SEND_BYTE(*dat_ptr++);  /* 写第4个字节数据 */

  w55CS_HIGH;
}


/**
  * 通过SPI接口向W5500指定寄存器发送指定的一个字节
  */
void vWriteRegByte(u16 reg, u8 dat)
{
  w55CS_LOW;

  prvSendShort(reg);                         /* 通过SPI1写16位寄存器地址 */
  w55SPI_SEND_BYTE(FDM1|RWB_WRITE|COMMON_R); /* 通过SPI1写控制字节,1个字节数据长度,写数据,选择通用寄存器 */
  w55SPI_SEND_BYTE(dat);                     /* 写1个字节数据 */

  w55CS_HIGH;
}


/**
  * 从指定寄存器读出一个字节数据
  */
u8 vReadRegByte(u16 reg)
{
  u8 i;

  w55CS_LOW;
                       
  prvSendShort(reg);                         /* 通过SPI1写16位寄存器地址 */
  w55SPI_SEND_BYTE(FDM1|RWB_READ|COMMON_R);  /* 通过SPI1写控制字节,1个字节数据长度,读数据,选择通用寄存器 */
  i = w55SPI_SEND_BYTE(0x00);                /* 发送一个哑数据 */

  w55CS_HIGH;

  return i;
}


/**
  * 通过SPI接口向W5500指定寄存器发送指定的一串字节
  */
void vWriteRegByteBuf(u16 reg, u8 *dat_ptr, u16 size)
{
  u16 i;

  w55CS_LOW;
               
  prvSendShort(reg);    /* 通过SPI1写16位寄存器地址 */
  w55SPI_SEND_BYTE(VDM|RWB_WRITE|COMMON_R);  /* 通过SPI1写控制字节,N个字节数据长度,写数据,选择通用寄存器 */

  /* 循环将缓冲区的size个字节数据写入W5500 */
  for (i = 0;i < size;i++) {
    w55SPI_SEND_BYTE(*dat_ptr++);  
  }

  w55CS_HIGH;
}


/**
  * 通过SPI接口从W5500指定寄存器读出的一串字节
  */
void vReadRegByteBuf(u16 reg, u8 *dat_ptr, u16 size)
{
  u16 i;

  w55CS_LOW;
               
  prvSendShort(reg);    /* 通过SPI1写16位寄存器地址 */
  w55SPI_SEND_BYTE(VDM|RWB_READ|COMMON_R);  /* 通过SPI1写控制字节,N个字节数据长度,读数据,选择通用寄存器 */

  /* 循环发送哑数据读出数据 */
  for (i = 0;i < size;i++) {
    *dat_ptr++ = w55SPI_SEND_BYTE(0x00);
  }

  w55CS_HIGH;
}


/**
  * 通过SPI接口向W5500发送一个16位的数据
  */
void prvSendShort(u16 dat)
{
  w55SPI_SEND_BYTE((u8)(dat >> 8));          /* 写数据高位 */
  w55SPI_SEND_BYTE((u8)(dat & 0x00FF));             /* 写数据低位 */
}


/***********************************end*************************************/

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

82

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2017-5-23
在线时间
17 小时
发表于 2018-1-3 16:26:48 | 显示全部楼层

看看这个8个socket 可以同时使用。要例程,可以找我们 0755-86568556或 发邮箱support@wisioe.com

1234.jpg

12345.png

123456.png
WIZnet 以太网芯片 w5500 Dai Li 商 深圳炜世科技0755-86568556  QQ2574989918
回复 支持 1 反对 0

使用道具 举报

5

主题

20

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
241
金钱
241
注册时间
2015-12-9
在线时间
84 小时
 楼主| 发表于 2016-12-3 12:05:27 | 显示全部楼层
     只能单独打开,如果同时打开有一个就会进不了中断,麻烦大神们,是不是中断出现问题了。
回复 支持 反对

使用道具 举报

30

主题

1170

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1993
金钱
1993
注册时间
2016-2-16
在线时间
527 小时
发表于 2016-12-3 16:05:08 | 显示全部楼层

回帖奖励 +10 金钱

我是来偷楼主经验的
回复 支持 反对

使用道具 举报

5

主题

20

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
241
金钱
241
注册时间
2015-12-9
在线时间
84 小时
 楼主| 发表于 2016-12-5 10:37:36 | 显示全部楼层

只能同时收  不能同时发   就是同时打开 socket0发送 然后socket1 发送  没有返回数据
回复 支持 反对

使用道具 举报

21

主题

387

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1043
金钱
1043
注册时间
2016-9-8
在线时间
213 小时
发表于 2016-12-5 12:02:39 | 显示全部楼层
UDP还是TCP?TCP每个不同的socket都有不同的端口,,服务端当然要监听不同的端口。。UDP就做成广播形式吧
shop60994719.taobao.com
回复 支持 反对

使用道具 举报

8

主题

82

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2017-5-23
在线时间
17 小时
发表于 2017-9-18 13:54:55 | 显示全部楼层
WIZnet W5500代理商深圳炜世科技与WIZnet,2017年9月23日在深圳携手举办“物联网通信协议详解与实践”免费培训课,第一期主题TCP/IP协议基础和TCP、UDP的实现。WIZnet资深工程师陈海峰博士亲自授课,机会难得,报名方式【姓名+公司名称+手机号+QQ】发送到邮箱support@wisioe.com,邮件收到后将会电话或者邮件形式通知 psb.png
WIZnet 以太网芯片 w5500 Dai Li 商 深圳炜世科技0755-86568556  QQ2574989918
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
154
金钱
154
注册时间
2018-1-8
在线时间
23 小时
发表于 2018-6-1 13:25:57 | 显示全部楼层
程序中启用Socket中断函数有问题,将:
  vWriteRegByte(SIMR,S0_IMR);
  prvWriteSocketByte(0, Sn_IMR, IMR_TIMEOUT |IMR_RECV | IMR_DISCON | IMR_CON);   /* IMR_SENDOK 发送数据完成中断 */
  vWriteRegByte(SIMR,S1_IMR);
  prvWriteSocketByte(1, Sn_IMR, IMR_TIMEOUT |IMR_RECV | IMR_DISCON | IMR_CON);

修改为:
  vWriteRegByte(SIMR,0x03);  //同时启用Socket0和Socket1中断。 不能单独启用,如果8个Socket全开,把0x03改为0xFF即可,其他类推
  prvWriteSocketByte(0, Sn_IMR, IMR_TIMEOUT |IMR_RECV | IMR_DISCON | IMR_CON);   /* IMR_SENDOK 发送数据完成中断 */
  prvWriteSocketByte(1, Sn_IMR, IMR_TIMEOUT |IMR_RECV | IMR_DISCON | IMR_CON);



回复 支持 反对

使用道具 举报

2

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
108
金钱
108
注册时间
2014-5-20
在线时间
23 小时
发表于 2020-9-24 15:34:02 | 显示全部楼层
WISIOE2016 发表于 2017-9-18 13:54
WIZnet W5500代理商深圳炜世科技与WIZnet,2017年9月23日在深圳携手举办“物联网通信协议详解与实践”免费 ...

W5500是否能同时使用两个socket,一个tcp client,一个udp?
回复 支持 反对

使用道具 举报

2

主题

474

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6077
金钱
6077
注册时间
2018-6-27
在线时间
524 小时
发表于 2020-10-29 12:48:25 | 显示全部楼层
学习学习,学习学习。
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2019-7-29
在线时间
9 小时
发表于 2024-7-1 10:14:09 | 显示全部楼层
学习学习
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 13:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表