0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

嵌入式技术 来源:嵌入式技术 作者:嵌入式技术 2022-06-02 08:51 次阅读

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("服务器断开连接\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,"连接云服务器");//显示字符串
	/*域名解析*/
	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("腾讯云平台连接成功\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;
		}
	}
}

运行效果:

pYYBAGKWt8OADQBbAA0lS-01nhQ250.pngpoYBAGKWt9iAbp3hAAD5lNZzvOY179.pngpYYBAGKWt_OANr6VAAGxNqgJr1c408.png

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 物联网
    +关注

    关注

    2867

    文章

    41600

    浏览量

    358306
  • STM32
    +关注

    关注

    2239

    文章

    10671

    浏览量

    348720
  • LwIP
    +关注

    关注

    1

    文章

    82

    浏览量

    26620
  • STM32F103ZE
    +关注

    关注

    2

    文章

    14

    浏览量

    10797
  • 腾讯云
    +关注

    关注

    0

    文章

    190

    浏览量

    16616
收藏 人收藏

    评论

    相关推荐

    STM32应用案例 基于STM32F103ZE开发的数码相册

    1.硬件平台 CPU:STM32F103ZE 屏幕:3.5寸TFTLCD屏 触控:电阻式触摸屏xpt2046 SD卡、外扩Sram
    的头像 发表于 06-02 09:09 6350次阅读
    <b class='flag-5'>STM32</b>应用案例 基于<b class='flag-5'>STM32F103ZE</b><b class='flag-5'>开发</b>的数码相册

    收购2手STM32F103ZE开发板

    朋友们新年好啊!    大家谁有闲置的STM32F103ZE开发板没有,如果有的话可以转让给兄弟吗/谢谢啊 &
    发表于 02-19 12:06

    STM32F103ZE最小系统版

    1.单片机:STM32F103ZE最小系统版6.0✔N1RVcKX0SpK₴回????/宝或點***击***链节至瑬览器【STM32F103ZET6小系统 STM32
    发表于 08-06 07:51

    基于nano的工程芯片选择STM32F103ZE

    在RT-THREAD 新建基于nano的工程芯片选择STM32F103ZE,开发板晶振8Mdrv_clk.c HSI时钟源码/* * Copyright (c) 2006-2019
    发表于 08-12 08:07

    STM32F103ZE的一款开发板上成功移植uCOSIII

    STM32F103ZE的一款开发板上成功移植uCOSIII,并建立简单的LED测试工程使用Keil uVision4软件,3.5固件库及v3.02.00版本的uCOSIII
    发表于 08-23 08:28

    怎样将uTenux移植到STM32F103ZE开发板上去呢

    uTenux是什么?怎样将uTenux移植到STM32F103ZE开发板上去呢?
    发表于 11-02 06:42

    基于stm32F103ZE单片机的USART串口怎么使用?

    基于stm32F103ZE单片机的USART串口怎么使用?
    发表于 12-10 06:57

    STM32F103ZE最小系统的主函数的流程是怎样的

    stm32最小系统要怎么得到感知层采集到的数据呢?STM32F103ZE最小系统的主函数的流程是怎样的?
    发表于 12-10 07:45

    STM32F103ze简介

    一、STM32F103ze 简介本文中,采用的 MCU 具体型号为 STM32F103ZET6,其拥有丰富的外设资源(USB,IIC,USART,TIMER)等,大容量的RAM和ROM,以及上百
    发表于 02-11 06:04

    STM32F103ZE最小系统原理图

    STM32F103ZE最小系统原理图
    发表于 09-20 11:07 196次下载
    <b class='flag-5'>STM32F103ZE</b>最小系统原理图

    基于stm32f103ze的四轴飞控代码

    基于stm32f103ze的四轴飞控代码
    发表于 01-13 10:21 30次下载

    新版STM32F103ZE核心板原理图免费下载

    本文档的主要内容详细介绍的是新版STM32F103ZE核心板原理图免费下载。
    发表于 02-26 11:46 0次下载
    新版<b class='flag-5'>STM32F103ZE</b>核心板原理图免费下载

    新版STM32F103ZE核心板原理图

    新版STM32F103ZE核心板原理图免费下载。
    发表于 06-18 11:14 0次下载

    STM32F103ZE构建固件库模板

    STM32F103ZE构建固件库模板
    发表于 12-08 18:51 13次下载
    <b class='flag-5'>STM32F103ZE</b>构建固件库模板

    STM32F103ZE最小系统板

    STM32F103ZE最小系统板,可能带有一些不足
    发表于 03-30 18:18 0次下载