1、首先进行IO分配:
2、时钟树配置
特别注意:W5500如果由单片机提供时钟,在配置时钟树的时候需要手动选择相应的时钟源,不然最终通信会产生各种未知问题。
3、中断配置,外设配置
4、程序内USART串口调试配置
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart3,(uint8_t *)&ch,1,0xffff);
return (ch);
}
重定义printf函数指定到USART3输出;
5、配置W5500
此部分参考于 飞鸿踏雪 的程序。
1)重置W5500
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9,GPIO_PIN_SET);
HAL_Delay(10);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9,GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9,GPIO_PIN_SET);
HAL_Delay(1000);
低电平有效,低电平至少保持500us以上。
2)注册临界区函数、片选函数、读写函数。
/* Critical section callback */
reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit);
/* Chip selection call back */
reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);
/* SPI Read & Write callback function */
reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte);
其中,相应的SPI函数为:
void SPI_WriteByte(uint8_t Send)
{
HAL_SPI_Transmit(&hspi3,&Send,1,0xffff);
while(HAL_SPI_GetState(&hspi3) == HAL_SPI_STATE_BUSY_RX);
SPI3->DR;
}
uint8_t SPI_ReadByte(void)
{
uint8_t Rcv=0;
HAL_SPI_Receive(&hspi3,&Rcv,1,0XFFFF);
return Rcv;
}
void SPI_CrisEnter(void)
{
__set_PRIMASK(1);
}
void SPI_CrisExit(void)
{
__set_PRIMASK(0);
}
void SPI_CS_Select(void)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_RESET);
}
void SPI_CS_Deselect(void)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_SET);
}
注意:在写的时候最后需要读一次,网上有人研究说如果不读,在TCP模式的时候会产生超时错误。
3)初始化W5500
void w5500_init(void)
{
uint8_t memsize[2][8] = {{2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2}};设置socket的发送和接收缓存大小。
if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1)
{
printf("WIZCHIP Initialized fail.\r\n");
}
do{
if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1)
{
printf("Unknown PHY Link stauts.\r\n");
}
}while(tmp == PHY_LINK_OFF);//等待PHY连接
}
void network_init(void)//初始化网络
{
uint8_t tmpstr[6];
ctlnetwork(CN_SET_NETINFO, (void*)&gWIZNETINFO);
ctlnetwork(CN_GET_NETINFO, (void*)&gWIZNETINFO);
// Display Network Information
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]);
ret = socket(SOCK_UDPS,Sn_MR_UDP,5000,0);
if(ret != SOCK_UDPS){
printf("%d:Socket Error\r\n",SOCK_UDPS);
while(1);
}else{
printf("Socket OK\n\r");
} // 初始化socket,设置为UDP模式
}
至此,完成了移植,使用sendto和recvfrom进行数据的发送接收。
移植参考网址:http://www.embed-net.com/thread-55-1-1.html