完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
NRF24L01和节点通信
根据MQTT协议自己写的库,自动连接,可以发布消息,订阅,取消订阅,PingReq MQ MqttClient_SetDefaultReceivedCallBack(MQTTCLIENTRECVCALLBACK pFun) { ReceivedHandler=pFun; } void OnMessageReceived(u8* topic, u8* payload, u8 type)//回调函数 { if(ReceivedHandler) { ReceivedHandler(topic, payload, type); } } u16 GetMessageIdentifier() { if (MessageIdentifier == 0x7FFF) MessageIdentifier = 0x0000; MessageIdentifier++; return MessageIdentifier; } void MqttClient_Connect() { len=GetData_Connet(send_buff); MqttConnect_SendMessage(send_buff,len); } //主函数调用或定时器1s调用 void MqttClient_AutoReconnect() { static u32 reTimer=0; if(ConnectState==Disconnected) { if(Get_RunTime()-reTimer>500)//5s { MqttClient_Connect(); } } } void MqttClient_DisConnet(void) { len=GetData_DisConnet(send_buff); MqttConnect_SendMessage(send_buff,len); ConnectState = Disconnected; } void MqttClient_Publish(u8* topic,u8* data,u8 qos,u8 retain) { u16 num; if(qos>0) num=GetMessageIdentifier(); else num=0; len=GetData_PUBLISH(send_buff,0,qos,retain,topic,num,data); MqttConnect_SendMessage(send_buff,len); PingDateTime=Get_RunTime(); } void MqttClient_Subscribe(u8* topic,u8 qos) { len=GetData_SUBSCRIBE(send_buff,GetMessageIdentifier(),topic,qos); MqttConnect_SendMessage(send_buff,len); } void MqttClient_Unsubscribe(u8* topic) { len=GetData_UNSUBSCRIBE(send_buff,GetMessageIdentifier(),topic); MqttConnect_SendMessage(send_buff,len); } //定时器1s调用 void MqttClient_PingReq(void) { if(ConnectState==Connected&&Get_RunTime()-PingDateTime>6000) { len=GetData_PINGREQ(send_buff); MqttConnect_SendMessage(send_buff,len); PingDateTime=Get_RunTime(); } } void Puback(u16 identifier) { len=GetData_PUBACK(send_buff,identifier); MqttConnect_SendMessage(send_buff,len); } void Pubrec(u16 identifier) { len=GetData_PUBREC(send_buff,identifier); MqttConnect_SendMessage(send_buff,len); } void Pubrel(u16 identifier) { len=GetData_PUBREL(send_buff,identifier); MqttConnect_SendMessage(send_buff,len); } void Pubcomp(u16 identifier) { len=GetData_PUBCOMP(send_buff,identifier); MqttConnect_SendMessage(send_buff,len); } void MqttClient_DecodeMessage(u8* buffer)//解码消息 { u8 FixedHead_MessageType = ((buffer[0] & 0xf0) >> 4); u8 FixedHead_Dup = ((buffer[0] & 0x08) >> 3) > 0; u8 FixedHead_Qos = ((buffer[0] & 0x06) >> 1); u8 FixedHead_Retain = (buffer[0] & 0x01) > 0; u8 RemaingLength = buffer[1]; u8 ReturnCode; lenindex=2; PingDateTime = Get_RunTime(); switch (FixedHead_MessageType) { case MQTT_TypeCONNACK://正确连接返回20 02 00 00 if(RemaingLength==2) ReturnCode = buffer[3]; else ReturnCode = 0xFF; if (ReturnCode == BrokerUnavailable || ReturnCode == IdentifierRejected || ReturnCode == UnacceptedProtocolVersion || ReturnCode == NotAuthorized || ReturnCode == BadUsernameOrPassword) { ConnectState = Disconnecting; ConnectState = Disconnected; } else { ConnectState = Connected; OnMessageReceived("", "", MQTT_TypeCONNACK); } break; case MQTT_TypePUBLISH: if(RemaingLength>2) { topiclen=buffer[lenindex++]<<8; topiclen=buffer[lenindex++]; } MemSet(topic,0,sizeof(topic)); BlockCopy(buffer,lenindex,topic,0,topiclen); lenindex+=topiclen; if(FixedHead_Qos>0) { msgIdentifier=buffer[lenindex++]<<8; msgIdentifier=buffer[lenindex++]; } payloadLen=RemaingLength-lenindex-2; MemSet(payload,0,sizeof(payload)); BlockCopy(buffer,lenindex,payload,0,payloadLen); lenindex+=payloadLen; if (FixedHead_Qos == 0)//Level 0 最多分发一次 { OnMessageReceived(topic, payload, MQTT_TypePUBLISH); } else if (FixedHead_Qos == 1)//Level 1 至少分发一次 { Puback(msgIdentifier);//(QoS 1)(服务端发布) if(!FixedHead_Dup) { OnMessageReceived(topic, payload, MQTT_TypePUBLISH); } } else if (FixedHead_Qos == 2)//Level 2 只分发一次 { //PUBREC – 发布收到(QoS 2,第一步)(服务端发布) Pubrec(msgIdentifier); //AddPublishMsg(topic, payload, msgIdentifier); OnMessageReceived(topic, payload, MQTT_TypePUBLISH); } break; case MQTT_TypePUBACK: //发布完成(QoS 1)(客户端发布) OnMessageReceived("", "", MQTT_TypePUBACK); break; case MQTT_TypePUBREC: //PUBREC – 发布收到(QoS 2,第一步)(客户端发布) msgIdentifier=buffer[lenindex++]<<8; msgIdentifier=buffer[lenindex++]; //PUBREL – 发布释放(QoS 2,第二步)(客户端发布) Pubrel(msgIdentifier); break; case MQTT_TypePUBREL: //PUBREL – 发布释放(QoS 2,第二步)(服务端发布) msgIdentifier=buffer[lenindex++]<<8; msgIdentifier=buffer[lenindex++]; //PUBCOMP – 发布完成(QoS 2,第三步)(服务端发布) Pubcomp(msgIdentifier); //根据msgIdentifier从PublishMsg列表读topic,payload //OnMessageReceived(topic, payload, MQTT_TypePUBCOMP); //发布完成,删除消息 //RemovePublishMsg(msgIdentifier); break; case MQTT_TypePUBCOMP: //PUBCOMP – 发布完成(QoS 2,第三步)(客户端发布) msgIdentifier=buffer[lenindex++]<<8; msgIdentifier=buffer[lenindex++]; OnMessageReceived("", "", MQTT_TypePUBCOMP); break; case MQTT_TypeSUBACK: //订阅成功 OnMessageReceived("", "", MQTT_TypeSUBACK); break; case MQTT_TypeUNSUBACK: //取消订阅成功 OnMessageReceived("", "", MQTT_TypeUNSUBACK); break; case MQTT_TypeDISCONNECT: //OnMessageReceived("", "", MQTT_TypeDISCONNECT); ConnectState = Disconnecting; MqttConnect_CloseConnect(); ConnectState = Disconnected; break; } } //获取数据包 //固定头 unsigned char GetData_FixedHead(unsigned char MesType, unsigned char DupFlag, unsigned char QosLevel, unsigned char Retain) { unsigned char dat = 0; dat = (MesType & 0x0f) << 4; dat |= (DupFlag & 0x01) << 3; dat |= (QosLevel & 0x03) << 1; dat |= (Retain & 0x01); return dat; } //获取连接的数据包 //正确连接返回20 02 00 00 u16 GetData_Connet(unsigned char *buff,unsigned char *clientId,unsigned char *userName,unsigned char *password) { unsigned int i, len, lennum = 0; buff[lennum++] = GetData_FixedHead(MQTT_TypeCONNECT, 0, 0, 0); buff[lennum++] = 0x00;//最后计算长度 buff[lennum++] = 0x00; buff[lennum++] = 0x04; buff[lennum++] = 'M'; buff[lennum++] = 'Q'; buff[lennum++] = 'T'; buff[lennum++] = 'T'; buff[lennum++] = 0x04;//协议级别 Protocol Level buff[lennum++] = 0 | (MQTT_StaCleanSession << 1) | (MQTT_StaWillFlag << 2) | (MQTT_StaWillQoS << 3) | (MQTT_StaWillRetain << 5) | (MQTT_StaPasswordFlag << 6) | (MQTT_StaUserNameFlag << 7);//连接标志 buff[lennum++] = MQTT_KeepAlive >> 8; buff[lennum++] = MQTT_KeepAlive; len = strlen((char*)clientId); buff[lennum++] = len >> 8; buff[lennum++] = len; for (i = 0; i { buff[lennum++] = clientId; } if (MQTT_StaWillFlag) { len = strlen(MQTT_WillTopic); buff[lennum++] = len >> 8; buff[lennum++] = len; for (i = 0; i buff[lennum++] = MQTT_WillTopic; } len = strlen(MQTT_WillMessage); buff[lennum++] = len >> 8; buff[lennum++] = len; for (i = 0; i buff[lennum++] = MQTT_WillMessage; } } if (MQTT_StaUserNameFlag) { len = strlen((char*)userName); buff[lennum++] = len >> 8; buff[lennum++] = len; for (i = 0; i buff[lennum++] = userName; } } if (MQTT_StaPasswordFlag) { len = strlen((char*)password); buff[lennum++] = len >> 8; buff[lennum++] = len; for (i = 0; i buff[lennum++] = password; } } buff[1] = lennum - 2; return lennum; } //获取断开连接的数据包 u8 GetData_DisConnet(unsigned char *buff) { buff[0] = 0xe0; buff[1] = 0; return 2; } //心跳请求的数据包 //成功返回d0 00 u8 GetData_PINGREQ(unsigned char *buff) { buff[0] = 0xc0; buff[1] = 0; return 2; } |
|
|
|
//订阅主题的数据包 Num:主题序号 RequestedQoS:服务质量要求0,1或2
//返回90 0x 00 Num RequestedQoS 0x00-QoS0 0x01QoS1 0x02-QoS2 0x80-Failure失败 u16 GetData_SUBSCRIBE(unsigned char *buff, unsigned int Num, const char *Topic, unsigned char RequestedQoS) { unsigned int i, len = 0, lennum = 0; buff[lennum++] = 0x82; buff[lennum++] = 0x00;//最后计算长度 buff[lennum++] = Num >> 8;//消息标识符 buff[lennum++] = Num; len = strlen(Topic); buff[lennum++] = len >> 8; buff[lennum++] = len; for (i = 0; i buff[lennum++] = Topic; } buff[lennum++] = RequestedQoS; buff[1] = lennum - 2; return lennum; } //取消订阅主题的数据包 Num:主题序号 //成功返回B0 02 00 00 u16 GetData_UNSUBSCRIBE(unsigned char *buff, unsigned int Num, const char *Topic) { unsigned int i, len = 0, lennum = 0; buff[lennum++] = 0xA2; buff[lennum++] = 0x00;//最后计算长度 buff[lennum++] = Num >> 8;//消息标识符 buff[lennum++] = Num; len = strlen(Topic); buff[lennum++] = len >> 8; buff[lennum++] = len; for (i = 0; i buff[lennum++] = Topic; } buff[1] = lennum - 2; return lennum; } //获取发布消息的数据包 //返回 QoS0 无响应 //QoS1 PUBACK 40 02 00 00 //QoS2 PUBREC 50 02 00 00 PUBREC报文是对QoS等级2的PUBLISH报文的响应(QoS2,第1步) u16 GetData_PUBLISH(unsigned char *buff, unsigned char dup, unsigned char qos, unsigned char retain, const char *topic, unsigned int identifier,const char *msg) { unsigned int i, len = 0, lennum = 0; buff[lennum++] = GetData_FixedHead(MQTT_TypePUBLISH, dup, qos, retain); buff[lennum++] = 0x00;//最后计算长度 len = strlen(topic); buff[lennum++] = len >> 8; buff[lennum++] = len; for (i = 0; i buff[lennum++] = topic; } if (qos > 0) { buff[lennum++] = identifier >> 8;//只有当QoS等级是1或2时,报文标识符(Packet Identifier)字段才能出现在PUBLISH报文中。 buff[lennum++] = identifier; } len = strlen(msg); for (i = 0; i buff[lennum++] = msg; } buff[1] = lennum - 2; return lennum; } u8 GetData_PUBACK(unsigned char *buff, unsigned int identifier) { buff[0] = 0x40; buff[1] = 0x02; buff[2] = identifier >> 8;; buff[3] = 0x00; return 4; } u8 GetData_PUBREC(unsigned char *buff, unsigned int identifier) { buff[0] = 0x50; buff[1] = 0x02; buff[2] = identifier >> 8; buff[3] = identifier; return 4; } //获取发布释放(QoS2,第2步)的数据包 //PUBREL报文是对PUBREC报文的响应 //返回70 02 00 00 PUBCOMP报文是对PUBREL报文的响应(QoS2,第3步) u8 GetData_PUBREL(unsigned char *buff, unsigned int identifier) { buff[0] = 0x62; buff[1] = 0x02; buff[2] = identifier >> 8; buff[3] = identifier; return 4; } u8 GetData_PUBCOMP(unsigned char *buff, unsigned int identifier) { buff[0] = 0x70; buff[1] = 0x02; buff[2] = identifier >> 8; buff[3] = identifier; return 4; } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1659 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1571 浏览 1 评论
998 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
695 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1617 浏览 2 评论
1877浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
663浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
529浏览 3评论
548浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
517浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-29 19:48 , Processed in 0.985705 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号