您的位置:首页 > 编程语言

基于STM32CUBEMX的W5500 UDP驱动编程步骤小记

2018-02-07 21:11 686 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: