单片机
返回首页

STM32F103ZE开发板 LWIP网络协议栈应用之连接腾讯云

2024-06-11 来源:elecfans

1.LWIP介绍

lwip是瑞典计算机科学院网络嵌入式系统小组(SICS)的Adam Dunkels(亚当·邓克尔) 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持 TCP 协议主要功能的基础上减少对RAM的占用。

LwIP是Light Weight(轻型)IP 协议,有无操作系统的支持都可以运行。LwIP 实现的重点是在保持TCP协议 主要功能的基础上减少对RAM的占用,它只需十几KB的RAM和 40K左右的ROM就可以运行,这使LwIP协议栈适合在低端的嵌入式系统中使用。


2.连接腾讯物联网平台

硬件平台:STM32F103ZE开发板、DM9000有线网卡、LCD屏

开发环境:KEIL5

网卡工作模式:TCP客户端模式

物联网平台通讯协议:MQTT

创建TCP客户端,接收服务器下发数据



#include "lwip_config.h"

#include "lwip/tcp.h"

/*接收成功回调函数*/

u8 dm9000_rx_buff[1024];

u16 dm9000_rx_len=0;

err_t tcp_recv_func(void *arg, struct tcp_pcb *tpcb,struct pbuf *p, err_t err)

{

memset(dm9000_rx_buff,0,sizeof(dm9000_rx_buff));

dm9000_rx_len=0;

u16 len=0;

if(p==NULL)

{

printf("服务器断开连接rn");

client_connect_stat=0;

}

else

{

if(p->tot_len==p->len)//p->tot_len整包数据长度,p->len当前节点数据长度

{

memcpy(dm9000_rx_buff,p->payload,p->len);

len=p->len;

}

else

{

struct pbuf *temp=p;

len=0;

while(temp!=NULL)

{

memcpy(dm9000_rx_buff+len,temp->payload,temp->len);

len+=temp->len;

temp=temp->next;

}

}

pbuf_free(p);//该释放函数只需填链表头进来即可

dm9000_rx_len=len;

}

return ERR_OK;

}


struct tcp_pcb *new_tcp;//tcp网络信息(套接字)

u8 client_addr[4];

u8 client_connect_stat=0;

/*连接服务器成功回调函数*/

err_t tcp_connect_func(void *arg, struct tcp_pcb *tpcb, err_t err)

{

client_addr[0]=tpcb->local_ip.addr>>0;

client_addr[1]=tpcb->local_ip.addr>>8;

client_addr[2]=tpcb->local_ip.addr>>16;

client_addr[3]=tpcb->local_ip.addr>>24;

new_tcp=tpcb;

client_connect_stat=1;

printf("%d.%d.%d.%d连接服务器成功rn",client_addr[0],client_addr[1],client_addr[2],client_addr[3]);

tcp_recv(tpcb,tcp_recv_func);

return 0;

}

/**********TCP客户端创建*****************

**

**形参:  addr IP地址

** u16_t port -- 服务器端口号

**返回值:0 --服务器创建成功,其他值--失败

**

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

u8 LWIP_CreateTcpClient(ip_addr_t *addr,u16 port)

{

/*1.创建新的网卡设备*/

new_tcp=tcp_new();

if(new_tcp==NULL)return 1;

/*连接服务器*/

tcp_connect(new_tcp,addr,port,tcp_connect_func);

return 0;

}

3.主函数

   在main.c中主要实现DM9000网卡初始化,LWIP网络协议栈初始化、动态分配IP、DNS域名解析、连接腾讯云登录物联网平台实现数据交互。


#include "lwip_config.h"

#include "aliyun_mqtt.h"

#define SERVER_IP "LA57WTHWL6.iotcloud.tencentdevices.com"//服务器IP

#define SERVER_PORT 1883 //端口号

//客户端ID:{产品ID}{设备名}

#define ClientID "LA57WTHWL6Smart_home"

//用户名和密码可使用密码生成工具完成

#define Username "LA57WTHWL6Smart_home;12010126;E4C8Z;1646652494"

#define Password "1ad14baba7986f44444c950d5ee2f1c8a3da601c8471aa284687a64e4809cb3e;hmacsha256"//密文 


//订阅题:$thing/down/property/{ProductID}/{DeviceName} ---{ProductID}产品ID,{DeviceName}设备名

#define SET_TOPIC  "$thing/down/property/LA57WTHWL6/Smart_home"//订阅

//发布主题:$thing/up/property/{ProductID}/{DeviceName}

#define POST_TOPIC "$thing/up/property/LA57WTHWL6/Smart_home"//发布

