STM32+W5500以太网模块

文章目录[隐藏]

一:w5500以太网模块介绍:

W5500 是一款全硬件 TCP/IP 嵌入式以太网控制器,为嵌入式系统提供了更加简易的互联网连接方 案。W5500 集成了 TCP/IP 协议栈,10/100M 以太网数据链路层(MAC) 及物理层(PHY),使得 用户使用单芯片就能够在他们的应用中拓展网络连接。

久经市场考验的 WIZnet 全硬件 TCP/IP 协议栈支持 TCP,UDP,IPv4,ICMP,ARP,IGMP 以及 PPPoE 协议。W5500 内嵌 32K 字节片上缓存以供以太网包处理。如果你使用 W5500, 你只需要一些简单 的 Socket 编程就能实现以太网应用。这将会比其他嵌入式以太网方案 更加快捷、简便。用户可以同 时使用 8 个硬件 Socket 独立通讯。

W5500 提供了 SPI(外设串行接口)从而能够更加容易与外设 MCU 整合。而且, W5500 的使用了新的高效SPI协议支持 80MHz 速率,从而能够更好的实现高速网络通讯。 为了减少系统能耗, W5500 提供了网络唤醒模式(WOL)及掉电模式供客户选择使用。

模块排针功能表:

 STM32与W5500连接方法:

PA15->W5500_RST(源程序使用的是PC5,这里没有该引脚修改为PA15)

PC4->W5500_INT(使用寄存器查询方式的例程时,此引脚可以不接,其他例程可能涉及修改引脚)

PA4->W5500_SCS

PA5->W5500_SCK

PA6->W5500_MISO

PA7->W5500_MOSI

调试寄存器的UDP模式:

 

 

基于stm32与w5500以太网应用:

 

 如上图所示,最底下的一层叫做“物理层”,也叫“PHY 层”,最上面的一层叫做“应用层”,中间的三层(自下而上)分别是“链路层”,也叫“MAC 层”、 “网络层”和“传输层”。越下面的层,越靠近硬件;越上面的层,越靠近用户。
我们一层一层讲解
一、物理层
物理层就是最基础的类似于modbus中的硬件连接是rs485的两根线。物理层由计算机和网络介质之间的实际界面组成,可定义电气信号、符号、线的状态和时钟要求、数据编码和数据传输用的连接器。上面的4层都是基于物理层的。
二、数据链路层
实际上由两个独立的部分组成,介质存取控制(Media AccessControl,MAC)和逻辑链路控制层(Logical Link Control,LLC)。

其中spi2的四根线要接上w5500的 SCSn, SCLK, MOSI, MISO 4 路信号。还有中断信号和复位信号。
W5500 有两种工作模式,分别是可变数据长度模式和固定数据长度模式。在可变数据长度模式中,W5500 可以与其他 SPI 设备共用 SPI 接口。但是一旦将 SPI接口指定给 W5500 之后,也就是 1 脚 CS 片选信号如果选中了这个 W5500,则不能再与其他 SPI 设备共用。在固定数据长度模式,SPI 将指定给 W5500,不能与其他 SPI 设备共享。因为 1 脚 CS 片选信号将直接接地为低电平。
8.1w5500初始化
W5500_conf.c 主要配置 W5500 的 MAC、IP 地址,W5500 基本的数据读写过程,复位设置函数等。
Socket.c 函数主要介绍了 W5500 的 SOCKET 相关配置函数,比如 SOCKET 的打开、关闭,以及接收数据、发送数据等等。
Utility.c 函数主要介绍了基本的延时函数,还有数据格式转化函数。

main()函数代码:

