1.LWIP介紹
lwip是瑞典計算機科學(xué)院網(wǎng)絡(luò)嵌入式系統(tǒng)小組(SICS)的Adam Dunkels(亞當(dāng)·鄧克爾) 開發(fā)的一個小型開源的TCP/IP協(xié)議棧。實現(xiàn)的重點是在保持 TCP 協(xié)議主要功能的基礎(chǔ)上減少對RAM的占用。
LwIP是Light Weight(輕型)IP 協(xié)議,有無操作系統(tǒng)的支持都可以運行。LwIP 實現(xiàn)的重點是在保持TCP協(xié)議 主要功能的基礎(chǔ)上減少對RAM的占用,它只需十幾KB的RAM和 40K左右的ROM就可以運行,這使LwIP協(xié)議棧適合在低端的嵌入式系統(tǒng)中使用。
2.連接騰訊物聯(lián)網(wǎng)平臺
- 硬件平臺:STM32F103ZE開發(fā)板、DM9000有線網(wǎng)卡、LCD屏
- 開發(fā)環(huán)境:KEIL5
- 網(wǎng)卡工作模式:TCP客戶端模式
- 物聯(lián)網(wǎng)平臺通訊協(xié)議:MQTT
創(chuàng)建TCP客戶端,接收服務(wù)器下發(fā)數(shù)據(jù)
#include "lwip_config.h"
#include "lwip/tcp.h"
/*接收成功回調(diào)函數(shù)*/
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("服務(wù)器斷開連接\r\n");
client_connect_stat=0;
}
else
{
if(p->tot_len==p->len)//p->tot_len整包數(shù)據(jù)長度,p->len當(dāng)前節(jié)點數(shù)據(jù)長度
{
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);//該釋放函數(shù)只需填鏈表頭進來即可
dm9000_rx_len=len;
}
return ERR_OK;
}
struct tcp_pcb *new_tcp;//tcp網(wǎng)絡(luò)信息(套接字)
u8 client_addr[4];
u8 client_connect_stat=0;
/*連接服務(wù)器成功回調(diào)函數(shù)*/
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連接服務(wù)器成功\r\n",client_addr[0],client_addr[1],client_addr[2],client_addr[3]);
tcp_recv(tpcb,tcp_recv_func);
return 0;
}
/**********TCP客戶端創(chuàng)建*****************
**
**形參: addr IP地址
** u16_t port -- 服務(wù)器端口號
**返回值:0 --服務(wù)器創(chuàng)建成功,其他值--失敗
**
*****************************************/
u8 LWIP_CreateTcpClient(ip_addr_t *addr,u16 port)
{
/*1.創(chuàng)建新的網(wǎng)卡設(shè)備*/
new_tcp=tcp_new();
if(new_tcp==NULL)return 1;
/*連接服務(wù)器*/
tcp_connect(new_tcp,addr,port,tcp_connect_func);
return 0;
}
3.主函數(shù)
? ?在main.c中主要實現(xiàn)DM9000網(wǎng)卡初始化,LWIP網(wǎng)絡(luò)協(xié)議棧初始化、動態(tài)分配IP、DNS域名解析、連接騰訊云登錄物聯(lián)網(wǎng)平臺實現(xiàn)數(shù)據(jù)交互。
#include "lwip_config.h"
#include "aliyun_mqtt.h"
#define SERVER_IP "LA57WTHWL6.iotcloud.tencentdevices.com"http://服務(wù)器IP
#define SERVER_PORT 1883 //端口號
//客戶端ID:{產(chǎn)品ID}{設(shè)備名}
#define ClientID "LA57WTHWL6Smart_home"
//用戶名和密碼可使用密碼生成工具完成
#define Username "LA57WTHWL6Smart_home;12010126;E4C8Z;1646652494"
#define Password "1ad14baba7986f44444c950d5ee2f1c8a3da601c8471aa284687a64e4809cb3e;hmacsha256"http://密文
//訂閱題:$thing/down/property/{ProductID}/{DeviceName} ---{ProductID}產(chǎn)品ID,{DeviceName}設(shè)備名
#define SET_TOPIC "$thing/down/property/LA57WTHWL6/Smart_home"http://訂閱
//發(fā)布主題:$thing/up/property/{ProductID}/{DeviceName}
#define POST_TOPIC "$thing/up/property/LA57WTHWL6/Smart_home"http://發(fā)布
char mqtt_message[200];//上報數(shù)據(jù)緩存區(qū)
ip_addr_t server_addr;
/*DNS域名解析成功回調(diào)函數(shù)*/
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,"網(wǎng)卡信息");//顯示字符串
stat=DM9000_Get_SpeedAndDuplex();//獲取連接狀態(tài)和工作方式
if(stat!=0xff)
{
printf("網(wǎng)卡速度:%d Mbps 模式:%s\r\n",(stat&0x02)?10:100,(stat&0x01)?"全雙工":"半雙工");
snprintf(buff,sizeof(buff),"網(wǎng)卡速度:%d MHZ\t %s",(stat&0x02)?10:100,(stat&0x01)?"全雙工":"半雙工");
LCD_ShowStr(30,30+20*3,16,(u8 *)buff);//網(wǎng)卡速度
}
else
{
printf("DM9000網(wǎng)卡狀態(tài)信息獲取失敗!\r\n");
LCD_ShowStr(30,30+20*3,16,(u8 *)"獲取網(wǎng)卡信息失敗!");//網(wǎng)卡速度
}
LWIP_Config_Init();//LWIP協(xié)議棧初始化
TIMx_Init(TIM6,72,1000);
TIM6->CR1|=1<<0;
while(!lwip_dhcp_stat);/*等待IP地址分配成功*/
LCD_ShowStr(112,30+20*7,16,"連接云服務(wù)器");//顯示字符串
/*域名解析*/
while(1)
{
stat=dns_gethostbyname(SERVER_IP,&server_addr,dns_callback,NULL);
if(stat==0)break;
Delay_Ms(1000);
}
/*連接服務(wù)器*/
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 *)"服務(wù)器連接成功");
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();//發(fā)送心跳包
}
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)//服務(wù)器斷開連接
{
goto AA;
}
}
}
運行效果:
-
物聯(lián)網(wǎng)
+關(guān)注
關(guān)注
2904文章
44306瀏覽量
371459 -
STM32
+關(guān)注
關(guān)注
2266文章
10876瀏覽量
354925 -
LwIP
+關(guān)注
關(guān)注
2文章
86瀏覽量
27105 -
STM32F103ZE
+關(guān)注
關(guān)注
2文章
14瀏覽量
10870 -
騰訊云
+關(guān)注
關(guān)注
0文章
208瀏覽量
16770
發(fā)布評論請先 登錄
相關(guān)推薦
評論