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