int main(void)
{
	unsigned char i;

	/* Initialize STM32F103 */
	System_Initialization();//系统配置
	SysTick_Init();//启动系统滴答定时器 SysTick

	/* Config W5500 */
	W5500_Configuration();//W5500配置
	Delay_ms(200);//延时等待

	/* Modbus-TCP Init */
    eMBTCPInit(MB_TCP_PORT_USE_DEFAULT); //端口依赖事件模块初始化
	Delay_ms(200); //延时等待
	
	/* Enable Modbus-TCP Stack */    
    eMBEnable();//激活协议栈	
    

    printf("\r\nModbus-TCP Start!\r\n");
    printf("IP:192.168.1.128\r\n");


	while(1)
	{
		
		i=Read_SOCK_1_Byte(0,Sn_SR);  //读W5500状态
		if(i==0)	  
		{
			do
			{
				Delay_ms(100);//延时等待
			
			}while(Socket_Listen(0)==FALSE);//设置“Socket n”为“TCP服务器模式”
		}
		else if(i==SOCK_ESTABLISHED)		 //建立TCP连接
		{
		eMBPoll();//启动modbus侦听
		BSP_LED();//线圈控制LED灯
		}
				
	}
}

W5500配置函数:

/* W5500 configuration */
void W5500_Configuration()
{
	unsigned char array[6];

	GPIO_SetBits(GPIO_W5500_RST_PORT, GPIO_W5500_RST_Pin);//上拉
	Delay_ms(100);    /*delay 100ms 使用systick 1ms时基的延时*/
    //等待以太网链路
	while((Read_1_Byte(PHYCFGR)&LINK)==0); 		/* Waiting for Ethernet Link */

	Write_1_Byte(MR, RST);//写入W5500普通寄存器一个字节
	Delay_ms(20);		/*delay 20ms */

	/* Set Gateway IP as: 192.168.1.1 */
	array[0]=192;
	array[1]=168;
	array[2]=1;
	array[3]=1;
	Write_Bytes(GAR, array, 4);//设置网关IP

	/* Set Subnet Mask as: 255.255.255.0 */
	array[0]=255;
	array[1]=255;
	array[2]=255;
	array[3]=0;
	Write_Bytes(SUBR, array, 4);//设置子网掩码

	/* Set MAC Address as: 0x48,0x53,0x00,0x57,0x55,0x00 */
	array[0]=0x48;
	array[1]=0x53;
	array[2]=0x00;
	array[3]=0x57;
	array[4]=0x55;
	array[5]=0x00;
	Write_Bytes(SHAR, array, 6);//设置MAC地址

	/* Set W5500 IP as: 192.168.1.128 */
	array[0]=192;
	array[1]=168;
	array[2]=1;
	array[3]=128;
	Write_Bytes(SIPR, array, 4);//设置W5500的IP地址
}

STM32+W5500的web服务

main()函数:

int main(void)
{
	Systick_Init(72);//系统时钟初始化
	GPIO_Configuration(); //GPIO configuration
	USART1_Init(); //串口初始化:115200@8-n-1
	printf("W5500 EVB initialization over.\r\n");
	Reset_W5500();
	WIZ_SPI_Init();//W5500相关引脚配置
	printf("W5500 initialized!\r\n");
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7))
	{
		DefaultSet();//出厂值
	}
	else
	{
 		get_config();//read config data from flash
	}
	printf("Firmware ver%d.%d\r\n",ConfigMsg.sw_ver[0],ConfigMsg.sw_ver[1]);
	if(ConfigMsg.debug==0) ConfigMsg.debug=1;

	set_network();//配置网络信息
	printf("Network is ready.\r\n");
	while(1)
	{
		if(ConfigMsg.JTXD_Control == 0)
		  	do_http();//开启http服务
		else
		  	JTXD_do_http();
		if(reboot_flag)
			NVIC_SystemReset();//发起系统复位请求复位单片机
//        reboot();
        
	}
}

GPIO初始化函数:

void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO , ENABLE);
  // Port A output
  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1| GPIO_Pin_2 |GPIO_Pin_3; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
//  GPIO_ResetBits(GPIOA, GPIO_Pin_0);
//  GPIO_ResetBits(GPIOA, GPIO_Pin_1);
//  GPIO_SetBits(GPIOA, GPIO_Pin_2); // led off
//  GPIO_SetBits(GPIOA, GPIO_Pin_3); // led off
  // Port B output;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_SetBits(GPIOB, GPIO_Pin_9);
  // Port C input
//  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
//  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//控制flash
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_SetBits(GPIOB, GPIO_Pin_7);	
}

W5500相关配置

