百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

W5500模块-UDP模式收发代码解析(w5500 tcp server)

cac55 2024-10-12 02:27 48 浏览 0 评论

MAIN.C

/

* 描述 :W5500的端口0工作在UDP模式,端口通信不需要建立连接即可接收其它UDP模式端口发来的数据,

* 数据的前4个字节为对方端口IP地址,第5、6个字节为端口号,获得对方IP和端口号后W5500端口0

* 将定时给对应端口发送字符串"\r\nWelcome To YiXinElec!\r\n",同时将接收

* 到的数据回发给对应端口。

* 实验平台:用户STM32开发板 + YIXIN_W5500以太网(TCP/IP)模块

* 硬件连接: PC5 -> W5500_RST

* PA4 -> W5500_SCS

* PA5 -> W5500_SCK

* PA6 -> W5500_MISO

* PA7 -> W5500_MOSI

***************************************************************************************/

/*网络参数*/

//网关:192.168.1.1

//掩码: 255.255.255.0

//物理地址:0C 29 AB 7C 00 01

//本机IP地址:192.168.1.199

//端口0的端口号:5000

//端口0的目的IP地址:192.168.1.190

//端口0的目的端口号:6000

#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; //W5500发送延时计数变量(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] = 1;

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]=1;

IP_Addr[3]=199;

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

S0_Port[1] = 0x88;

S0_Mode=UDP_MODE;//加载端口0的工作模式,UDP模式

}

/*******************************************************************************

* 函数名 : 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);

UDP_DIPR[0] = Rx_Buffer[0];

UDP_DIPR[1] = Rx_Buffer[1];

UDP_DIPR[2] = Rx_Buffer[2];

UDP_DIPR[3] = Rx_Buffer[3];

UDP_DPORT[0] = Rx_Buffer[4];

UDP_DPORT[1] = Rx_Buffer[5];

memcpy(Tx_Buffer, Rx_Buffer+8, size-8);

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端口初始化配置

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 >= 500)//定时发送字符串

{

if(S0_State == (S_INIT|S_CONN))

{

S0_Data&=~S_TRANSMITOK;

memcpy(Tx_Buffer, "\r\nWelcome To YiXinElec!\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以下配置

//

/* 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);

}

/*******************************************************************************

* 函数名 : 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);

}

相关推荐

让组策略保护Windows XP的安全

默认安装完WindowsXP之后,我们的WindowsXP并不很安全。因此,我们有必要对系统进行一些修修补补,一般情况下我们都要动用到注册表。诚然,修改注册表是一种非常有效的方法,但是它需要一定的...

你造吗?十种方式保护你免受&quot;零日攻击&quot;

|责编:王迪WindowsXP的寿终正寝,数据安全问题又再一次成为人们关注的焦点。近日,微软透漏,一个基于InternetExplorer的“零日攻击”给用户带来了严重破坏。“零日攻击”一种利用...

特立独行——打造游戏专用独立系统

大部分人的电脑是为了学习和工作用的,所以,如果你是一个游戏迷,那么推荐你安装一个独立系统专用于游戏,做到工作娱乐两不相扰。方案1:游戏专用移动WindowsXP目的:解决游戏兼容性问题喜欢玩游戏的都...

驰为VX8 3G Win8入门教程篇

距离Win8.1的正式发布也将近1年了,凭借着Win8.1在移动便携以及娱乐办公上的优势,现在的Win8平板越来越受到消费者的追捧,而驰为VX83G就是其中一款,搭载了卓越的英特尔Z3735G四核芯,...

易淘收银软件说明

易淘收银系统,简称易淘收银,专为小型及连锁零售、餐饮行业打造。基于SaaS模式,智能便捷,无需维护,轻量级设计却功能强大,简约而不失专业,助力门店高效管理收银。1、前台系统:收银客户端;2、后台系...

CAD打不开怎么办?原因可能是电脑中毒了,6步就能完美解决问题

一、问题描述我的CAD安装后无法打开,安装过程中没有出现任何问题,但是安装后打开就出现一个对话框“DBXCAS0”点击后又出现“FATALERROR:UnhandledAccessViola...

腾讯QQ6.1正式版发布更新

2014-07-2405:12:00作者:张林【中关村在线软件资讯】7月24日消息:腾讯QQ官网小幅更新了QQ6.1正式版,最新版本号升级至11905,继续主打扁平化、炫酷登录窗口、支持同步最近一...

Win10等网页版OneDrive无法登陆怎么办?

IT之家(www.ithome.com):Win10等网页版OneDrive无法登陆怎么办?Win10之家报道,微软OneDrive云网盘是跨平台的数据同步和存储服务,支持WindowsPC(如Wi...

经典回顾:折戟沉沙的Windows Longhorn有着惊艳的登录屏幕

尽管微软原先计划让WindowsLonghorn继承WindowsXP操作系统的衣钵,但这个充满雄心壮志的操作系统项目最终还是未能迎来曙光,而是被微软用WindowsVista取而代...

电脑怎么优化

电脑配置和宽带流量也是硬件,但这些要求其实并不需要很高,关键还是怎么去安全使用电脑并进行有效的优化。电脑的应用和优化处理一、电脑的应用和优化处理二、目前,大家使用的个人电脑,配置方面均没多大问题,比如...

怎么安装usb驱动

USB驱动主要是针对WIN98时代的说法,如今WINXP已集成大部分USB驱动,通常都能识别。只有极少数情况下,例如手机、打印机或扫描仪等办公设备的USB驱动可能无法自动识别。1、USB驱动偶尔无法...

普通话考试多名考生信息被泄露,接投诉后涉事网站被限制访问

“陕西普通话成绩查询网(sxpth.cn)”泄露个人信息网站截图网传图片显示,407名普通话考试考生的姓名、身份证号码等个人信息疑似被泄露。9月26日下午,涉事网站sxpth.cn的域名注册商——成...

电脑伪技巧——个人电脑无需设置登录密码

默认情况下,我们每次登录系统都要输入登录账户对应的密码才能进入桌面。有些朋友觉得这样很麻烦,由于电脑只是自己使用,还不如不要设置密码,这样每次可以自动登录。大家知道,账户密码是系统验证用户合法性的唯一...

Windows 10/11 自带远程桌面:实用技巧与操作指南

Windows10/11自带远程桌面:实用技巧与操作指南在当今快节奏的数字时代,远程访问和控制计算机的需求日益增长。微软在Windows10和Windows11中内置了远程桌面功能,为用户提供...

不升级系统的5大原因造吗?

2015-01-2405:54:00作者:陈占伟Windows10系统的发布,让人们重新将目光聚焦到生命力长久的Windows系统之上。如今操作系统越来越多,似乎Windows升级的获得的关注度...

取消回复欢迎 发表评论: