基于STM32+W5500 的Ethernet移植

  Ethernet,以太网,是局域网通信的一种技术,本文要移植的基于W5500芯片的Ethernet文件,移植前的准备工作见上一篇文章。链接
移植的参考是网上的一篇文章:https://www.cnblogs.com/foxclever/p/5717844.html

1.keil中添加文件和路径

  要添加的文件是Ethernet文件中的socket.c、w5500.c、wizchip_.conf.c三个文件和对应的三个头文件,路径的添加方法见下图:
  这里写图片描述
  这里写图片描述

SPI接口程序编写

  本文的SPI接口并未使用STM32自带的SPI口,而是用GPIO口来模拟SPI通讯完成的,各IO口的对应关系如下:
  

#define W5500_REST   GPIO_PIN_12  //PB12
#define W5500_NSS    GPIO_PIN_9   //PD9
#define W5500_SCLK   GPIO_PIN_8   //PD8
#define W5500_DO     GPIO_PIN_14  //PB14   MOSI
#define W5500_DI     GPIO_PIN_15    //PB15 MISO 
#define W5500_INTn   GPIO_PIN_13    //PB13

  接下来开始编写SPI接口函数:

//SPI2接口初始化
void SPI2_init(void)
{
    //各管脚的初始化配置
    GPIO_InitTypeDef GPIO_InitStruct;

    GPIO_InitStruct.Pin =  W5500_REST | W5500_DO;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);     

    GPIO_InitStruct.Pin =  W5500_SCLK | W5500_NSS;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); 

    GPIO_InitStruct.Pin =  W5500_DI |W5500_INTn ; 
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    W5500_NSS_H;
}
//延时函数
void delay_us(uint16_t time)
{
    uint16_t i,j;
    for(i=0;i<time;i++)
    {
        j=32;
        while(j>1)j--;
    }
}

//W5500芯片复位
void W5500_RESET(void)
{
    W5500_REST_L;//RESET置低复位
    HAL_Delay(50);
    W5500_REST_H;//RESET置高  
    HAL_Delay(10);
}

//SPI写一字节数据
void SPI_WriteByte(uint8_t Tdata)
{
    uint8_t i,temp;
    temp=Tdata;
    for(i=0;i<8;i++)
    {
        if(temp&0x80)
            W5500_DO_H;
        else
            W5500_DO_L;
        delay_us(2);
        W5500_SCLK_H; 
        temp=(temp<<1);
        W5500_SCLK_L;
    }
}

//SPI读取一字节数据
uint8_t SPI_ReadByte(void)
{
    uint8_t i,j=0;  
    for(i=0;i<8;i++)
    {
        W5500_SCLK_H; 
        j=(j<<1);
        if(W5500_DINPUT==GPIO_PIN_SET)
            j=j|0x01;
        delay_us(2);        
        W5500_SCLK_L;
    }
    return j;
}

Ethernet的通讯配置初始化

通讯配置初始化主要按照顺序依次执行以下3个函数。
1. 注册TCP通讯相关的回调函数 RegisterFunction();
2. 初始化芯片参数 ChipParametersConfiguration();
3. 初始化网络通讯参数 NetworkParameterConfiguration();

//初始化配置定义
wiz_NetInfo gWIZNETINFO = { .mac = {0x78, 0x83, 0x68, 0x88, 0x56, 0x38},
                            .ip =  {192, 168, 4,17},
                            .sn =  {255,255,255,0},
                            .gw =  {192, 168,4,1},
                            .dns = {180,76,76,76},
                            .dhcp = NETINFO_DHCP};

//注册TCP通讯相关的回调函数
void RegisterFunction(void)
{  

  reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit);    //注册临界区回调函数

#if   _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_
  reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);//注册片选回调函数
#elif _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_
  reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);  
#else
   #if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_
      #error "Unknown _WIZCHIP_IO_MODE_"
   #else
      reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); 
   #endif
#endif
  reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte);    //SPI读写字节回调函数
}
//初始化芯片参数
void ChipParametersConfiguration(void)
{
  uint8_t tmp;
  uint8_t memsize[2][8] = {{2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2}};
    if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1)
        {
            printf("WIZCHIP Initialized fail.\r\n");
            while(1);
        }

    do{
        if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1)
            {
            printf("Unknown PHY Link stauts.\r\n");
            }
      }while(tmp == PHY_LINK_OFF);
}
//初始化网络通讯参数,mac,ip等
void NetworkParameterConfiguration(void)  //Intialize the network information to be used in WIZCHIP

{

  uint8_t tmpstr[6];

  ctlnetwork(CN_SET_NETINFO, (void*)&gWIZNETINFO);

  ctlnetwork(CN_GET_NETINFO, (void*)&gWIZNETINFO);

  ctlwizchip(CW_GET_ID,(void*)tmpstr);
    //串口打印出参数
    printf("\r\n=== %s NET CONF ===\r\n",(char*)tmpstr);
    printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n",gWIZNETINFO.mac[0],gWIZNETINFO.mac[1],gWIZNETINFO.mac[2],
            gWIZNETINFO.mac[3],gWIZNETINFO.mac[4],gWIZNETINFO.mac[5]);
    printf("SIP: %d.%d.%d.%d\r\n", gWIZNETINFO.ip[0],gWIZNETINFO.ip[1],gWIZNETINFO.ip[2],gWIZNETINFO.ip[3]);
    printf("GAR: %d.%d.%d.%d\r\n", gWIZNETINFO.gw[0],gWIZNETINFO.gw[1],gWIZNETINFO.gw[2],gWIZNETINFO.gw[3]);
    printf("SUB: %d.%d.%d.%d\r\n", gWIZNETINFO.sn[0],gWIZNETINFO.sn[1],gWIZNETINFO.sn[2],gWIZNETINFO.sn[3]);
    printf("DNS: %d.%d.%d.%d\r\n", gWIZNETINFO.dns[0],gWIZNETINFO.dns[1],gWIZNETINFO.dns[2],gWIZNETINFO.dns[3]);
    printf("======================\r\n");

}

  4个回调函数的定义如下:

//进入临界区
void SPI_CrisEnter(void)
{
    __set_PRIMASK(1);
}
//退出临界区
void SPI_CrisExit(void)
{
    __set_PRIMASK(0);
}

void SPI_CS_Select(void)
{
    W5500_NSS_L;
}
void SPI_CS_Deselect(void)
{
    W5500_NSS_H;
}

调用上述3个配置函数进行初始化即可,至此,W5500的移植全部完成,芯片配置完成。

void W5500_ChipInit(void)
{
    W5500_RESET();
    RegisterFunction();
    ChipParametersConfiguration();
    NetworkParameterConfiguration();
}   

最终,串口输出的配置参数如下:
这里写图片描述
打开电脑的cmd窗口,输入ping 192.168.4.17,测试ok,移植成功。

移植的源程序见链接:https://download.csdn.net/download/u014470361/10234803

  • 8
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值