void WIZ_SPI_Init(void)
{
	SPI_InitTypeDef   SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO , ENABLE);	
  // Port B output
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_SetBits(GPIOB, GPIO_Pin_12);
  /* Configure SPIy pins: SCK, MISO and MOSI */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
	  /* SPI Config -------------------------------------------------------------*/
	  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
	  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
	  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
	  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	  SPI_InitStructure.SPI_CRCPolynomial = 7;

	  SPI_Init(SPI2, &SPI_InitStructure);
	  SPI_Cmd(SPI2, ENABLE);
}

http请求:

void do_http(void)
{
  uint8 ch=SOCK_HTTP;
  uint16 len;

  st_http_request *http_request;
  memset(rx_buf,0x00,MAX_URI_SIZE);
  http_request = (st_http_request*)rx_buf;		// struct of http request  
  /* http service start */
  switch(getSn_SR(ch))
  {
    case SOCK_INIT:
      listen(ch);
      break;
    case SOCK_LISTEN:
      break;
    case SOCK_ESTABLISHED:
    //case SOCK_CLOSE_WAIT:
      if(getSn_IR(ch) & Sn_IR_CON)
      {
        setSn_IR(ch, Sn_IR_CON);
      }
      if ((len = getSn_RX_RSR(ch)) > 0)		
      {
        len = recv(ch, (uint8*)http_request, len); 
        *(((uint8*)http_request)+len) = 0;
        proc_http(ch, (uint8*)http_request); // request is processed
        disconnect(ch);
      }
      break;
    case SOCK_CLOSE_WAIT:   
      if ((len = getSn_RX_RSR(ch)) > 0)
      {
        //printf("close wait: %d\r\n",len);
        len = recv(ch, (uint8*)http_request, len);       
        *(((uint8*)http_request)+len) = 0;
        proc_http(ch, (uint8*)http_request); // request is processed
      }
      disconnect(ch);
      break;
    case SOCK_CLOSED:
      socket(ch, Sn_MR_TCP, 80, 0x00);    /* reinitialize the socket */
      break;
    default:
    break;
  }// end of switch
}


void JTXD_do_http(void)
{
  uint8 ch=SOCK_HTTP;
  uint16 len;

  st_http_request *http_request;
  memset(rx_buf,0x00,MAX_URI_SIZE);
  http_request = (st_http_request*)rx_buf;		// struct of http request
  
  /* http service start */
  switch(getSn_SR(ch))
  {
    case SOCK_INIT:
      listen(ch);
      break;
    case SOCK_LISTEN:

      break;
    case SOCK_ESTABLISHED:
    //case SOCK_CLOSE_WAIT:
      if(getSn_IR(ch) & Sn_IR_CON)
      {
        setSn_IR(ch, Sn_IR_CON);
      }
      if ((len = getSn_RX_RSR(ch)) > 0)		
      {
        len = recv(ch, (uint8*)http_request, len); 
        *(((uint8*)http_request)+len) = 0;
        JTXD_proc_http(ch, (uint8*)http_request); // request is processed
        disconnect(ch);
      }
      break;
    case SOCK_CLOSE_WAIT:   
      if ((len = getSn_RX_RSR(ch)) > 0)
      {
        //printf("close wait: %d\r\n",len);
        len = recv(ch, (uint8*)http_request, len);       
        *(((uint8*)http_request)+len) = 0;
        JTXD_proc_http(ch, (uint8*)http_request); // request is processed
      }
      disconnect(ch);
      break;
    case SOCK_CLOSED:                   
      socket(ch, Sn_MR_TCP, 80, 0x00);    /* reinitialize the socket */
      break;
    default:
    break;
  }// end of switch
}

版权声明:本文为CSDN博主「今年又秃头了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_48302823/article/details/122129393

一:w5500以太网模块介绍:

W5500 是一款全硬件 TCP/IP 嵌入式以太网控制器,为嵌入式系统提供了更加简易的互联网连接方 案。W5500 集成了 TCP/IP 协议栈,10/100M 以太网数据链路层(MAC) 及物理层(PHY),使得 用户使用单芯片就能够在他们的应用中拓展网络连接。