char mqtt_message[200];//上报数据缓存区

ip_addr_t server_addr;

/*DNS域名解析成功回调函数*/

void dns_callback(const char *name, ip_addr_t *ipaddr, void *callback_arg)

{

server_addr.addr=ipaddr->addr;/*IP地址*/

}

int main()

{

char buff[200];

u8 stat;

u16 time=0,i=0,cnt=0;

float temp=10;

Beep_Init();

Led_Init();

Key_Init();

W25Q64_Init();

Usartx_Init(USART1,115200,72);

TIMx_Init(TIM2,72,20*1000);

IIC_Init();

printf("DM9000连接腾讯云VER1.0rn");

NT35310_Init();

LCD_ShowStr(75,5,16,"DM9000连接腾讯云VER1.0");//显示字符串

AA:

/*DM9000初始化*/

LCD_ShowStr(30,30,16,"DM9000初始化中。。。");//显示字符串

if(DM9000_Init()==0)

{

printf("DM9000初始化成功rn");

LCD_ShowStr(30,30+20,16,"DM9000t OK!");//显示字符串

}

else 

{

printf("DM9000初始化失败rn");

LCD_ShowStr(30,30+20,16,"DM9000t ERR!");//显示字符串

}

/*获取DM9000工作模式*/

LCD_ShowStr(128,30+20*2,16,"网卡信息");//显示字符串

stat=DM9000_Get_SpeedAndDuplex();//获取连接状态和工作方式

if(stat!=0xff)

{

printf("网卡速度:%d Mbps 模式:%srn",(stat&0x02)?10:100,(stat&0x01)?"全双工":"半双工");

snprintf(buff,sizeof(buff),"网卡速度:%d MHZt %s",(stat&0x02)?10:100,(stat&0x01)?"全双工":"半双工");

LCD_ShowStr(30,30+20*3,16,(u8 *)buff);//网卡速度

}

else 

{

printf("DM9000网卡状态信息获取失败!rn");

LCD_ShowStr(30,30+20*3,16,(u8 *)"获取网卡信息失败!");//网卡速度

}

LWIP_Config_Init();//LWIP协议栈初始化

TIMx_Init(TIM6,72,1000);

TIM6->CR1|=1<<0;

while(!lwip_dhcp_stat);/*等待IP地址分配成功*/

LCD_ShowStr(112,30+20*7,16,"连接云服务器");//显示字符串

/*域名解析*/

while(1)

{

stat=dns_gethostbyname(SERVER_IP,&server_addr,dns_callback,NULL);

if(stat==0)break;

Delay_Ms(1000);

}

/*连接服务器*/

stat=1;

time=300;

while(!client_connect_stat)

{

if(time>=300)

{

stat=1;

}

if(stat && time>=300)

{

time=0;

stat=LWIP_CreateTcpClient(&server_addr,1883);

}

time++;

Delay_Ms(10);

}

LCD_ShowStr(30,30+20*8,16,(u8 *)"服务器连接成功");

while(1)

{

MQTT_Init();

if(MQTT_Connect(ClientID,Username,Password)==0)

{

printf("腾讯云平台连接成功rn");

break;

}

}

LCD_ShowStr(30,30+20*9,16,(u8 *)"腾讯云连接成功");

  stat=MQTT_SubscribeTopic(SET_TOPIC,0,1);

  if(stat)printf("订阅失败rn"); 

else

{

LCD_ShowStr(30,30+20*10,16,(u8 *)"消息订阅成功");

}

time=0;

while(1)

{

if(dm9000_rx_len>0)

{

printf("len=%drn",dm9000_rx_len);

for(i=0;i=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":{"temp":%.2f,"humi":60}}",temp);//温度

      MQTT_PublishData(POST_TOPIC,mqtt_message,0);

    } 

if(!client_connect_stat)//服务器断开连接

{

goto AA;

}

}

}

运行效果:

pYYBAGKWt8OADQBbAA0lS-01nhQ250.pngpoYBAGKWt9iAbp3hAAD5lNZzvOY179.pngpYYBAGKWt_OANr6VAAGxNqgJr1c408.png


进入单片机查看更多内容>>
相关视频
  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 新唐 8051单片机教程

精选电路图
  • 低成本有源FM放大器电路

  • 如何从标准USB插座构建双+5V/-5V电源

  • 液位报警指示器电路

  • 一个简单的太阳能电池充电器电路

  • 继电器的电气符号、功能、类型、技术参数

  • 一文详解全波整流的过程

    相关电子头条文章