首页 > 其他分享 >STM32驱动W5500应用

STM32驱动W5500应用

时间:2023-03-24 22:03:23浏览次数:49  
标签:ConfigMsg W5500 IP .% STM32 printf 驱动 gateway

1.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应用_DHCP


2.W5500动态获取IP

硬件开发平台:STM32F103C8T6

驱动协议:SPI

开发环境:KEIL5

2.1 接线方式

W5500模块

STM32核心板

片选CS

PB12

时钟SCLK

PB13

主机输入MISO

PB14

主机输出MOSI

PB15

INT

PB0

RST

PB1

2.2 SPI底层接口函数

      SPI 协议定义了四种工作模式(模式 0, 1 , 2, 3)。每种模式的区别是根据 SCLK的极性及相位不同定义的。 SPI 的模式 0 和模式 3 唯一不同的就是在非活动状态下,SCLK 信号的极性。

     SPI 的模式 0 和 3,数据都是在 SCLK 的上升沿锁存,在下降沿输出。

     W5500 支持 SPI 模式 0 及模式 3.MOSI 和 MISO 信号无论是接收或发送,均遵从从最高标志位(MSB)到最低标志位(LSB)的传输序列。

STM32驱动W5500应用_物联网平台_02

/*硬件配置*/
void W5500_GPIO_Init(void)
{
  RCC->APB2ENR|=1<<3;
  GPIOB->CRH&=0x0000FFFF;
  GPIOB->CRH|=0x38330000;
  GPIOB->CRL&=0xFFFFFF00;
  GPIOB->CRL|=0x00000038;
  W5500_CS=1;
  W5500_RST=1;
}
/*SPI读写一个字节*/
u8 SPI_WR_Byte(u8 byte)
{
  u8 data_rx=0;
  u8 i=0;
  for(i=0;i<8;i++)
  {
    W5500_SCLK=0;
    if(byte&0x80)W5500_MOSI=1;
    else W5500_MOSI=0;
    W5500_SCLK=1;
    byte<<=1;
    
    data_rx<<=1;
    if(W5500_MISO)data_rx|=0x01;
  }
  W5500_SCLK=0;
  return data_rx;
}


2.3 W5500动态IP获取

/*配置W5500网卡信息*/
void set_w5500_ip(void)
{
  /*复制定义的配置信息到配置结构体*/
	memcpy(ConfigMsg.mac, mac, 6);//MAC地址
  memcpy(ConfigMsg.lip,local_ip,4);//IP
  memcpy(ConfigMsg.sub,subnet,4);//子网掩码
  memcpy(ConfigMsg.gw,gateway,4);//网关
  memcpy(ConfigMsg.dns,dns_server,4);//DNS
  
  
  if(ip_from == IP_FROM_DHCP)/*动态获取IP*/
  {
    if(dhcp_ok==1)/*动态获取IP成功*/
    {
      printf(" IP from DHCP\r\n");		 
			memcpy(ConfigMsg.lip,DHCP_GET.lip, 4);
			memcpy(ConfigMsg.sub,DHCP_GET.sub, 4);
			memcpy(ConfigMsg.gw,DHCP_GET.gw, 4);
			memcpy(ConfigMsg.dns,DHCP_GET.dns,4);
    }
  }
  
  /*将IP配置信息写入W5500相应寄存器*/	
	setSUBR(ConfigMsg.sub);
	setGAR(ConfigMsg.gw);
	setSIPR(ConfigMsg.lip);
  /*判断数据是否写入成功*/
	getSIPR (local_ip);			
	printf(" W5500 IP地址   : %d.%d.%d.%d\r\n", local_ip[0],local_ip[1],local_ip[2],local_ip[3]);
	getSUBR(subnet);
	printf(" W5500 子网掩码 : %d.%d.%d.%d\r\n", subnet[0],subnet[1],subnet[2],subnet[3]);
	getGAR(gateway);
	printf(" W5500 网关     : %d.%d.%d.%d\r\n", gateway[0],gateway[1],gateway[2],gateway[3]);  
}
//配置W5500的MAC地址
void set_w5500_mac(void)
{
	memcpy(ConfigMsg.mac, mac, 6);
	setSHAR(ConfigMsg.mac);	
	memcpy(DHCP_GET.mac, mac, 6);
}

2.4效果展示

STM32驱动W5500应用_DHCP_03


STM32驱动W5500应用_TCP_04

