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)
{
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;
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;
}
u8 LWIP_CreateTcpClient(ip_addr_t *addr,u16 port)
{
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"
#define SERVER_PORT 1883
#define ClientID "LA57WTHWL6Smart_home"
#define Username "LA57WTHWL6Smart_home;12010126;E4C8Z;1646652494"
#define Password "1ad14baba7986f44444c950d5ee2f1c8a3da601c8471aa284687a64e4809cb3e;hmacsha256"
#define SET_TOPIC "$thing/down/property/LA57WTHWL6/Smart_home"
#define POST_TOPIC "$thing/up/property/LA57WTHWL6/Smart_home"
char mqtt_message[200];
ip_addr_t server_addr;
void dns_callback(const char *name, ip_addr_t *ipaddr, void *callback_arg)
{
server_addr.addr=ipaddr->addr;
}
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:
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!");
}
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();
TIMx_Init(TIM6,72,1000);
TIM6->CR1|=1<<0;
while(!lwip_dhcp_stat);
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<dm9000_rx_len;i++)
{
printf("%c",dm9000_rx_buff[i]);
}
dm9000_rx_len=0;
}
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\":{\"temp\":%.2f,\"humi\":60}}",temp);
MQTT_PublishData(POST_TOPIC,mqtt_message,0);
}
if(!client_connect_stat)
{
goto AA;
}
}
}
运行效果: 参考示例:https://download.csdn.net/download/weixin_44453694/82868942
|