久经市场考验的 WIZnet 全硬件 TCP/IP 协议栈支持 TCP,UDP,IPv4,ICMP,ARP,IGMP 以及 PPPoE 协议。W5500 内嵌 32K 字节片上缓存以供以太网包处理。如果你使用 W5500, 你只需要一些简单 的 Socket 编程就能实现以太网应用。这将会比其他嵌入式以太网方案 更加快捷、简便。用户可以同 时使用 8 个硬件 Socket 独立通讯。

W5500 提供了 SPI(外设串行接口)从而能够更加容易与外设 MCU 整合。而且, W5500 的使用了新的高效SPI协议支持 80MHz 速率,从而能够更好的实现高速网络通讯。 为了减少系统能耗, W5500 提供了网络唤醒模式(WOL)及掉电模式供客户选择使用。

模块排针功能表:

 STM32与W5500连接方法:

PA15->W5500_RST(源程序使用的是PC5,这里没有该引脚修改为PA15)

PC4->W5500_INT(使用寄存器查询方式的例程时,此引脚可以不接,其他例程可能涉及修改引脚)

PA4->W5500_SCS

PA5->W5500_SCK

PA6->W5500_MISO

PA7->W5500_MOSI

调试寄存器的UDP模式:

 

 

基于stm32与w5500以太网应用:

 

 如上图所示,最底下的一层叫做“物理层”,也叫“PHY 层”,最上面的一层叫做“应用层”,中间的三层(自下而上)分别是“链路层”,也叫“MAC 层”、 “网络层”和“传输层”。越下面的层,越靠近硬件;越上面的层,越靠近用户。
我们一层一层讲解
一、物理层
物理层就是最基础的类似于modbus中的硬件连接是rs485的两根线。物理层由计算机和网络介质之间的实际界面组成,可定义电气信号、符号、线的状态和时钟要求、数据编码和数据传输用的连接器。上面的4层都是基于物理层的。
二、数据链路层
实际上由两个独立的部分组成,介质存取控制(Media AccessControl,MAC)和逻辑链路控制层(Logical Link Control,LLC)。

其中spi2的四根线要接上w5500的 SCSn, SCLK, MOSI, MISO 4 路信号。还有中断信号和复位信号。
W5500 有两种工作模式,分别是可变数据长度模式和固定数据长度模式。在可变数据长度模式中,W5500 可以与其他 SPI 设备共用 SPI 接口。但是一旦将 SPI接口指定给 W5500 之后,也就是 1 脚 CS 片选信号如果选中了这个 W5500,则不能再与其他 SPI 设备共用。在固定数据长度模式,SPI 将指定给 W5500,不能与其他 SPI 设备共享。因为 1 脚 CS 片选信号将直接接地为低电平。
8.1w5500初始化
W5500_conf.c 主要配置 W5500 的 MAC、IP 地址,W5500 基本的数据读写过程,复位设置函数等。
Socket.c 函数主要介绍了 W5500 的 SOCKET 相关配置函数,比如 SOCKET 的打开、关闭,以及接收数据、发送数据等等。
Utility.c 函数主要介绍了基本的延时函数,还有数据格式转化函数。

main()函数代码:

int main(void)
{
	unsigned char i;

	/* Initialize STM32F103 */
	System_Initialization();//系统配置
	SysTick_Init();//启动系统滴答定时器 SysTick

	/* Config W5500 */
	W5500_Configuration();//W5500配置
	Delay_ms(200);//延时等待

	/* Modbus-TCP Init */
    eMBTCPInit(MB_TCP_PORT_USE_DEFAULT); //端口依赖事件模块初始化
	Delay_ms(200); //延时等待
	
	/* Enable Modbus-TCP Stack */    
    eMBEnable();//激活协议栈	
    

    printf("\r\nModbus-TCP Start!\r\n");
    printf("IP:192.168.1.128\r\n");


	while(1)
	{
		
		i=Read_SOCK_1_Byte(0,Sn_SR);  //读W5500状态
		if(i==0)	  
		{
			do
			{
				Delay_ms(100);//延时等待
			
			}while(Socket_Listen(0)==FALSE);//设置“Socket n”为“TCP服务器模式”
		}
		else if(i==SOCK_ESTABLISHED)		 //建立TCP连接
		{
		eMBPoll();//启动modbus侦听
		BSP_LED();//线圈控制LED灯
		}
				
	}
}