3.W5500物联网平台连接

#include "stm32f10x.h"
#include "usart.h"
#include "timer.h"
#include "aliyun_mqtt.h"

/*w5500相关头文件*/
#include "w5500api.h"
#include "dhcp.h"
#include "dns.h"
#define SERVER_IP "LA57WTHWL6.iotcloud.tencentdevices.com"//服务器IP
#define SERVER_PORT 1883 //端口号
//客户端ID:{产品ID}{设备名}
#define ClientID "LA57WTHWL6Smart_home"
//用户名和密码可使用密码生成工具完成
#define Username "LA57WTHWL2Smart_home;120310126;HK8V9;1635948714"
#define Password "2a915cae4489b591ce556e71f4e9f1ka21c354a37d12fee7c46f56abee1f048a;hmacsha256"//密文 

//订阅题:$thing/down/property/{ProductID}/{DeviceName} ---{ProductID}产品ID,{DeviceName}设备名
#define SET_TOPIC  "$thing/down/property/Lb57WTHWL3/Smart_home"//订阅
//发布主题:$thing/up/property/{ProductID}/{DeviceName}
#define POST_TOPIC "$thing/up/property/Lb57WTHWL3/Smart_home"//发布

char mqtt_message[200];//上报数据缓存区
u8 rx_buff[200];
void init_Net(void)
{
	u8 try_times=0;
	init_W5500();/*W5500初始化*/
	init_dhcp_client();//动态分配IP
	while(check_DHCP_state(SOCK_DHCP)!=DHCP_RET_UPDATE)
  {
			try_times++;
			if(try_times==255)//超时 重启芯片
      {							
				Reset_W5500();
				init_dhcp_client();
				try_times=0;
			}
			delay_ms(10);
		}
    while(!set_Network());
  /*判断数据是否写入成功*/
  u8 ipaddr[4];//ip地址
  u8 subnet[4];//子网掩码
  u8 gateway[4];//网关
	getSIPR (ipaddr);			
	printf(" W5500 IP地址   : %d.%d.%d.%d\r\n", ipaddr[0],ipaddr[1],ipaddr[2],ipaddr[3]);
	getSUBR(subnet);
	printf(" W5500 子网掩码 : %d.%d.%d.%d\r\n", subnet[0],subnet[1],subnet[2],subnet[3]);
	getGAR(gateway);
	printf(" W5500 网关     : %d.%d.%d.%d\r\n", gateway[0],gateway[1],gateway[2],gateway[3]);  
}
/*连接服务器*/
uint8 TCP_Connect(SOCKET Socket,uint8 *sip,uint16 sport,uint16 lport)
{
  static uint8 CONNECT_FLAG = 0;
  switch(getSn_SR(Socket))
  {
    case SOCK_INIT:
			 CONNECT_FLAG=connect(Socket,sip,sport);/*连接服务器*/
       break;
    case SOCK_CLOSE_WAIT:
      disconnect(Socket);
      close(Socket);
      break;
    case SOCK_CLOSED:
			 CONNECT_FLAG=0;
			 socket(Socket,Sn_MR_TCP,lport,Sn_MR_ND);
			 break;
  }
  return CONNECT_FLAG;
}
int main()
{
  u16 i=0;
  u8 stat=0;
  u16 time=0,cnt=0;
  float temp=10;
  u16 rlen;
  USART1_Init(115200);
  printf("W5500 SPI模拟时序寄存器版,连接腾讯云VER1.0 \r\n");
  init_Net();/*W5500硬件初始化,动态分配IP*/
  printf("W5500 硬件初始化成功\r\n");
  while(!do_dns((u8 *)SERVER_IP)){}/*域名解析*/
  while(1)
  {
    stat=TCP_Connect(MQTT_SOCK,NET_CONFIG.rip,1883,5500);/*连接服务器*/
    printf("stat=%d\r\n",stat);
    if(stat)break;
    delay_ms(1000);
  } 
  printf("腾讯物联网平台连接中....\n");
  while(1)
  {
    if(getSn_SR(MQTT_SOCK)==SOCK_ESTABLISHED)
    {
       if(getSn_IR(MQTT_SOCK)&Sn_IR_CON)
       {
         setSn_IR(MQTT_SOCK,Sn_IR_CON);
       }
       MQTT_Init();
       if(MQTT_Connect(ClientID,Username,Password)==0)
       {
          printf("腾讯云平台连接成功\r\n");
         break;
       }
    }
  }
  stat=MQTT_SubscribeTopic(SET_TOPIC,0,1);
  if(stat)printf("订阅失败\r\n"); 
  while(1)
  {
    /*接收数据*/
    rlen=getSn_RX_RSR(MQTT_SOCK);
    if(rlen>0)
    {
      rlen=recv(MQTT_SOCK,rx_buff,rlen);
      printf("len=%d\r\n",rlen);
      for(i=0;i<rlen;i++)
      {
        printf("%c",rx_buff[i]);
      }
    }
    delay_ms(1);
    time++;
    cnt++;
    if(time>=5000)
    {
      time=0;
      MQTT_SentHeart();//发送心跳包
    }
    if(cnt>=2000)
    {
      temp+=1.5;
      if(temp>=85)temp=-15;
      cnt=0;
      sprintf(mqtt_message,"{\"method\":\"report\",\"clientToken\":\"123\",\"params\":{\"LED1\":1,\"temp\":%.2f,\"L\":356}}",temp);//温度
      MQTT_PublishData(POST_TOPIC,mqtt_message,0);
    }    
  }
}

