STM32|STM32之LWIP网络协议栈连接腾讯云

STM32之LWIP网络协议栈连接腾讯云 1.LWIP介绍

??lwip是瑞典计算机科学院网络嵌入式系统小组(SICS)的Adam Dunkels(亚当·邓克尔) 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持 TCP 协议主要功能的基础上减少对RAM的占用。
??LwIP是Light Weight(轻型)IP 协议,有无操作系统的支持都可以运行。LwIP 实现的重点是在保持TCP协议 主要功能的基础上减少对RAM的占用,它只需十几KB的RAM和 40K左右的ROM就可以运行,这使LwIP协议栈适合在低端的嵌入式系统中使用。
STM32移植LWIP协议栈示例:https://blog.csdn.net/weixin_44453694/article/details/123119624
STM32连接腾讯云示例:https://blog.csdn.net/weixin_44453694/article/details/116802776
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("服务器断开连接\r\n"); 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连接服务器成功\r\n",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.0\r\n"); NT35310_Init(); LCD_ShowStr(75,5,16,"DM9000连接腾讯云VER1.0"); //显示字符串 AA: /*DM9000初始化*/ LCD_ShowStr(30,30,16,"DM9000初始化中。。。"); //显示字符串 if(DM9000_Init()==0) { printf("DM9000初始化成功\r\n"); LCD_ShowStr(30,30+20,16,"DM9000\t OK!"); //显示字符串 } else { printf("DM9000初始化失败\r\n"); LCD_ShowStr(30,30+20,16,"DM9000\t ERR!"); //显示字符串 } /*获取DM9000工作模式*/ LCD_ShowStr(128,30+20*2,16,"网卡信息"); //显示字符串 stat=DM9000_Get_SpeedAndDuplex(); //获取连接状态和工作方式 if(stat!=0xff) { printf("网卡速度:%d Mbps 模式:%s\r\n",(stat&0x02)?10:100,(stat&0x01)?"全双工":"半双工"); snprintf(buff,sizeof(buff),"网卡速度:%d MHZ\t %s",(stat&0x02)?10:100,(stat&0x01)?"全双工":"半双工"); LCD_ShowStr(30,30+20*3,16,(u8 *)buff); //网卡速度 } else { printf("DM9000网卡状态信息获取失败!\r\n"); 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,"连接云服务器"); //显示字符串 /*域名解析*/ stat=dns_gethostbyname(SERVER_IP,&server_addr,dns_callback,NULL); /*连接服务器*/ 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("腾讯云平台连接成功\r\n"); break; } } LCD_ShowStr(30,30+20*9,16,(u8 *)"腾讯云连接成功"); stat=MQTT_SubscribeTopic(SET_TOPIC,0,1); if(stat)printf("订阅失败\r\n"); else { LCD_ShowStr(30,30+20*10,16,(u8 *)"消息订阅成功"); } time=0; while(1) { if(dm9000_rx_len>0) { printf("len=%d\r\n",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; } } }

【STM32|STM32之LWIP网络协议栈连接腾讯云】运行效果:
STM32|STM32之LWIP网络协议栈连接腾讯云
文章图片

STM32|STM32之LWIP网络协议栈连接腾讯云
文章图片

STM32|STM32之LWIP网络协议栈连接腾讯云
文章图片

参考示例:https://download.csdn.net/download/weixin_44453694/82868942

    推荐阅读