资讯详情

stm32 w5500以太网模块使用

写完标题后,我发现似乎没有什么可写的. 主要原因是硬件从来没有这么顺利。总结一下 1.购买后发送的文件非常详细。即便如此,接线也没有说明 3.3v 和gnd要接.他们可能认为这是常识猪都知道, 但是有些人真的不知道我在做软件,但是我的直觉让我接上了 2.当出现问题时,很难找到与硬件相关的问题。例如,我的板开关接触不良,但我没有在上面贴上标签,所以在烧制程序后没有电源。它是通过插入模拟器usb 这提供了稳定的电压 3.keil v5 是我的ide ,但示例程序是v4、不兼容 表现为cpu不在我的列表里,编译后烧录报错,只好在v5的工程,代码,工程对应我的板.只有这样才能成功烧录. 4.netAssist.exe 网络调试助手 很好用, http://www.cmsoft.cn

贴下代码吧

/*************************************************************************************** * 工程名 :泥人W5500模块-客户端模型例程 * 描述 :W在客户端模式下,5500端口0工作,主动提供泥人《TCP&UDP在测试工具上创建的服务端连接, * 并且以500ms定期将字符串发送到服务器"\r\nWelcome To NiRenElec!\r\n",同时将接 * 回发到服务端的数据。 * 实验平台:NiRen_TwoHeart系统板(或用户)STM32开发板) NiRen_W5500以太网(TCP/IP)模块 * 硬件连接: PC5 -> W5500_RST * PC4 -> W5500_INT * PA4 -> W5500_SCS * PA5 -> W5500_SCK * PA6 -> W5500_MISO * PA7 -> W5500_MOSI * 库版本 :ST_v3.5 * 作者 :泥人通信模块开发团队 * 博客 :http://nirenelec.blog.163.com * 淘宝 :http://nirenelec.taobao.com ***************************************************************************************/  /*例程网络参数*/ //网关:192.168.0.1 //掩码: 255.255.255.0 物理地址:0C 29 AB 7C 00 01 //本机IP地址:192.168.0.199 ///端口0端口号:5000 ///端口0的目的IP地址:192.168.0.101 ///端口0目的端口号:6万  //配合 NetAssist.exe 作为调试工具|  #include "stm32f10x.h"  #include "W5500.h"  #include <string.h>  void RCC_Configuration(void);  ///设置系统时钟为72MHZ(这个可以根据需要改) void NVIC_Configuration(void);  //STM32中断向量表配置 void Timer2_Init_Config(void);  //Timer2初始化配置 void System_Initialization(void); //STM32系统初始化函数(初始化函数)STM32小时及外设) void Delay(unsigned int d);   ///延迟函数(ms)  unsigned int Timer2_Counter=0; //Timer2定时器计数变量(ms) unsigned int W5500_Send_Delay_Counter=0; //W延迟计数变量5500(ms)  /******************************************************************************* * 函数名 : W5500_Initialization * 描述 : W5500初始货配置 * 输入 : 无 * 输出 : 无 * 返回值 : 无 * 说明 : 无 *******************************************************************************/ void W5500_Initialization(void)
{ 
       
	W5500_Init();		//初始化W5500寄存器函数
	Detect_Gateway();	//检查网关服务器 
	Socket_Init(0);		//指定Socket(0~7)初始化,初始化端口0
}

/******************************************************************************* * 函数名 : Load_Net_Parameters * 描述 : 装载网络参数 * 输入 : 无 * 输出 : 无 * 返回值 : 无 * 说明 : 网关、掩码、物理地址、本机IP地址、端口号、目的IP地址、目的端口号、端口工作模式 *******************************************************************************/
void Load_Net_Parameters(void)
{ 
       
	Gateway_IP[0] = 192;//加载网关参数
	Gateway_IP[1] = 168;
	Gateway_IP[2] = 0;
	Gateway_IP[3] = 1;

	Sub_Mask[0]=255;//加载子网掩码
	Sub_Mask[1]=255;
	Sub_Mask[2]=255;
	Sub_Mask[3]=0;

	Phy_Addr[0]=0x0c;//加载物理地址
	Phy_Addr[1]=0x29;
	Phy_Addr[2]=0xab;
	Phy_Addr[3]=0x7c;
	Phy_Addr[4]=0x00;
	Phy_Addr[5]=0x01;

	IP_Addr[0]=192;//加载本机IP地址
	IP_Addr[1]=168;
	IP_Addr[2]=0;
	IP_Addr[3]=199;

	S0_Port[0] = 0x13;//加载端口0的端口号5000 
	S0_Port[1] = 0x88;

	S0_DIP[0]=192;//加载端口0的目的IP地址
	S0_DIP[1]=168;
	S0_DIP[2]=0;
	S0_DIP[3]=101;
	
	S0_DPort[0] = 0x17;//加载端口0的目的端口号6000
	S0_DPort[1] = 0x70;

	S0_Mode=TCP_CLIENT;//加载端口0的工作模式,TCP客户端模式
}