W5500配置函数:

/* W5500 configuration */
void W5500_Configuration()
{
	unsigned char array[6];

	GPIO_SetBits(GPIO_W5500_RST_PORT, GPIO_W5500_RST_Pin);//上拉
	Delay_ms(100);    /*delay 100ms 使用systick 1ms时基的延时*/
    //等待以太网链路
	while((Read_1_Byte(PHYCFGR)&LINK)==0); 		/* Waiting for Ethernet Link */

	Write_1_Byte(MR, RST);//写入W5500普通寄存器一个字节
	Delay_ms(20);		/*delay 20ms */

	/* Set Gateway IP as: 192.168.1.1 */
	array[0]=192;
	array[1]=168;
	array[2]=1;
	array[3]=1;
	Write_Bytes(GAR, array, 4);//设置网关IP

	/* Set Subnet Mask as: 255.255.255.0 */
	array[0]=255;
	array[1]=255;
	array[2]=255;
	array[3]=0;
	Write_Bytes(SUBR, array, 4);//设置子网掩码

	/* Set MAC Address as: 0x48,0x53,0x00,0x57,0x55,0x00 */
	array[0]=0x48;
	array[1]=0x53;
	array[2]=0x00;
	array[3]=0x57;
	array[4]=0x55;
	array[5]=0x00;
	Write_Bytes(SHAR, array, 6);//设置MAC地址

	/* Set W5500 IP as: 192.168.1.128 */
	array[0]=192;
	array[1]=168;
	array[2]=1;
	array[3]=128;
	Write_Bytes(SIPR, array, 4);//设置W5500的IP地址
}

STM32+W5500的web服务

main()函数:

int main(void)
{
	Systick_Init(72);//系统时钟初始化
	GPIO_Configuration(); //GPIO configuration
	USART1_Init(); //串口初始化:115200@8-n-1
	printf("W5500 EVB initialization over.\r\n");
	Reset_W5500();
	WIZ_SPI_Init();//W5500相关引脚配置
	printf("W5500 initialized!\r\n");
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7))
	{
		DefaultSet();//出厂值
	}
	else
	{
 		get_config();//read config data from flash
	}
	printf("Firmware ver%d.%d\r\n",ConfigMsg.sw_ver[0],ConfigMsg.sw_ver[1]);
	if(ConfigMsg.debug==0) ConfigMsg.debug=1;

	set_network();//配置网络信息
	printf("Network is ready.\r\n");
	while(1)
	{
		if(ConfigMsg.JTXD_Control == 0)
		  	do_http();//开启http服务
		else
		  	JTXD_do_http();
		if(reboot_flag)
			NVIC_SystemReset();//发起系统复位请求复位单片机
//        reboot();
        
	}
}

GPIO初始化函数:

void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO , ENABLE);
  // Port A output
  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1| GPIO_Pin_2 |GPIO_Pin_3; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
//  GPIO_ResetBits(GPIOA, GPIO_Pin_0);
//  GPIO_ResetBits(GPIOA, GPIO_Pin_1);
//  GPIO_SetBits(GPIOA, GPIO_Pin_2); // led off
//  GPIO_SetBits(GPIOA, GPIO_Pin_3); // led off
  // Port B output;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_SetBits(GPIOB, GPIO_Pin_9);
  // Port C input
//  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
//  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//控制flash
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_SetBits(GPIOB, GPIO_Pin_7);	
}

W5500相关配置

void WIZ_SPI_Init(void)
{
	SPI_InitTypeDef   SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB |RCC_APB2Periph_AFIO , ENABLE);	
  // Port B output
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_SetBits(GPIOB, GPIO_Pin_12);
  /* Configure SPIy pins: SCK, MISO and MOSI */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
	  /* SPI Config -------------------------------------------------------------*/
	  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
	  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
	  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
	  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	  SPI_InitStructure.SPI_CRCPolynomial = 7;

	  SPI_Init(SPI2, &SPI_InitStructure);
	  SPI_Cmd(SPI2, ENABLE);
}