STM32驱动W5500应用_TCP_05

STM32驱动W5500应用_物联网平台_06

STM32驱动W5500应用_DHCP_07

标签:ConfigMsg,W5500,IP,.%,STM32,printf,驱动,gateway
From: https://blog.51cto.com/u_15688123/6146648

相关文章

  • SpringCloudStream消息驱动的使用以及解决消息重复消费
    场景SpringCloudConfig集成Bus消息总线实现动态刷新配置(全局广播和定点通知):SpringCloudConfig集成Bus消息总线实现动态刷新配置(全局广播和定点通知)_霸道流氓气质的博客-......
  • ubuntu安装显卡驱动(一般)
    步骤一、查看显卡驱动(看一下系统推荐的版本号)  步骤二、设置下载源(要联网) 步骤三、查看附加驱动(根据步骤一的系统推荐的版本号选择一个) 步骤四、测试(没安装......
  • 显卡驱动+cuda+cudnn+深度学习框架
    安装概览安装显卡驱动、CUDA和cuDNN可能因操作系统和GPU型号而异,下面是一般的步骤:下载和安装适合你GPU型号的显卡驱动,可以从官方网站或者GPU制造商的网站下载......
  • 热敏打印机-步进电机驱动
    满步驱动:就是一次走一个步距,这是一种常用的驱动方式。根据通电相数,满步驱动又分成两种,一种是单相通电驱动,一种是双相通电驱动。2-2相驱动方式走4个相位马达才会转动一圈......
  • 【STM32】库函数开发项目模板
    1.下载固件库官方网址:https://www.st.com工具与软件->嵌入式软件->安全微控制器软件->微控制器软件->STM32微控制器软件->STM32标准外设软件库直达链接:https......
  • Linux 2.4G USB遥控板驱动
    #include<linux/kernel.h>#include<linux/slab.h>#include<linux/module.h>#include<linux/init.h>#include<linux/usb/input.h>#include<linux/hid.h>#include<lin......
  • springcloud Stream整合rabbitmq消息驱动生产者踩坑
    消息驱动之生产者8801(踩坑记录)1.首先说一下情况,我是跟着尚硅谷周阳老师的springcloud2020教程学习的,前面也踩了不少坑,但是这个坑,是我找的比较久的坑了,所以希望大家能直......
  • 领域驱动设计DDD应用与最佳实践
    领域驱动设计(DomainDrivenDesign,简称:DDD)设计思想和方法论早在2005年时候就被提出来,但是一直没有重视和推荐使用,直到2015年之后微服务流行之后,再次被人重视和推荐使用。......
  • #创作者激励# [FFH]标准系统HDF平台驱动(一)——ADC驱动适配
    【本文正在参加2023年第一期优质创作者激励计划】标准系统HDF平台驱动(一)——ADC驱动适配个人简介:深圳技术大学FSR实验室大三学生,正于九联科技实习,共同学习研究鸿蒙南向......
  • Qt+MySql开发笔记:Qt5.9.3的mingw32版本编译MySql8版本驱动并Demo连接数据库测试
    前言  之前特定的mysql版本msvc版本已经调通了,但是为了更好的跨平台,所以选择用mingw32版本,于是需要编译mysql驱动的mingw32版本的驱动库,以便提供给qt连接mysql使用。<br......