/******************************************************************************* * 函数名 : W5500_Socket_Set * 描述 : W5500端口初始化配置 * 输入 : 无 * 输出 : 无 * 返回值 : 无 * 说明 : 分别设置4个端口,根据端口工作模式,将端口置于TCP服务器、TCP客户端或UDP模式. * 从端口状态字节Socket_State可以判断端口的工作情况 *******************************************************************************/
void W5500_Socket_Set(void)
{ 
       
	if(S0_State==0)//端口0初始化配置
	{ 
       
		if(S0_Mode==TCP_SERVER)//TCP服务器模式 
		{ 
       
			if(Socket_Listen(0)==TRUE)
				S0_State=S_INIT;
			else
				S0_State=0;
		}
		else if(S0_Mode==TCP_CLIENT)//TCP客户端模式 
		{ 
       
			if(Socket_Connect(0)==TRUE)
				S0_State=S_INIT;
			else
				S0_State=0;
		}
		else//UDP模式 
		{ 
       
			if(Socket_UDP(0)==TRUE)
				S0_State=S_INIT|S_CONN;
			else
				S0_State=0;
		}
	}
}

/******************************************************************************* * 函数名 : Process_Socket_Data * 描述 : W5500接收并发送接收到的数据 * 输入 : s:端口号 * 输出 : 无 * 返回值 : 无 * 说明 : 本过程先调用S_rx_process()从W5500的端口接收数据缓冲区读取数据, * 然后将读取的数据从Rx_Buffer拷贝到Temp_Buffer缓冲区进行处理。 * 处理完毕,将数据从Temp_Buffer拷贝到Tx_Buffer缓冲区。调用S_tx_process() * 发送数据。 *******************************************************************************/
void Process_Socket_Data(SOCKET s)
{ 
       
	unsigned short size;
	size=Read_SOCK_Data_Buffer(s, Rx_Buffer);
	memcpy(Tx_Buffer, Rx_Buffer, size);			
	Write_SOCK_Data_Buffer(s, Tx_Buffer, size);
}

/******************************************************************************* * 函数名 : main * 描述 : 主函数,用户程序从main函数开始运行 * 输入 : 无 * 输出 : 无 * 返回值 : int:返回值为一个16位整形数 * 说明 : 无 *******************************************************************************/
int main(void)
{ 
       
	System_Initialization();	//STM32系统初始化函数(初始化STM32时钟及外设)
	Load_Net_Parameters();		//装载网络参数 
	W5500_Hardware_Reset();		//硬件复位W5500
	W5500_Initialization();		//W5500初始货配置
	while (1)
	{ 
       
		W5500_Socket_Set();//W5500端口初始化配置

		if(W5500_Interrupt)//处理W5500中断 
		{ 
       
			W5500_Interrupt_Process();//W5500中断处理程序框架
		}
		if((S0_Data & S_RECEIVE) == S_RECEIVE)//如果Socket0接收到数据
		{ 
       
			S0_Data&=~S_RECEIVE;
			Process_Socket_Data(0);//W5500接收并发送接收到的数据
		}
		else if(W5500_Send_Delay_Counter >= 8)//定时发送字符串
		{ 
       
			if(S0_State == (S_INIT|S_CONN))
			{ 
       
				S0_Data&=~S_TRANSMITOK;
				memcpy(Tx_Buffer, "\r\nWelcome To NiRenElec!\r\n", 23);	
				Write_SOCK_Data_Buffer(0, Tx_Buffer, 23);//指定Socket(0~7)发送数据处理,端口0发送23字节数据
			}
			W5500_Send_Delay_Counter=0;
		}
	}
}

/******************************************************************************* * 函数名 : RCC_Configuration * 描述 : 设置系统时钟为72MHZ(这个可以根据需要改) * 输入 : 无 * 输出 : 无 * 返回值 : 无 * 说明 : STM32F107x和STM32F105x系列MCU与STM32F103x系列MCU时钟配置有所不同 *******************************************************************************/
void RCC_Configuration(void)
{ 
       
  ErrorStatus HSEStartUpStatus;               //外部高速时钟(HSE)的工作状态变量
  
  RCC_DeInit();                               //将所有与时钟相关的寄存器设置为默认值
  RCC_HSEConfig(RCC_HSE_ON);                  //启动外部高速时钟HSE 
  HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟(HSE)稳定

  if(SUCCESS == HSEStartUpStatus)             //如果外部高速时钟已经稳定
  { 
       
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Flash设置
    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_2);
    
  
    RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟等于系统时钟(1分频)/72MHZ
    RCC_PCLK2Config(RCC_HCLK_Div1);  //设置APB2时钟和HCLK时钟相等/72MHz(最大为72MHz)
    RCC_PCLK1Config(RCC_HCLK_Div2);  //设置APB1时钟是HCLK时钟的2分频/36MHz(最大为36MHz)
  
#ifndef STM32F10X_CL //如果使用的不是STM32F107x或STM32F105x系列MCU,PLL以下配置 
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHz 
#else //如果使用的是STM32F107x或STM32F105x系列MCU,PLL以下配置
    /***** 配置PLLx *****/
    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
    RCC_PREDIV2Config(RCC_PREDIV2_Div5);
    RCC_PLL2Config(RCC_PLL2Mul_8);

    RCC_PLL2Cmd(ENABLE); //使能PLL2 
    while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);//等待PLL2稳定

    /* PLL configuration: PLLCLK = (PLL2 / 5) * 9 = 72 MHz */ 
    RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
    RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