http请求:

void do_http(void)
{
  uint8 ch=SOCK_HTTP;
  uint16 len;

  st_http_request *http_request;
  memset(rx_buf,0x00,MAX_URI_SIZE);
  http_request = (st_http_request*)rx_buf;		// struct of http request  
  /* http service start */
  switch(getSn_SR(ch))
  {
    case SOCK_INIT:
      listen(ch);
      break;
    case SOCK_LISTEN:
      break;
    case SOCK_ESTABLISHED:
    //case SOCK_CLOSE_WAIT:
      if(getSn_IR(ch) & Sn_IR_CON)
      {
        setSn_IR(ch, Sn_IR_CON);
      }
      if ((len = getSn_RX_RSR(ch)) > 0)		
      {
        len = recv(ch, (uint8*)http_request, len); 
        *(((uint8*)http_request)+len) = 0;
        proc_http(ch, (uint8*)http_request); // request is processed
        disconnect(ch);
      }
      break;
    case SOCK_CLOSE_WAIT:   
      if ((len = getSn_RX_RSR(ch)) > 0)
      {
        //printf("close wait: %d\r\n",len);
        len = recv(ch, (uint8*)http_request, len);       
        *(((uint8*)http_request)+len) = 0;
        proc_http(ch, (uint8*)http_request); // request is processed
      }
      disconnect(ch);
      break;
    case SOCK_CLOSED:
      socket(ch, Sn_MR_TCP, 80, 0x00);    /* reinitialize the socket */
      break;
    default:
    break;
  }// end of switch
}


void JTXD_do_http(void)
{
  uint8 ch=SOCK_HTTP;
  uint16 len;

  st_http_request *http_request;
  memset(rx_buf,0x00,MAX_URI_SIZE);
  http_request = (st_http_request*)rx_buf;		// struct of http request
  
  /* http service start */
  switch(getSn_SR(ch))
  {
    case SOCK_INIT:
      listen(ch);
      break;
    case SOCK_LISTEN:

      break;
    case SOCK_ESTABLISHED:
    //case SOCK_CLOSE_WAIT:
      if(getSn_IR(ch) & Sn_IR_CON)
      {
        setSn_IR(ch, Sn_IR_CON);
      }
      if ((len = getSn_RX_RSR(ch)) > 0)		
      {
        len = recv(ch, (uint8*)http_request, len); 
        *(((uint8*)http_request)+len) = 0;
        JTXD_proc_http(ch, (uint8*)http_request); // request is processed
        disconnect(ch);
      }
      break;
    case SOCK_CLOSE_WAIT:   
      if ((len = getSn_RX_RSR(ch)) > 0)
      {
        //printf("close wait: %d\r\n",len);
        len = recv(ch, (uint8*)http_request, len);       
        *(((uint8*)http_request)+len) = 0;
        JTXD_proc_http(ch, (uint8*)http_request); // request is processed
      }
      disconnect(ch);
      break;
    case SOCK_CLOSED:                   
      socket(ch, Sn_MR_TCP, 80, 0x00);    /* reinitialize the socket */
      break;
    default:
    break;
  }// end of switch
}

版权声明:本文为CSDN博主「今年又秃头了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_48302823/article/details/122129393

生成海报
点赞 0

今年又秃头了

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

STM32+W5500网络通信

一、Modbus/TCP协议 1.查询报文 00 6D 00 00 00 06 01 03 00 00 00 01 00 6D 查询编号 00 00 协议 00 06 数据包长度 01 设备编号 03 功能码 00 00 起始地址 00 01

STM32F103基于W5500实现Modbus简单TCP通信

一,目的 掌握W5500网络模块的特点,参考模块厂商配套资料,完成TCP数据通信、DHCP自动获取IP的程序设计。在此基础上,实现应用层modbus、httpd(web服务

W5500+STM32F103C8T6进行TCP通信(modbus)

一、w5500资料 w5500的资料就放在下面了,单纯的客户端和其他模式上面有教程 https://www.aliyundrive.com/s/enPnnZgNtpE 二、modbus通信 Modbus RTU通信时使用的数据帧