W5500模块-UDP模式收发代码解析(w5500 tcp server)
cac55 2024-10-12 02:27 62 浏览 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);
}
相关推荐
- 高中生又来卷我们了!手搓 Android 浏览器,可高度定制+脚本支持
-
回想一下,你曾经的暑假,是怎么度过的?可能是无尽的娱乐时光,或者是懒洋洋的休息日。然而,对于这位Gitee上的高中生来说,他选择在这个暑假里独立开发一款Android浏览器——Vie浏览器,...
- 网页加载CAD图纸的两个方案对比说明(网页浏览编辑DWG)
-
一.说明梦想控件提供两种技术在网页中加载CAD图纸,一个是OCX技术方案,另一个是HTML5技术方案,它们各有优缺点,用户需根据实际情况进行选择,下边分别说明一下。1、ocx技术方案(1)OCX技术是...
- 前后端分离的开源在线考试系统调试实战
-
开篇在我们的教育生涯中,或多或少的都接触过在线考试系统。例如大学里最常见的各种软件考试,上机考试等,那么有没有开源的这样的系统呢?当然是有了,今天就来调试个开源的在线考试系统。本文重点是调试,因为很多...
- 网友:小松鼠长大了!UC浏览器推出18周年专版logo引热议
-
近日,互联网厂商logo更新再次引发热议。作为国内手机浏览器的代表性厂商,UC浏览器的标志性logo小松鼠悄然发生了变化,在网友中引发了关注和讨论。依照UC微博官方账号的说法,这个全新的形象是UC18...
- 超多案例!谷歌AI模型Nano Banana的5个实用+趣味玩法
-
再不用这个AI修图神器,你的同行明天就把订单抢光了。谷歌刚放出的NanoBanana,能在一张照片里把背景、姿势、衣服一次换完,脸还是那张脸。实测把地铁照改成海边大片,只用一句话,三秒出图,不用PS来...
- 2025年最佳Windows数据恢复软件解决方案前5名
-
您是否正在寻找互联网上排名前五的WindowsPC最佳数据恢复软件解决方案?其实,网上有很多工具可以恢复已删除的文件。但并非所有应用程序都值得使用。值得信赖的文件恢复工具可以帮助您快速检索丢失、删...
- 电脑数据恢复软件推荐:10个顶级数据恢复软件分享
-
在数字化的工作与生活中,电脑文件误删除的情况时有发生,这不仅会引发我们的焦虑情绪,更可能导致重要数据的丢失。不过,幸运的是,借助正确的数据恢复软件,我们仍有机会找回那些被误删的文件。10个顶级数据恢复...
- 更懂国内APP的开源智能体!感知定位推理中文能力全面提升
-
更懂国内APP的开源智能体!感知定位推理中文能力全面提升“帮我点外卖,别点到广告位。”一句话,说出了多少人对手机自动化的真实期待。浙大和美团刚扔出来的开源项目UItron,就是冲着这句吐槽来的——它真...
- 美光首家推出采用EUV技术的1γ DDR5 DRAM芯片
-
美光科技宣布已开始向部分生态系统合作伙伴和客户出货1γ(1-gamma)16GbitDDR5DRAM芯片。美光声称,它是第一个采用1-gamma(1γ)节点的公司,该节点指的是DRAM工艺技术的第...
- DDR4的PCB设计及仿真_ddr pcb
-
以下文章来源于鼎阳硬件智库,作者王彦武DDR4关键技术和方法分析1.1DDR4与DDR3不同之处相对于DDR3,DDR4首先在外表上就有一些变化,比如DDR4将内存下部设计为中间稍微突出,边缘变...
- DDR4和DDR5内存的性能差距有哪些?
-
DDR4和DDR5内存的性能差距主要体现在带宽、延迟、能效及未来扩展性上,以下是关键差异的总结及选择建议:1.带宽与频率DDR4:主流频率为2133MHz–3600MHz,带宽约25.6–30.2...
- DDR5内存一根和两根的区别,建议收藏观看。
-
大家好,我是海韵,DDR5内存条,单条和双条有什么区别,如何选择,DDR5单条和双条内存在性能上存在差距,单条内存保持在64个通道,但内部升级为32乘以2,虽然出口速度相同,但内部运行略有提升,...
- Kingston FURY叛逆者DDR5 RGB CUDIMM内存评测 强势突破9000MT/s!
-
【ZOL中关村在线原创评测】当8000MT/s从当年的液氮超频艰难达成,到如今XMP轻松开启,DDR5内存频率的极限探索似乎看不到终点。在早先,我们曾为大家带来KingstonFURY品牌的叛逆者D...
- SK海力士将在年内推出1bnm 32Gb DDR5内存颗粒
-
IT之家4月25日消息,据韩媒NEWSIS报道,SK海力士在今日的2024年一季度财报电话会议上表示将在年内推出1bnm32GbDDR5内存颗粒。32Gb颗粒意味着消费级的...
- DRAM史上最大代际倒挂继续:三星将延长DDR4生产期限至2026年
-
IT之家8月6日消息,韩媒TheElec今天(8月6日)发布博文,报道称三星决定延长DDR41zDRAM的生产期限至2026年,一方面在DRAM史上最大代际倒挂中进...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 如何绘制折线图 (52)
- javaabstract (48)
- 新浪微博头像 (53)
- grub4dos (66)
- s扫描器 (51)
- httpfile dll (48)
- ps实例教程 (55)
- taskmgr (51)
- s spline (61)
- vnc远程控制 (47)
- 数据丢失 (47)
- wbem (57)
- flac文件 (72)
- 网页制作基础教程 (53)
- 镜像文件刻录 (61)
- ug5 0软件免费下载 (78)
- debian下载 (53)
- ubuntu10 04 (60)
- web qq登录 (59)
- 笔记本变成无线路由 (52)
- flash player 11 4 (50)
- 右键菜单清理 (78)
- cuteftp 注册码 (57)
- ospf协议 (53)
- ms17 010 下载 (60)