#endif

    RCC_PLLCmd(ENABLE); //使能PLL
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL稳定

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);          //设置系统时钟的时钟源为PLL

    while(RCC_GetSYSCLKSource() != 0x08);               //检查系统的时钟源是否是PLL
    RCC_ClockSecuritySystemCmd(ENABLE);                 //使能系统安全时钟 

	/* Enable peripheral clocks --------------------------------------------------*/
  	/* Enable I2C1 and I2C1 clock */
 	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  	/* Enable GPIOA GPIOB SPI1 and USART1 clocks */
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB
					| RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD
					| RCC_APB2Periph_AFIO, ENABLE);    
  }
}

/******************************************************************************* * 函数名 : NVIC_Configuration * 描述 : STM32中断向量表配配置 * 输入 : 无 * 输出 : 无 * 返回值 : 无 * 说明 : 设置KEY1(PC11)的中断优先组 *******************************************************************************/
void NVIC_Configuration(void)
{ 
       
	NVIC_InitTypeDef NVIC_InitStructure;						//定义NVIC初始化结构体

  	/* Set the Vector Table base location at 0x08000000 */
  	NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);				//设置中断优先级组为1,优先组(可设0~4位)
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;				//设置中断向量号
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	//设置抢先优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;			//设置响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能NVIC
	NVIC_Init(&NVIC_InitStructure);

	W5500_NVIC_Configuration();	//W5500 接收引脚中断优先级设置
}

/******************************************************************************* * 函数名 : Timer2_Init_Config * 描述 : Timer2初始化配置 * 输入 : 无 * 输出 : 无 * 返回 : 无 * 说明 : 无 *******************************************************************************/
void Timer2_Init_Config(void)
{ 
       
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);		//使能Timer2时钟
	
	TIM_TimeBaseStructure.TIM_Period = 9;						//设置在下一个更新事件装入活动的自动重装载寄存器周期的值(计数到10为1ms)
	TIM_TimeBaseStructure.TIM_Prescaler = 7199;					//设置用来作为TIMx时钟频率除数的预分频值(10KHz的计数频率)
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;		//设置时钟分割:TDTS = TIM_CKD_DIV1
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;	//TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);				//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	 
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE ); 				//使能TIM2指定的中断
	
	TIM_Cmd(TIM2, ENABLE);  									//使能TIMx外设
}

/******************************************************************************* * 函数名 : TIM2_IRQHandler * 描述 : 定时器2中断断服务函数 * 输入 : 无 * 输出 : 无 * 返回 : 无 * 说明 : 无 *******************************************************************************/
void TIM2_IRQHandler(void)
{ 
       
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{ 
       
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
		Timer2_Counter++;
		W5500_Send_Delay_Counter++;
	}
}

/******************************************************************************* * 函数名 : System_Initialization * 描述 : STM32系统初始化函数(初始化STM32时钟及外设) * 输入 : 无 * 输出 : 无 * 返回 : 无 * 说明 : 无 *******************************************************************************/
void System_Initialization(void)
{ 
       
	RCC_Configuration();		//设置系统时钟为72MHZ(这个可以根据需要改)
  	NVIC_Configuration();		//STM32中断向量表配配置
	SPI_Configuration();		//W5500 SPI初始化配置(STM32 SPI1)
	Timer2_Init_Config();		//Timer2初始化配置
	W5500_GPIO_Configuration();	//W5500 GPIO初始化配置 
}

/******************************************************************************* * 函数名 : Delay * 描述 : 延时函数(ms) * 输入 : d:延时系数,单位为毫秒 * 输出 : 无 * 返回 : 无 * 说明 : 延时是利用Timer2定时器产生的1毫秒的计数来实现的 *******************************************************************************/
void Delay(unsigned int d)
{ 
       
	Timer2_Counter=0; 
	while(Timer2_Counter < d);
}

需注意的是 1.设备要在一个子网内,同个网关 2.设好服务端的ip和端口. 这个代码是客户端, 不需要在意客户端的IP端口

对了,顺便看下效果, 同是8ms发送一次到服务端 这是windows发送,且无线wifi发送: 在这里插入图片描述 这是上面的代码,stm32发送,且有线发送: 摊手撇嘴.jpg 对实时性有要求那就必须使用stm32, 当然还有其他方案,比如linux系统安装RT(realtime)模块

标签: 107安全继电器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台