你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32+ESP8266通过AT指令WIFI连接阿里云MQTT服务器

[复制链接]
STMCU小助手 发布时间:2022-3-16 11:31
    上一篇使用USB转串口的方式通过ESP8266wifi模块的方式成功连接上了阿里云,现在就要通过单片机来替换电脑上位机了,这样单片机自动的去调用并发送串口数据更加方便,也更加符合一个产品的开发。板载的传感器有NTC温度,光强,这两个主要用来设备上传到平台,另外一个是RGB的灯,这个主要是用来平台下发设备的接收和解析。这里为了直观我直接用串口打印出来。只要数据部分对了其他的都好说。% Z* E5 L1 y& s4 \3 Z$ T
`RAB`OEW$ABE`2QAOX431DT.png ( I8 c4 Q1 u) l9 c
9 J) M- W8 o* l, \7 [  V' c
网页上的运行状态图
' g7 b/ w' R: K9 c
8 M: @9 h! p& i5 j: u8 _5 ]; Z DMQQN_}6SP)ZI550}S8J7MN.png + n3 j0 H7 M- a. B7 S6 P, `
3 L* v% E, r% O' L+ X/ @; O
温度曲线图
8 ~; c. w7 ]% ~' [( c) B8 [4 j- i
2 S- u; `! H! R% r, U) [ 7QY221`1MJ8SF)VY)1{SQ[E.png
) q6 _7 V8 P( r% R0 ^3 y4 r9 i
9 F0 f8 U7 O; B& J光强曲线图) p2 W0 H) Q( _6 Y  n/ q) J) A
+ f  m! n9 b6 B4 H1 i! Z; h: L0 m
UAPMBBGIE%@7RX$B1APCSOR.png
+ ?5 e( p( U5 W. k) x- S+ x# ~5 }# H, S; O) N& B2 e9 L# f) [: v6 s
颜色色值曲线图,这里其实是通过单片机随机函数生成的一个数据,所以变化也是比较大的,为了直观我也把这个值上传到平台。
5 p9 @/ ~+ N( g; n: v1 ~8 N  ?2 v0 ^  e( [, G/ t
@`W1AZU{@]5LM)3@9LN$FYA.png 9 e' }. E1 d- U* t+ f  F

9 }$ x( v/ d. W" }6 V0 [7 _4 w! l平台下发数据、设备解析测试。0 R( ~4 P/ i, O0 k8 J/ s- V

5 [8 t: `" R4 x! ^' x5 Q  I这里要注意一下,最开始我通过strstr方法来找出关键字“hue”,但是测了下不行,后来找到原因,估计是平台下发的josn数据包中含有多个0,比方说设备收到的是“123456\0789”,这里的‘\0’其实hex就是0x00,也正好是字符串的结尾标识符,这样通过strstr要找出“789”就找不到的,因为再者之前字符串就认为已经是断了,后来自己写了一个查找函数,解决!
4 C2 e8 `6 r/ p. P( ^2 }
+ I, _# i$ @$ ]2 V( F1 U网络部分和MQTT部分我都做了封装,非常方便参考和移植,不多说直接贴上代码:! j9 g& t& E, M$ @3 U! d8 V/ G

* n/ Z$ p; s: S* r/ M# J" Dmain.c部分
" c% a, j  B6 e; C1 g1 ]+ _5 }% A, u- P
  1. #include "fy_includes.h"
    , \! G( k, J% p+ {' C
  2. #include "fy_tlink.h"
    2 X7 g/ k1 E/ S4 W% F+ X& V
  3. /*1 o! H- I; H/ I" X
  4. 晶振使用的是16M 其他频率在system_stm32f10x.c中修改
    - b; T3 P5 ~8 l& h7 }
  5. 使用printf需要在fy_includes.h修改串口重定向为#define PRINTF_USART USART1
    1 G; @. \% [5 w; k3 @# T
  6. */
    & s; q  l$ p1 o; ?3 K
  7. $ S0 q9 \7 [* P2 U$ R$ R9 T6 o: ?
  8. _typdef_adc _adc;
      m' d# `: d# {8 L2 t+ v4 h8 c# b8 _& ~
  9. u16 adc_light;, e* J. G7 o7 L
  10. u16 adc_ntc;$ @4 L4 y5 q1 s8 v) W5 S6 N
  11. u16 battery;
    4 d0 p. K' s8 B; V" @* l
  12. float temperature;
    7 \9 U: X9 N+ z
  13. u8 led_sta;, `( h+ W( a$ r, L
  14. u8 sta;0 e9 p! h0 y* q( i
  15. void Adc_GetValue(void);) n7 Z* ]: V! n

  16. 5 v( `3 s: x& I2 X  @1 [: a) f
  17. u8 txbuf[256];
    . A0 r4 m7 V  m! Y, R0 B* m& i3 c
  18. u8 rxbuf[256];, B5 D. M, c; ]
  19. 7 j8 D& ^% n( D( h, `6 s, I- U. z
  20. char mqtt_message[200];* X* Q. ^, L+ _' _& |
  21. # r: d* ]7 k2 ?
  22. ' I8 j1 x$ i" q4 Z' H- s
  23. void Mqtt_Progress(u8 *buf,u16 len);
    % |4 |0 Z; Z. B' Z% |4 I7 ?$ e- O

  24. 6 V6 p) i6 |9 b. g. ~; \
  25. void UsartTrance(void)
    " \8 l5 L; D3 V' f4 ?1 K) y
  26. {  q8 q0 n# `: n% @* |
  27.         while(1)
    , ?8 D, H3 ]9 q1 S$ B, h( O( c
  28.         {
    ) w+ V, \% D# h4 l# ~! g
  29.                 Led_Tog();! m) J. ^3 y9 i2 j+ k* f
  30.                 Delay_ms(500);
    3 I+ M/ l* _6 W9 @* i
  31.         }
    8 x: q) C2 X; Q& Z
  32. }
    5 J& _" U- o3 S7 ^) c0 x4 U7 y1 L
  33.   X2 g# u* D, t+ U% s
  34. int main(void)$ E$ v+ j0 _  g# \; r' @$ N- B$ H) L
  35. {" u2 `. g4 I3 Y
  36.         u8 cnt_2s=0;, X. W4 f' d$ \( E: q  U  [3 B
  37.         u16 cnt_5s=0;
    ; J" c* P9 v- @* X" w( P6 q
  38.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);0 ]8 R- K) y. n$ L
  39.     Systick_Configuration();3 p- ~% q" j8 {- B8 C+ u
  40.     Led_Configuration();
    : a3 E8 d7 k7 ?; ?, b5 ?/ [( t
  41. //        UsartTrance();+ T# ~2 @* N" L' d  Q
  42.         Key_Configuration();
    4 ]; x; ~" }6 e  s) C
  43.         Adc_Configuration();
    ; H1 U, I" |/ y, t
  44.         Adc_DMA_Configuration((u32)&_adc.buf,ADC_FILTER*ADC_CH_MAX);+ R! ^) J4 A, o* T
  45.         Usart1_Configuration(115200);5 D9 k- v  R% M
  46.         Usart2_Configuration(115200);
    7 F2 h9 U" e  t- }3 |3 o9 W) _$ I
  47.         Oled_Configuration();8 z1 o# f5 K) n+ D3 [; S' L. i9 |
  48.         Usart1_SendString("  usart1 is ok!\r\n");
      g- {4 d; R" p- x
  49. //        Usart2_SendString("  usart2 is ok!\r\n");
    " X" _5 k' v8 o. @4 G1 E; f% n
  50.         Delay_ms(200);5 ~" b9 k) W  q% g0 Q) `( b
  51.         
    8 ]* V9 Y6 w& O% `9 N% x9 [# S
  52. //        UsartTrance();( q9 ?9 U' \% D& b" U. X
  53.         sta=0;
    ! g8 x+ L/ H& l. D) Z
  54.         ' {' R0 c" H3 {+ ~( G/ B) z7 H! T
  55.         //检查ESP8266# G' b6 t& c) G' A( W0 w7 e6 a/ R
  56.     if(_net.Init(rxbuf,sizeof(rxbuf),txbuf,sizeof(txbuf))!=0){3 [/ G* G. f. R& }/ P* z
  57.                 Oled_ShowString(0,0*16,"Net Init OK!",8,16,1);- C' f9 o# X' i1 c
  58. //                printf("Net Init OK!\r\n");: U8 B* p% F& n- {8 g
  59.                 sta++;6 B0 y9 E+ \  K. ?7 p5 Q, ?
  60.         }
    . X; ]. x  Z- W2 j& d. `
  61.         else{5 |  ^8 b0 P$ J1 L; ~
  62.                 Oled_ShowString(0,0*16,"Net Init Error!",8,16,1);
    " R  i3 `2 K( m
  63. //                printf("Net Init Error!\r\n");. Y/ \% ?1 j* K; l6 w& ]6 O/ Q
  64.                 sta=0;: K) y! [" {8 T" u6 _' P
  65.         }% l0 `2 \4 p  L, l  K  ?
  66.         Oled_RefreshGram();! I" b- |9 I* V4 O! r4 ?
  67.         & U8 {# w- L/ P5 f# f/ O
  68.         if(sta==1){2 f2 c# q7 ?, \/ J4 p* M
  69.                 //连接热点. X. X5 J4 p- {7 G: y9 x* O3 K
  70.                 if(_net.ConnectAP("ssid","password")!=0){
    2 ?& S% t' o+ C8 u
  71.                         Oled_ShowString(0,1*16,"Conncet AP OK!",8,16,1);
    9 W9 h9 @. P% Z  u; V* v$ e* Q4 w% f
  72. //                        printf("Conncet AP OK!\r\n");7 o4 @3 p" V' ^6 x' R
  73.                         sta++;
    . {) u! n5 O$ [* Y' V
  74.                 }% @# ^2 p: b' R1 W6 L8 K/ N$ y5 K
  75.                 else {
    6 V# B# |* z; }6 r# H) c7 a. q
  76.                         Oled_ShowString(0,1*16,"Conncet AP Error!",8,16,1);9 \( A) W0 f9 h, ~5 X8 B' O" c3 _9 E& D
  77. //                        printf("Conncet AP Error!\r\n");& D/ Y8 d: U- d( s* H9 L
  78.                         sta=0;
    7 ?( R" b' v$ a  F/ J2 j( d
  79.                 }
    1 _. F) W- H% }& h% i3 ^0 ]
  80.                 Oled_RefreshGram();
    4 v) r7 L8 S4 Y* u  S, X' u" c
  81.         }
    ! K6 i4 ~) d3 f! k) ^5 F
  82.         
    9 E1 K% K, S# P
  83.         if(sta==2){        
    1 j' {# o# _0 v$ c1 [2 N! V3 L
  84.                 //连接TCP
    # B; f  m, C+ |. O2 Z2 z, g! w
  85.                 if(_net.ConnectServer("TCP","a1ugBNniFGU.iot-as-mqtt.cn-shanghai.aliyuncs.com",1883)!=0) {
    4 T! {# T/ L' {  D, D9 `* Y
  86.                         Oled_ShowString(0,2*16,"Conet Server OK!",8,16,1);) `' I- F7 ?, g$ n; r# }
  87. //                        printf("Conncet Server OK!\r\n");. Z: b3 n5 E3 W4 {
  88.                         sta++;
    " K2 U6 r; ^1 o+ p
  89.                 }
    ' _0 {# V. _8 s/ U4 U2 j
  90.                 else{. \- q. b2 o# y0 ]
  91.                         Oled_ShowString(0,2*16,"Server Error!",8,16,1);
    2 `; o% y# f( q& k% |) M- w% N) ~
  92. //                        printf("Conncet Server Error!\r\n");        7 I1 s8 F; {. r6 D, V- x
  93.                         sta=0;
    . F& Y2 ?2 K2 ]/ m$ e8 Q( X
  94.                 }6 u- I" h# ^) B/ a5 ]
  95.                 Oled_RefreshGram();
    9 J+ @5 b7 \1 r' W+ \# e
  96.         }
    4 {" j, v8 a' [: o# \+ F) T/ [
  97.         
    6 }- d; R: a9 M
  98.         if(sta==3){
    1 s+ q4 @, Q  D, \% |3 f) a$ \% G
  99.                 //登录MQTT3 d7 p# v' A/ Q& Q) X; P
  100.                 _mqtt.Init(rxbuf,sizeof(rxbuf),txbuf,sizeof(txbuf));               
    * ~; j9 X4 `4 \/ \
  101.                 if(_mqtt.Connect(
    % }$ Z) T" A+ M" U
  102.                         "123456|securemode=3,signmethod=hmacsha1,timestamp=789|",//ClientID! T5 h) C) I) u( v! Q
  103.                         "FY-STM32&a1ugBNniFGU",//Username
    0 W3 |6 r" A8 L+ |0 Y1 P' B
  104.                         "b447b9f26938d8eba6b2a4878066aae91839600c"//Password
    4 V/ i+ R: B3 N) |( G
  105.                         ) != 0){( T6 u# M, I' }: o. @
  106.                         Oled_ShowString(0,3*16,"Enter MQTT OK!",8,16,1);) \0 B' X- L& Z
  107. //                        printf("Enter MQTT OK!\r\n");
    6 _2 I; ?' o3 Q7 U+ i
  108.                         sta++;' D5 ]$ W( r! r; ?% ]+ }- f1 l
  109.                 }) i; D( P  S" k7 \6 t3 c9 V  q# w
  110.                 else{                : E( t: |, j$ q8 [8 M
  111.                         Oled_ShowString(0,3*16,"Enter MQTT Error",8,16,1);
    ! F2 }+ q$ _) f# n. s. j9 ?9 S' Z
  112. //                        printf("Enter MQTT Error!\r\n");
    2 h$ w) H0 p8 b5 V% k- F
  113.                         sta=0;5 e( U" N% R8 _; y5 X1 w
  114.                 }        8 U# V% U/ T# q7 g0 h
  115.                 Oled_RefreshGram();
    * ?% _7 e/ o* g8 d
  116.         }        3 P; A1 o# q4 _, A
  117.         8 C$ T7 V6 [- J. P
  118.         if(sta==4){9 X& Q; \$ }( u
  119.                 Oled_Clear();
    8 O+ O  N/ v0 ?1 B2 d+ G9 |+ I
  120.                 //订阅主题
    ' Y4 u7 C* ~) s% s% o: ~
  121.                 if(_mqtt.SubscribeTopic("/sys/a1ugBNniFGU/FY-STM32/thing/service/property/set",0,1) != 0){+ X; a1 o! o. D& x
  122.                         Oled_ShowString(0,0*16,"Subscribe OK!",8,16,1);/ k( ?6 l# M: Y- E) N+ J
  123. //                        printf("SubscribeTopic OK!\r\n");
    ! i" ?. M5 M! [
  124.                 }. \3 c. V" X& v0 U' R6 m# ?% [
  125.                 else{                        ( {2 l! P! l7 i
  126.                         Oled_ShowString(0,0*16,"Subscribe Error!",8,16,1);) f8 G, _1 {1 F% w0 T
  127. //                        printf("SubscribeTopic Error!\r\n");
    0 o3 ^& d/ I, b" C6 S% S  m
  128.                 }
    5 W- v6 Y$ O" N/ t( n. X  z
  129.                 Oled_RefreshGram();                ' z* X; h! |' D1 Y* m. b  ^
  130.         }$ E# N' c: Y- `$ a! N/ m
  131.         Delay_ms(1000);
    : P1 C. \' p2 U; ?: K: _
  132.         Oled_Clear();                        ' N6 I6 B6 |! M0 n4 D6 _
  133.         Oled_ShowString(32,0*16,"Mars Tech",8,16,1);
    % o' T) n% z) u9 M! ]
  134.         Oled_ShowString(0,1*16," VCC: 0000 mV",8,16,1);
    ( Q* H! Z8 a% C. }" d0 b1 X' @
  135.         Oled_ShowString(0,2*16,"Temp: 00.0 C",8,16,1);
    2 _, [$ b8 p  I2 P
  136.         Oled_ShowString(0,3*16," LUX: 0000  ",8,16,1);4 w4 @$ c0 [  C$ {
  137.         Oled_RefreshGram();( G2 g& v$ ?" `" _0 h( [* T
  138.         sta = 0;
    # Q/ Q- J+ R* U4 j
  139.     while(1)
    . N9 V9 t2 [4 N$ W
  140.     {
    ) d% X- O; O% y5 |
  141.                 if(++cnt_2s>=200){" _2 ~4 P/ S2 _# n# a4 P5 x8 J
  142.                         cnt_2s=0;
    1 d7 i. }) i: P8 h( I
  143.                         Adc_GetValue();
    ! c: x) U: n" Z5 @- o
  144.                         temperature = Ntc_GetTemp(adc_ntc)*0.1f;
    8 s6 S( q* K! h0 Y4 m
  145.                         Oled_ShowNum(8*6,1*16,battery,4,8,16);                        6 t9 J' N+ k" \4 X+ @8 W
  146.                         Oled_ShowNum(8*6,2*16,(u8)temperature,2,8,16);! ]' H* T; @$ T
  147.                         Oled_ShowNum(8*6+3*8,2*16,(u16)(temperature*10)%10,1,8,16);                        * b3 G/ J* F* v. y
  148.                         Oled_ShowNum(8*6,3*16,adc_light,4,8,16);
    / ]( `5 e' s" B. ^: J# t+ W5 K; L
  149.                         
    : O5 g! n$ k, z6 O) v! X9 e& b/ S. B
  150.                         Oled_RefreshGram();9 Q0 k& ^4 w/ l) G
  151.                 }
    1 ~+ ?9 R- w. F9 [! M( M0 v
  152.                 if(++cnt_5s>=500){//
    & Y+ s. j" r+ C9 {: B0 ?
  153.                         cnt_5s=0;% a9 [5 t+ e/ k, M+ i
  154.                         sprintf(mqtt_message,0 ^- M4 i2 L1 Q' H  l# c# H% f: X. F
  155.                         "{"method":"thing.service.property.set","id":"630262306","params":{\
    9 X! w$ M+ b3 B* U7 e6 @* b( \
  156.                                 "CurrentTemperature":%.1f,\9 i! u* s  u! `( K
  157.                                 "hue":%d,\" E- T( S' K: ?; O& q
  158.                                 "mlux":%d\
    9 Z* U1 ]$ i' X8 @$ ^3 P# a: j
  159.                         },"version":"1.0.0"}",5 p' q, k- U6 L4 l1 r( C
  160.                         temperature,; |3 ]1 O8 _* a; }1 ~* N6 I% p
  161.                         rand()%0x00ffffff,
    + D3 ~" t' s$ T) t8 g. j
  162.                         adc_light
    ( z* ]! t9 b9 C5 h
  163.                         );
    / q5 N7 s* B4 ^5 v: T
  164.                         
    * A" m" z3 r/ T9 h4 t
  165.                         _mqtt.PublishData("/sys/a1ugBNniFGU/FY-STM32/thing/event/property/post",mqtt_message,0);                        ) @2 B0 A* M3 n% M. e3 s
  166.                 }
    : Z  ^+ r1 |: K* t
  167.                 if(_mqtt.rxlen){
    2 x3 y4 z( t; n
  168.                         Mqtt_Progress(_mqtt.rxbuf,_mqtt.rxlen);                ( T9 `2 B( n- J! K/ P
  169.                         memset(_mqtt.rxbuf,0,_mqtt.rxlen);0 @' f. k8 X8 S
  170.                         _mqtt.rxlen = 0;0 a5 Q0 p( c' O1 R% i
  171.                 }                        
    ! `2 X- O9 ?( i$ p
  172.                 Delay_ms(10); 3 \  Z) e& r, d0 K; t) x9 K
  173.     }
    2 x8 O3 a( D9 n# _7 Q8 [
  174. }
    * E8 U# E  ?% H

  175. 7 D+ Y( L# A* H% U4 P7 f  S8 H
  176. void Adc_GetValue(void)
    $ J+ R; c% I# m% b
  177. {1 \  Y' `3 d% W# Y* X- f, x
  178.         u32 sum[ADC_CH_MAX];        6 f" {1 t: K5 Z
  179.         memset(sum,0,sizeof(sum));- [9 x0 y; g! Y7 _' I
  180.         for(u8 ch=0; ch<ADC_CH_MAX; ch++)
    7 m* ?4 G" O! e8 c4 Q3 o. g
  181.         {; Y8 a, N! K% L$ ^+ M: A
  182.                 for(u8 filter=0; filter<ADC_FILTER; filter++)
    6 c" F9 F2 w& j% m, R
  183.                 {
    / _) t8 u1 k& w& v6 r) Y
  184.                         sum[ch] += _adc.buf[filter][ch];//计算累加和9 V- u. j+ g4 ]3 U) y" c
  185.                 }               
    ! [! m( [$ v, P
  186.         }/ d, H  D2 g& i' ~0 J4 F
  187.         adc_light = sum[ADC_LIGHT]/ADC_FILTER;& W, w. a3 G. w, l! m2 f
  188.         adc_ntc = sum[ADC_NTC]/ADC_FILTER;
    & I9 B5 a4 }$ r. k9 j
  189.         battery = sum[ADC_VCC]/ADC_FILTER*3300/4095*11;         //mV
    % a+ |& n. r& F/ p  {5 G
  190. }& H# d$ n! c) M2 z9 n6 l
  191. 5 s6 j( f2 B" m9 i8 J$ [
  192. u8 temp;
    & }) F# y9 b; b; i9 Y; E  b0 [4 @, N
  193. void USART2_IRQHandler(void), O1 L0 I, z) `8 t# W3 x0 E/ l
  194. {
    ! i1 ^4 ?6 m1 e* w; w; x( ]
  195.     static u8 rxlen = 0;
    6 P  @! k6 X" i- y6 F* @9 d
  196.   F4 f  n4 z( u! R
  197.     if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //判断接收数据寄存器是否有数据0 p$ ?( s' n6 T. u: b( H
  198.     {
    " @% w+ ^5 n- m2 b
  199.                 temp = USART2->DR;' l, ?3 y, b1 `3 M3 W. y" V
  200. //                USART1->DR = temp;//这里用作串口1打印WIFI模块发送的数据, L8 ^4 ], }- M8 ^/ L1 P1 A* f
  201.                 if(rxlen>=255) rxlen=0;* v* q9 ?  [. \' B: Z% z6 m
  202.         rxbuf[rxlen++] = temp;
    8 ]& @( Z: d  ?
  203.         rxlen%=sizeof(rxbuf);
    * D5 I, q3 j7 ?# H: p# \+ _
  204.     }! G- }4 W& \$ k- ^' L% C) i* A6 j7 G

  205. * _2 Y& a/ C, J  @; |. p8 t
  206.     if(USART_GetITStatus(USART2, USART_IT_IDLE))' s1 l/ k2 P$ D6 F/ W
  207.     {
    3 e$ A. b5 v+ B, D7 @% p5 M  I2 C
  208.                 temp = USART2->DR;8 d. T4 _1 m7 s: ~* ?
  209.                 temp = USART2->SR;
    , B0 G4 ~8 a* W5 _
  210.                 _mqtt.rxlen = rxlen;3 }: @0 ]4 `; f/ c4 z
  211. //                Mqtt_Progress(rxbuf,rxlen);//主循环做异步处理. m9 W: P  X9 w
  212.                 rxlen=0;/ V6 F- O+ z, p9 a
  213.     }5 W8 g5 @! n5 Q$ u9 O
  214. }
      k: f4 l+ w( v2 m% n
  215. //void *StrStr(void *dest,void *src);
    1 M7 m2 m0 s7 h2 d% f' P, [( f

  216. $ A" m" b7 a+ {. e( B  ]  A% n
  217. u8 *p;
    0 @4 \5 E! c, c; h! V8 c* H. j
  218. void Mqtt_Progress(u8 *buf,u16 len)8 D7 f4 V& Z6 ^
  219. {
    6 l! x' W  Q8 [! y+ u
  220.         char *keyStr = "hue";1 D' |$ p8 x) f  ~7 r
  221.         u8 keyStrLen = strlen(keyStr)-1;/ y' ?5 H/ ^& b/ m9 A% l9 [
  222.         u8 i,j;% e7 ~% S( z! t2 i
  223.         for(i=0;i<len-keyStrLen;i++)
    4 X' J1 `( Q9 ^) d4 K, {6 u
  224.         {
    + I7 R8 R' F3 p1 y; K1 y( y
  225.                 for(j=0;j<keyStrLen;j++)) L% `: ~( D" y9 x8 t/ @" x
  226.                 {! S7 O. z! a# S
  227.                         if(buf[i+j] != keyStr[j])        break;0 l& N0 C0 [) I  c
  228.                 }          j! H3 y& {& r1 i5 `/ w" `) P
  229.                 if(j==keyStrLen) break;
    # K4 o0 {; B4 m& V) F
  230.         }9 Z3 F% @, h5 D  M
  231.         if(i<=len-keyStrLen)
    # l5 Q. W+ r. Y; \
  232.     {* W4 f- V- k; j5 a! \
  233.                 u16 temp = 0;
    $ G9 L) Z; Q, O- }; ?7 z
  234.                 p = &buf<i>;( e7 s9 H9 y/ r9 D* N0 n( [: _
  235.                                 3 r* @" o0 w6 w# |' I& _
  236.                 while(*p != ':') p++;: Q: v/ V# B4 k+ p# C0 s6 y
  237.                 p++;" z: y- J; f1 ^& V9 b* Q% V
  238.                 while(*p != '}')) V9 Z/ I+ X5 V
  239.                 {
    * Z; \: s( R2 i: T
  240.                         temp = temp *10 + (*p - '0');! ]. H" G( e( T1 ?/ t
  241.                         p++</i>;/ t( _8 c& R0 ~3 v1 i% N) B; F
  242.                 }
    5 h+ m( z1 n  ?/ U$ S' W8 L. p
  243.                 printf("receive message, hue = %d \r\n",temp);. o+ V6 z' X* }
  244. //                Usart1_SendBuf(buf,len);
    $ L% t  e% Z, \( X) p
  245.     }
    ( G$ G/ Y6 j8 v7 D# t
  246. }/ d6 }) }' O" `, I) Z0 \
  247. 4 q' e: ]8 t* _# S) C4 o) J; J% F
  248. /*********************************************END OF FILE********************************************/
复制代码

1 }" m: F* j# K7 W, m8 e* y/ @6 w- V  R* ^
net.c部分
1 A0 q6 h5 a: o- D' ]: Q  _1 |$ Q/ s( Q/ H# u) p' V
  1. #include "fy_network.h": f7 \8 B' u2 W% I( V* R; `
  2. ( I- G: z7 }. I& y) S
  3. //#define _DEBUG_NET
    - [( F3 E5 S: a

  4. - f* z: Y6 y4 m5 o
  5. static u8 Check(void);# \* f. G0 w3 V8 Q' |2 K- b
  6. static u8 Init(u8 *prx,u16 rxlen,u8 *ptx,u16 txlen);
    + g7 m. i) |3 q1 `
  7. static void Restore(void);
    " a, z! x: l0 y0 @
  8. static u8 ConnectAP(char* ssid,char* pswd);7 g* A+ V; J. ?; E0 B' i
  9. static u8 ConnectServer(char* mode,char* ip,u16 port);# B" c9 t! h' L. o( P* Z; j
  10. static u8 DisconnectServer(void);
    2 v: m4 P3 q' m- [$ ?5 ]8 o
  11. static u8 OpenTransmission(void);
    # i3 N3 n; @. I  S+ q/ X
  12. static void CloseTransmission(void);& B, z+ r1 y: N# s$ O1 ?' u
  13. static void SendString(char* str);
      s* y5 C- D/ X6 a5 t, q
  14. static void SendBuf(u8* buf,u16 len);) l4 `5 h) _+ f  c# B

  15. 9 |7 L4 d9 |0 @) |% ~

  16. 8 i: M1 H, }; R2 u
  17. _typdef_net _net=
    * H1 P2 ]: Y* x5 t7 W% a9 Z) E5 q
  18. {
    . [9 `0 P. v  N
  19.         0,0,
    ( o2 y2 v- G( Z& ]! K4 |
  20.         0,0,! P; a" e/ }" u3 `
  21.         Check,
    ; A) u# {6 u/ A7 A0 U% Q+ M! D8 u
  22.         Init,
    % X+ j$ u3 g' t* T9 M4 `
  23.         Restore,
    8 C( Y* p. O# @7 ]0 [1 B  O% V
  24.         ConnectAP,4 G, W, R+ q; B8 \/ W& a7 r3 P- \
  25.         ConnectServer,
    - s" X3 b7 b5 g) F" W4 |: X! E
  26.         DisconnectServer,5 L% u& L8 y( t
  27.         OpenTransmission,3 g7 G* v/ ?6 Z7 n' z. M
  28.         CloseTransmission,
    " B$ {+ e6 P8 W: d
  29.         SendString,
    $ O& y4 f; O; g. A
  30.         SendBuf% @% {, k( o2 f8 ~. i4 z: Q0 A
  31. };
      ~1 A. ]1 b5 L
  32. ) L6 J8 O) M; I1 I! S
  33. /**
      s9 T. G' E$ L; O
  34. * 功能:初始化ESP8266! x6 F) G- B" `, D/ \0 C
  35. * 参数:None5 x$ T5 E2 y& m' G8 @+ z1 B
  36. * 返回值:初始化结果,非0为初始化成功,0为失败
    " W; ^; \: I% }/ r( G4 p8 F
  37. */
    - J7 S! C2 ]; o4 _9 `9 |0 [. c
  38. static u8 Init(u8 *prx,u16 rxlen,u8 *ptx,u16 txlen)
    5 c4 ?- S! a) a1 ]
  39. {  @7 T/ z/ u" l! u5 g* R) a9 \' D
  40.         _net.rxbuf = prx;_net.rxlen = rxlen;
    5 Q0 {) H/ w7 ?6 D" B; o
  41.         _net.txbuf = ptx;_net.txlen = txlen;  r  p3 [# N, ~1 M, ?
  42.         
      {, X" m- \% i
  43.         memset(_net.rxbuf,0,_net.rxlen);
    . |3 m% m& d+ H: \- S
  44.         memset(_net.txbuf,0,_net.txlen);$ n8 O% Z+ a. [% ^6 A/ k/ D) i
  45.         5 V* @5 V& H, Y2 p' T
  46.         _net.CloseTransmission();          //退出透传
    & \5 G- Q" x0 Z" h4 S$ c
  47.     Delay_ms(500); $ @5 E) d; }/ t* p5 E
  48.         _net.SendString("AT+RST\r\n");   //重启ESP8266   C$ O4 l% ?# I  F: q
  49.         Delay_ms(800);8 Z3 \, |2 ~( p. K1 v
  50.     if(_net.Check()==0)              //使用AT指令检查ESP8266是否存在  W% [8 F' L' c6 ]* V
  51.     {
    6 F/ V8 F( z8 V2 T: E
  52.         return 0;1 P; E8 V$ E. _: R5 ~  y" G* v
  53.     }
    ( y' \% \% G" s  @

  54.   l& L9 p% q% E1 N6 H/ a& M
  55.     memset(_net.rxbuf,0,_net.rxlen);    //清空接收缓冲! d- D# |3 n5 h+ }
  56.     _net.SendString("ATE0\r\n");             //关闭回显
    " D$ ~7 b7 ?( k
  57.     if(FindStr((char*)_net.rxbuf,"OK",500)==0)  //设置不成功
    1 K7 Q( k" P( B+ X0 j6 c
  58.     {8 P, c& ~' t6 h6 d- n
  59.         return 0;      
    ; f* J: y- G7 e  q8 r3 G& o
  60.     }+ @2 f* A) @9 I$ N9 P
  61.     return 1;                         //设置成功: F" T* \) L6 j; d1 D# Z
  62. 7 O4 H0 B9 R! L
  63. }1 ~# H, t. ?8 B5 s& `% L9 b. d
  64. , ]9 \1 V0 S/ g# |3 h+ j' _
  65. /**
    , S+ \! `4 r6 |+ J/ s
  66. * 功能:恢复出厂设置
    8 [+ l! U( H8 E- V4 x0 Y
  67. * 参数:None
    * A: G( U/ A( Y" s
  68. * 返回值:None0 R  ?& T! q' J6 m0 r; b9 k
  69. * 说明:此时ESP8266中的用户设置将全部丢失回复成出厂状态
    + D# e6 z+ s! f* S! v, |
  70. */
    0 a/ H6 _/ z0 ^& y& [6 Z
  71. static void Restore(void)( B6 }5 |1 c6 Q( a- f2 o- c
  72. {
    9 g3 M1 l# A0 C( O3 ~
  73.         _net.CloseTransmission();           //退出透传
    ) @2 u: m; C8 i; l
  74.     Delay_ms(500);
      G/ H; y& m/ e( K
  75.         _net.SendString("AT+RESTORE\r\n");//恢复出厂         
      D& w1 e- C( D  q; X
  76. //    NVIC_SystemReset();                 //同时重启单片机   
    ; }: M& z* x* o9 Q
  77. }3 u% }6 h- {3 a# r! L3 p6 v

  78. 2 Z5 U( O5 y  P: s, l6 F
  79. /**
    % h. N  e1 I* M9 g4 Y+ R
  80. * 功能:检查ESP8266是否正常8 t  S  i0 Q) y. h3 w
  81. * 参数:None
    + T' }7 s9 Y: W1 l) U, M
  82. * 返回值:ESP8266返回状态! [1 g4 X. E- E+ E
  83. *        非0 ESP8266正常
    . G* `( S3 M8 T1 D$ F, I
  84. *        0 ESP8266有问题  ! g# N* a0 i; R0 Z8 R' @8 F
  85. */1 G$ e- D' L5 Z$ ^
  86. static u8 Check(void)
    7 y- G5 v! H2 E1 u6 K1 F
  87. {
    ( I; b4 x% A& g: `- \( \% M3 @3 {
  88.         u8 check_cnt=5;" A; }+ Z2 l& X* y9 ]$ Q' ~
  89.         while(check_cnt--)9 t  O& _3 {, p0 g
  90.         {( L# K& A- S) F& V; F
  91.                 memset(_net.rxbuf,0,_net.rxlen);          //清空接收缓冲
    4 P0 x3 _6 k' {0 Q$ d' `; S0 ^; \
  92.                 _net.SendString("AT\r\n");                      //发送AT握手指令        2 j7 f3 T" d4 F. M. a
  93.                 if(FindStr((char*)_net.rxbuf,"OK",200) != 0)
    # p) @; [6 G* s& Y; Y; N8 Q
  94.                 {4 k2 ^1 J  P+ R: k' o8 U
  95.                         return 1;7 D* z6 c# i$ J" i1 k
  96.                 }
    0 s, R: ?: m. V- j3 z5 v/ a
  97.         }
    8 g! x7 J/ B( K9 d1 X1 Y& u
  98.         return 0;
    2 U- m( e; n, i& Y& L* U8 f
  99. }& x7 J8 a; f/ Z  F
  100. 6 N9 w: a6 Y4 B8 M8 G2 Y
  101. /**( p8 n! r9 E" @; C1 O" }
  102. * 功能:连接热点+ N2 V$ o$ l' H& U9 Y
  103. * 参数:
    ) k( v/ v$ z+ W% G3 [1 D; ~0 \
  104. *         ssid:热点名
    1 F+ u( V; r$ v
  105. *         pwd:热点密码1 p1 D6 @4 |9 X
  106. * 返回值:
    ) l' C0 F* X# c/ c
  107. *         连接结果,非0连接成功,0连接失败6 p; `  V) i6 L% D- ~7 ^
  108. * 说明:
    9 m+ @; q0 Y/ @$ S. ~
  109. *         失败的原因有以下几种(UART通信和ESP8266正常情况下)
    9 r% f9 J; H$ t( b. \4 y$ v1 V
  110. *         1. WIFI名和密码不正确
    " `" b0 m3 D" d4 u* D, ^, |( J  L2 j
  111. *         2. 路由器连接设备太多,未能给ESP8266分配IP
    + R' V) Q# j, |0 H
  112. */) R( L" v$ q4 _" O% ^% K
  113. static u8 ConnectAP(char* ssid,char* pswd)
    * G- P! v! W) ]$ D; h1 e
  114. {  o& k- y. K5 B2 y9 I9 d
  115.         u8 cnt=5;
    7 a% x$ p9 z) L
  116.         while(cnt--)
    ( G$ c: y; ]5 }" c& b+ _
  117.         {5 m5 h. g; \- i9 N- R1 v
  118.                 memset(_net.rxbuf,0,_net.rxlen);     2 n  Y+ c& S: B& K. `1 S$ [
  119.                 _net.SendString("AT+CWMODE_CUR=1\r\n");              //设置为STATION模式        1 s% s6 Q0 {+ T9 u5 {: D, s
  120.                 if(FindStr((char*)_net.rxbuf,"OK",200) != 0)8 P- H% D  A5 D
  121.                 {
    $ s2 E2 }* @' v4 M0 }' ^( J
  122.                         break;4 Y) w0 B6 l3 N: e: n
  123.                 }                             : K4 n& o6 }( m/ m( v6 \9 P9 |
  124.         }* b0 x( h7 f8 Q
  125.         if(cnt == 0) ; j0 h! Y6 k* D* _: v# W
  126.                 return 0;
    5 u6 m0 t% F0 e
  127. - E0 F/ O$ R6 I5 Y
  128.         cnt=2;' a. J. q. T7 f, n9 B
  129.         while(cnt--). S5 f, R/ C, j( A1 @2 \& ^
  130.         {' b, f+ _2 @" f/ H3 k! ^1 j
  131.                 memset(_net.txbuf,0,_net.txlen);                            //清空发送缓冲
    % N2 G( y4 Y& b5 M- Y
  132.                 memset(_net.rxbuf,0,_net.rxlen);                            //清空接收缓冲
    # y: G+ D* g1 ~& s
  133.                 sprintf((char*)_net.txbuf,"AT+CWJAP_CUR="%s","%s"\r\n",ssid,pswd);//连接目标AP: M% A# Y3 z( J
  134.                 _net.SendString((char*)_net.txbuf);        
    1 F7 l" b% v# X6 x3 a/ V
  135.                 if(FindStr((char*)_net.rxbuf,"OK",8000)!=0)                      //连接成功且分配到IP" F$ x, Q* D; ^: d- G/ H
  136.                 {
    $ a' N. _5 N  a" f6 o; N" w
  137.                         return 1;
    - L$ e$ W# }# m# H
  138.                 }
    0 ?* k# I, Z. w, i1 h
  139.         }1 W% y- S0 _. {$ ]- \
  140.         return 0;
    " L, q- F  e- v. V$ h6 ~6 p% F3 a4 M
  141. }
    $ [$ g3 T0 R* a, s$ G3 ~5 H7 I7 I3 E
  142.   I; _. l6 ^, u0 m: {& s2 _
  143. /**
    2 w, c& L3 ~9 Y' X: h! W8 [2 v
  144. * 功能:使用指定协议(TCP/UDP)连接到服务器. Y9 a: C; t, ~! Y& Z; w! O
  145. * 参数:. a& h5 b- P0 o5 @
  146. *         mode:协议类型 "TCP","UDP"
    7 ], \- z7 Y5 `- j8 o/ l* e; d
  147. *         ip:目标服务器IP4 C" Y' n  L1 ~% {4 A
  148. *         port:目标是服务器端口号
    & T) a' @+ {3 w/ \3 ~
  149. * 返回值:" T+ Y" A+ T. i" H. n, D' ?
  150. *         连接结果,非0连接成功,0连接失败' b5 ~8 v) Z& ]& s: C' q
  151. * 说明: 8 O/ W, H6 \1 T& j/ O
  152. *         失败的原因有以下几种(UART通信和ESP8266正常情况下)
    ' |$ N4 n% c9 ?$ c- R! r0 z
  153. *         1. 远程服务器IP和端口号有误/ \: q# c# v( h2 k/ w' Q1 k
  154. *         2. 未连接AP
    3 T, E; P. r6 F, D/ M, z8 D
  155. *         3. 服务器端禁止添加(一般不会发生)
    : n: Q) w3 s! A
  156. */
    3 a3 M7 ]: e  k
  157. static u8 ConnectServer(char* mode,char* ip,u16 port)
    9 d( R% b; q5 ^5 m* p0 D: M
  158. {! L5 n4 Y7 Q8 ?& _6 a. g7 a) F
  159.         u8 cnt;
      w: R: Y/ Z5 L+ b. Y
  160. ' I7 ]. n$ I/ y4 y
  161.     _net.CloseTransmission();                   //多次连接需退出透传
    1 b- U' \1 A4 l$ T! U5 K* M
  162.     Delay_ms(500);/ J$ z; r* ^! m' t
  163. 1 {  a2 X4 H7 ]2 F: |
  164.         //连接服务器
    + d8 a( G" k1 h% ^
  165.         cnt=2;
    + ]8 S! Z; X# t+ T$ @
  166.         while(cnt--)  X# L8 s8 j! F" p: K0 ~
  167.         {" P8 M. u! N1 b- {
  168.                 memset(_net.rxbuf,0,_net.rxlen);      2 [( ]4 g2 |; q4 z7 B! L9 J. }
  169.                 memset(_net.txbuf,0,_net.txlen);   
    7 l7 }) Y( l8 k  m/ Y3 W7 p3 V5 [
  170.                 sprintf((char*)_net.txbuf,"AT+CIPSTART="%s","%s",%d\r\n",mode,ip,port);0 m  v1 J- L" k4 `3 H, \8 k' z/ y
  171.                 _net.SendString((char*)_net.txbuf);% t2 K* W5 {7 M1 r: k$ C& v! o
  172.                 if(FindStr((char*)_net.rxbuf,"CONNECT",8000) !=0 )
    4 ?2 y  D/ n' P6 F
  173.                 {
      b. c  r' x: v1 o) f
  174.                         break;6 e" Q1 x! K1 q3 ?2 H
  175.                 }
      T2 V+ z+ M# O6 ^0 P9 u; m
  176.         }
    7 L+ D! ~5 v4 x! j
  177.         if(cnt == 0)
    : _$ f/ y  p7 b6 q
  178.                 return 0;. F& s1 t  l1 _3 O: k/ E* v) H3 X
  179.         & T# X( r4 p! u9 L( a# C# \: G! P# u- q. g
  180.         //设置透传模式. L2 L" V# |$ {3 R3 b: ^
  181.         if(_net.OpenTransmission()==0) return 0;& J9 u4 D. U" H! t: H
  182.         ) X' X4 A3 q, i- T: Z8 z8 D
  183.         //开启发送状态
    & j! ]$ P/ \9 B% ?
  184.         cnt=2;0 y. x% }0 U0 ^9 z8 d
  185.         while(cnt--)! ~* a$ A3 B# h1 X- r% z5 b- L
  186.         {
    7 a0 ^0 A5 w- |; S6 W! H+ \
  187.                 memset(_net.rxbuf,0,_net.rxlen); / d! k, M1 {: \+ p
  188.                 _net.SendString("AT+CIPSEND\r\n");//开始处于透传发送状态7 p& c# X0 u& H0 ~/ r5 x
  189.                 if(FindStr((char*)_net.rxbuf,">",200)!=0)
    0 @0 u$ _1 d  C8 j1 b2 L: Z/ _
  190.                 {
    ) \+ F2 H! k7 _! @- o  {- P) ]0 b* n: v
  191.                         return 1;
    + z, d4 |2 ^" n. o) @  ~
  192.                 }
    / K( o( G! o2 A3 i
  193.         }
    ( H7 w9 u; d& ^/ `
  194.         return 0;
    . z4 D- d2 A: w/ X: l% N
  195. }
    1 o6 l" L9 K& }+ M6 x/ K

  196. , n) @, N8 M3 [+ D5 _4 G; {: f
  197. /**
    ! D1 r2 |2 w( p! W2 D1 e
  198. * 功能:主动和服务器断开连接
    ) R* h! O! ]8 N0 n, n- V' J' ?7 P
  199. * 参数:None0 ~' X3 J9 \! O' _( w' q) K! r+ \
  200. * 返回值:
    1 h8 ]3 Q0 @1 S+ J" y/ y
  201. *         连接结果,非0断开成功,0断开失败
    7 |. r. j% J( E% X) U- ^# F& J
  202. *// S% X( x" Y* V) G1 K4 u: Z
  203. static u8 DisconnectServer(void)
    8 [" m$ N* h" A4 {
  204. {' t: ?0 s6 }8 N. e! i6 h5 f* f& j
  205.         u8 cnt;
    - c; y8 y! t- V
  206.     _net.CloseTransmission();        //退出透传% G: x( p! k. @/ s! H+ K
  207.     Delay_ms(500);
    ! q1 j  O; }. b, o$ \
  208.         while(cnt--)' j+ j' m. A9 O$ Q3 R1 k4 r
  209.         {7 ]; k7 X& t; F
  210.                 memset(_net.rxbuf,0,_net.rxlen);  7 N9 _) f0 s0 H. \" j: o
  211.                 _net.SendString("AT+CIPCLOSE\r\n");//关闭链接
    # h* h# \$ \4 h& D5 D/ s5 X

  212. 8 ~8 e; r" \# d  k! ~6 e2 h$ K2 M
  213.                 if(FindStr((char*)_net.rxbuf,"CLOSED",200)!=0)//操作成功,和服务器成功断开/ d8 _" r& b* I0 ^0 q9 d  o1 j
  214.                 {1 U9 @1 t% L* |" ~! w  E
  215.                         break;
    " |0 i1 \# H+ f* J* a
  216.                 }
    ' q0 E* a" ~) {
  217.         }8 R$ _2 H. r- {$ v6 s
  218.         if(cnt) return 1;
    5 n5 {; [4 e( u7 q
  219.         return 0;
    & @2 Y1 n# I- m, K9 o; I
  220. }
    & y/ C5 P; E* l1 x) c+ t8 y
  221. - r( M- G3 y$ Z' P5 l
  222. /**; |' _7 ]+ v/ J4 {
  223. * 功能:透传模式下的数据发送函数$ Y, n( w; H1 E4 ^- N. U9 {  j: G3 g
  224. * 参数:  v& g: |9 {, L7 O6 W! m
  225. *      buffer:待发送数据
    ' R7 v7 @  b  }9 B5 z& B
  226. * 返回值:None
    - G; c. L5 k4 Y$ H  b; N0 U  Q" j( I
  227. */
    : N) E4 q; _1 }8 s# X% [6 c7 S
  228. static void SendBuf(u8* buf,u16 len)
    / b  ~' h7 E2 _6 K
  229. {
    7 m# F8 }- z- O/ l/ K! I
  230.     memset(_net.rxbuf,0,_net.rxlen);
    - c" p3 f" _- F. u7 L; }6 G
  231.         #ifdef _DEBUG_NET
      E8 a) c4 L, ?6 ^( H! @2 N4 I
  232.         Usart1_SendBuf(buf,len);
    " f0 y8 d- m" y' _5 _' G8 c6 U" ]
  233.         #endif        
    : C: m8 F# d6 q; a5 W
  234.         Net_SendBuf(buf,len);$ Y% S7 B9 x8 r( a0 z3 X4 A/ |. t, U+ o5 N
  235. }3 d  T7 N( [5 \# {2 M& V

  236. 2 N5 Z6 G% |/ n/ a, u6 @

  237. - d' @1 c' J$ O5 \, i, {8 t0 u9 v
  238. /**
    2 l0 c! x: p* p6 S+ v
  239. * 功能:透传模式下的数据发送函数# f6 t6 z! y7 j% {
  240. * 参数:2 ^4 h* l" V- z3 K) L5 d
  241. *      buffer:待发送数据
    ; E# i% C" I$ D9 k$ x8 u5 V& {
  242. * 返回值:None
    3 H5 ?- h% j. L! D0 c# C
  243. */
    2 q1 \- t" f# o9 k/ [$ E5 z
  244. static void SendString(char* str)
    9 L# w) D& D2 n/ h/ T- k4 [* S, w. D$ M
  245. {1 E" R* Z( E. O! p: i5 ?
  246.     memset(_net.rxbuf,0,_net.rxlen);! F- u6 B. V) ~
  247.         #ifdef _DEBUG_NET3 ]7 ]4 V: D: f8 n1 S8 C7 T4 K
  248.         Usart1_SendString(str);* l3 P5 d9 k: D
  249.         #endif        
      h/ |' g  f* y& H5 V: o
  250.         Net_SendString(str);
    1 T8 K" o$ Y5 a
  251. }
    ' N' r4 F3 {$ G1 {# J2 f

  252. " d/ q+ h. h+ {) y3 L( ~
  253. static u8 OpenTransmission(void); v0 T7 i! `# Q4 q& C
  254. {
    2 j& C4 Q, H" ?+ Y' s$ G0 x3 ]
  255.         //设置透传模式
    9 z3 p) Y' J5 t2 }) I/ T7 @
  256.         u8 cnt=2;. g$ V1 D+ K$ y% y8 p" P- a
  257.         while(cnt--)6 u& y7 X7 q# P8 K4 a. R. T
  258.         {5 v, @9 E8 v8 n4 C# j6 Y& E: a
  259.         memset(_net.rxbuf,0,_net.rxlen);   
    8 c! b/ b8 q8 _- n% g0 P6 ?4 x/ p
  260.         _net.SendString("AT+CIPMODE=1\r\n");  
    & j' |0 ^( ~8 A5 X8 T5 u
  261.         if(FindStr((char*)_net.rxbuf,"OK",200)!=0)& Z# D/ D, I, {  R8 U
  262.         {        5 O8 r% \, E/ a! G  k% q/ n/ H2 c+ o
  263.                         return 1;: e, v9 x# ]& n% x# f
  264.                 }                        
    ( T! Q. t: b* P; O5 l
  265.         }( U$ q# Y4 L( W" ~( k
  266.         return 0;7 U  q% o# K4 H
  267. }8 g" G/ @- T7 ?& t* A7 i
  268. //退出透传
    : K$ J6 S  v7 J6 t4 U( }
  269. static void CloseTransmission(void)' v5 ~/ {9 D  U; r+ H; w
  270. {7 l3 l# K! Q1 N  Y- y  P/ S0 |
  271.         _net.SendString("+++"); Delay_ms(50);) C3 K9 s: v) ?, j: T; i: }$ @
  272.         _net.SendString("+++"); Delay_ms(50);
    " u8 I3 t* V* D, t. l! w( x
  273. }) U0 }# R5 h$ w6 ~$ M/ ]/ p

  274. 7 l  z) X- Y& k1 {" h  v# ^& N8 |; d
  275. /*********************************************END OF FILE********************************************/
复制代码

8 T9 F5 s, Y$ R8 Tnet.h部分
/ W( B* m, p% f' P3 e  p4 I5 Z1 `: L  e# ?$ u- B$ m" R5 H  u
  1. #ifndef __FY_NETWORK_H
    . ~# T: |, [: U
  2. #define __FY_NETWORK_H
      ]8 J7 m/ S0 `

  3. 2 x  ?1 m' N2 H" K4 Q2 J4 z- I
  4. #include "fy_includes.h"+ d/ e( y/ M$ d

  5.   e0 D8 N0 h# t/ X1 @2 @# t( R+ F
  6. /*连接AP宏定义*/
    & ?" X) P' V* ~# i" I, J
  7. #define SSID "ssid"
      A1 m5 `* N9 b( Q2 R
  8. #define PWD  "password"
    0 W* H: o. J+ v1 y; _% ?* k
  9. 3 E  A9 Q. F1 ~
  10. /*连接服务器宏定义*/  P  r1 w. B" j" U( P6 K1 |4 F2 @
  11. #define TCP "TCP", L/ s7 m+ l: T4 \8 v. c
  12. #define UDP "UDP"
    2 U1 G0 ~4 L6 o/ Z" K3 S7 [: F8 B
  13. #define IP  "122.114.122.174"
    % S% {$ i9 l" c( |( c$ ?
  14. #define PORT 40915+ G9 u6 g# p6 T
  15. ' E5 \3 W5 R. i( }4 c8 s
  16. #define Net_SendString(str) Usart2_SendString(str)
    ; V  ?7 R) g8 S' n) D
  17. #define Net_SendBuf(buf,len) Usart2_SendBuf(buf,len)
    & j0 E' j9 C- [5 h, w  i
  18. ' F$ z/ ^: e4 I7 B% Z
  19. typedef struct% ^0 o0 Y* j3 w5 Q3 t4 e
  20. {
    1 i: S5 S& B0 }
  21.         u8 *rxbuf;u16 rxlen;
    ! q. B3 ~% g7 V- Z' G$ x
  22.         u8 *txbuf;u16 txlen;5 V; K5 L7 E% b2 \& _* {5 S
  23.         
    - o+ q( ~1 }6 [1 W0 G# o! i5 \
  24.         u8 (*Check)(void);" h6 i3 [, U4 V5 L  F
  25.         u8 (*Init)(u8 *prx,u16 rxlen,u8 *ptx,u16 txlen);- g0 S" E3 b/ \* ]' p2 C3 h4 o
  26.         void (*Restore)(void);' A/ k5 K- k( D$ ~5 R
  27.         u8 (*ConnectAP)(char *ssid,char *pswd);
    3 V. @! R% N7 \9 E3 t
  28.         u8 (*ConnectServer)(char* mode,char *ip,u16 port);
    ' s& N* [& K  v: I3 Y( t  E
  29.         u8 (*DisconnectServer)(void);
    * H3 I) i9 O8 e: d  X6 J
  30.         u8 (*OpenTransmission)(void);; P' r8 n0 T* B5 c
  31.         void (*CloseTransmission)(void);                + S5 t$ B" `$ M6 `
  32.         void (*SendString)(char *str);0 N: [& e; q) H0 o6 G; y
  33.         void (*SendBuf)(u8 *buf,u16 len);3 u. {6 J3 e& I6 N* C
  34. }_typdef_net;
    * r  }# G: d# Z

  35. ) `; q8 H! q" [7 l/ G& S3 o3 J
  36. extern _typdef_net _net;
    0 S% z( p9 w  V
  37. - |8 k/ A) H% L) o% {
  38. #endif
    # N4 S: Q$ p! Q" a0 H  h1 N9 u
  39. ) I2 E# b1 U% V: {, p! |
  40. /*********************************************END OF FILE********************************************/
复制代码
4 B0 ]" G8 \- Z+ U7 t- l2 y
mqtt.c部分* H' y9 [! N& P
  1. #include "fy_mqtt.h"
    0 X; ^8 p1 z! ^: K$ J
  2. : h+ _2 n; }! g/ ?4 S9 a
  3. //#define _DEBUG_MQTT0 G: P* e% e3 v) b+ j$ W. V9 m5 E$ }

  4. 8 l9 i% R! A7 L: _% x4 H8 H
  5. typedef enum
    6 K% C( m+ O6 S# K
  6. {8 Q) a- [- L8 A: t. b" y" S
  7.         //名字             值                         报文流动方向         描述3 [; y- b$ B+ D
  8.         M_RESERVED1        =0        ,        //        禁止        保留' v, X! d1 g$ c: L# j: ^2 A
  9.         M_CONNECT                ,        //        客户端到服务端        客户端请求连接服务端
    " B( ]  o2 D, M  o' f$ x9 Z
  10.         M_CONNACK                ,        //        服务端到客户端        连接报文确认
    # _8 [4 }  R2 K
  11.         M_PUBLISH                ,        //        两个方向都允许        发布消息
    ' g. K( P' M( y0 t+ w, U- L! s
  12.         M_PUBACK                ,        //        两个方向都允许        QoS 1消息发布收到确认) }  }  f' x# r9 V, L
  13.         M_PUBREC                ,        //        两个方向都允许        发布收到(保证交付第一步)
    . {, |" w0 _/ C% e2 v7 L# q7 C
  14.         M_PUBREL                ,        //        两个方向都允许        发布释放(保证交付第二步)
    & s, c$ ?; r; v% e) f0 ^. `' R
  15.         M_PUBCOMP                ,        //        两个方向都允许        QoS 2消息发布完成(保证交互第三步)
    8 M' d- w0 P; h0 n
  16.         M_SUBSCRIBE                ,        //        客户端到服务端        客户端订阅请求
    ! _& N8 x+ W/ P/ @  }6 d4 d9 D8 j
  17.         M_SUBACK                ,        //        服务端到客户端        订阅请求报文确认
    - F8 q3 z, H5 H/ D2 i
  18.         M_UNSUBSCRIBE        ,        //        客户端到服务端        客户端取消订阅请求
    ( @8 V+ O4 ]4 B" _" i
  19.         M_UNSUBACK                ,        //        服务端到客户端        取消订阅报文确认9 |$ r3 T0 N' ]' _5 K
  20.         M_PINGREQ                ,        //        客户端到服务端        心跳请求0 d8 i; {" B0 e
  21.         M_PINGRESP                ,        //        服务端到客户端        心跳响应! l4 i7 X3 G+ C1 r/ Y
  22.         M_DISCONNECT        ,        //        客户端到服务端        客户端断开连接
    " Q) d% P5 q: d- k/ d1 {- ^" p
  23.         M_RESERVED2                ,        //        禁止        保留' f$ Z, D! }) q' A1 u4 f
  24. }_typdef_mqtt_message;/ f4 ]$ y7 E9 I+ k8 g; D
  25. ' s" D" f8 a# p4 A- ], C# `) [

  26. ! i2 E* L$ @3 I2 [. B, k7 Q& G2 \

  27. ) j! T8 W6 |2 [: b- D  f
  28. //连接成功服务器回应 20 02 00 00+ G0 W' V+ O7 D( y
  29. //客户端主动断开连接 e0 00
    2 D+ T' U: \3 R' m
  30. const u8 parket_connetAck[] = {0x20,0x02,0x00,0x00};! f+ i, \7 x" f0 Z! o: k; I
  31. const u8 parket_disconnet[] = {0xe0,0x00};1 F0 L* p: {- p. K1 @
  32. const u8 parket_heart[] = {0xc0,0x00};, _* H& c9 R9 b  L9 I: L& E
  33. const u8 parket_heart_reply[] = {0xc0,0x00};- q- ^- \# g* O! C" C4 H7 c, L
  34. const u8 parket_subAck[] = {0x90,0x03};$ U9 A3 V3 O5 i# z

  35. ' L* z3 m3 Q/ F. j0 F( `  O; \: ?
  36. static void Mqtt_SendBuf(u8 *buf,u16 len);& c5 Z5 ?) J" y5 }( N& _8 P
  37. & G/ E8 o7 b3 P/ Q. T: u% I2 U
  38. static void Init(u8 *prx,u16 rxlen,u8 *ptx,u16 txlen);; N( g+ E" ^6 G) F; W
  39. static u8 Connect(char *ClientID,char *Username,char *Password);/ F! r$ j: T+ C% p7 }) L6 H
  40. static u8 SubscribeTopic(char *topic,u8 qos,u8 whether);
    1 w* n6 s- s* |, B
  41. static u8 PublishData(char *topic, char *message, u8 qos);
    : B6 ]4 A/ G1 j7 I: i2 q
  42. static void SentHeart(void);
    0 W8 J$ D, G# K2 r  F$ u* ?" O
  43. static void Disconnect(void);
    ) q: L6 y, c) I( U  j
  44. % d. r1 B) E* X# {5 Y+ z' b
  45. _typdef_mqtt _mqtt = ( C- U* K/ x  E1 w, Q, F! i( p
  46. {
      [( U* p9 V' p' k% y1 @
  47.         0,0,
    / w0 m% d+ m2 D! L" I5 T" D7 g; L5 m
  48.         0,0,
    ; U: m  H, X$ H9 A7 D+ |
  49.         Init,1 p$ r! _5 ~$ s& B6 u+ S0 c' I
  50.         Connect,
    8 G4 }) `' g( ]. w
  51.         SubscribeTopic,) j/ h$ }4 r3 `
  52.         PublishData,
    & P+ I5 j( k9 m
  53.         SentHeart,
    . X" [5 n' e' w% B
  54.         Disconnect,% S$ D' |, S8 ?1 Q
  55. };
    7 h$ I6 s5 ?8 b; F2 |4 D0 b
  56. 0 S  E* w- w3 R' d% j, U
  57. static void Init(u8 *prx,u16 rxlen,u8 *ptx,u16 txlen)4 V* `/ R7 j& ~
  58. {3 l* |2 v$ W! y) {8 ~
  59.         _mqtt.rxbuf = prx;_mqtt.rxlen = rxlen;$ U: d" ?0 t# N2 `% ^4 A7 i8 ^2 ]
  60.         _mqtt.txbuf = ptx;_mqtt.txlen = txlen;
    " j0 i8 B: w% N0 H, G1 ~
  61.         : [) \/ Q3 K2 D) M# Q) i
  62.         memset(_mqtt.rxbuf,0,_mqtt.rxlen);
    3 z0 s" P9 U1 s. j0 q# X
  63.         memset(_mqtt.txbuf,0,_mqtt.txlen);
    . J+ P1 G+ S7 \' L( o, b
  64.         
    % `/ @% W$ ^/ h& N" Q
  65.         //无条件先主动断开* B; [; c$ B3 |$ H* z. h! [" s
  66.         _mqtt.Disconnect();Delay_ms(100);
    ( J, ~# ]& B! F
  67.         _mqtt.Disconnect();Delay_ms(100);
    5 t" K+ A5 S& A- C( t9 |4 j
  68. }
    * k4 i" u  g8 R0 o* p2 ?  P8 T
  69. ( ?' n& R/ M1 P( K" [4 x, t7 L& l
  70. + \) r6 q2 R  ?4 R$ I$ ^
  71. //连接服务器的打包函数
    ) E. E! H3 V  Y+ G6 T
  72. static u8 Connect(char *ClientID,char *Username,char *Password)+ }& j5 g; r0 ]$ Z
  73. {
    $ V$ b8 n/ ^& {' o* a2 l+ G3 \$ z
  74.     int ClientIDLen = strlen(ClientID);
    ( X, ?) t. m" v  J4 {$ |# h
  75.     int UsernameLen = strlen(Username);
    & X; p  g! G$ F5 r
  76.     int PasswordLen = strlen(Password);* e! S; V- B8 @! I
  77.     int DataLen;0 o/ h3 V; b: I" r) A
  78.         _mqtt.txlen=0;; ]6 X" E  M; s" I7 h1 K
  79.         //可变报头+Payload  每个字段包含两个字节的长度标识; c/ n" b& F4 |% ?+ ^+ }
  80.     DataLen = 10 + (ClientIDLen+2) + (UsernameLen+2) + (PasswordLen+2);3 o& b+ E- z# `& G5 m1 y% {
  81.         9 ~' Y1 B/ H8 y3 n
  82.         //固定报头
    1 F+ V9 s3 \/ c' \' u% Y/ W
  83.         //控制报文类型. o& z- N& `2 n2 w/ ~5 d( }
  84.     _mqtt.txbuf[_mqtt.txlen++] = 0x10;                //MQTT Message Type CONNECT. U! S3 v5 H/ u5 b$ P+ q
  85.         //剩余长度(不包括固定头部)
    0 |4 J2 X% i5 n0 Q# @1 U
  86.         do
    & }1 k- b: G  G  {1 ^" B
  87.         {6 w0 J; V- J' ?% i& `6 E/ U' G; ]
  88.                 u8 encodedByte = DataLen % 128;6 g, ]9 o. ]6 d6 d
  89.                 DataLen = DataLen / 128;
    7 o  B1 J, e, G, q/ a3 [8 c  N8 J
  90.                 // if there are more data to encode, set the top bit of this byte( c/ J( m7 w" D+ P  l) H1 S
  91.                 if ( DataLen > 0 )
    ) @. N: H$ |1 U
  92.                         encodedByte = encodedByte | 128;4 h# h% n) X5 B8 ]" K1 C3 G0 c
  93.                 _mqtt.txbuf[_mqtt.txlen++] = encodedByte;' [, ^2 o7 z7 ?
  94.         }while ( DataLen > 0 );+ u- A; A! `- }1 h+ G- b1 p
  95.             3 j* O4 l: w5 M6 q) u
  96.         //可变报头
    ; h8 s5 F* y2 r/ ?+ `
  97.         //协议名  O' j2 h3 M# y% k" {+ R
  98.     _mqtt.txbuf[_mqtt.txlen++] = 0;                        // Protocol Name Length MSB   
    7 I1 }) c! D1 A  V. j4 a% q1 j
  99.     _mqtt.txbuf[_mqtt.txlen++] = 4;                        // Protocol Name Length LSB   
    / w( @+ h7 R* k8 P( \  @% D+ l! B4 B
  100.     _mqtt.txbuf[_mqtt.txlen++] = 'M';                // ASCII Code for M   
    ! s) W1 j  m( s5 L
  101.     _mqtt.txbuf[_mqtt.txlen++] = 'Q';                // ASCII Code for Q    5 n9 W3 ]; i/ W+ C
  102.     _mqtt.txbuf[_mqtt.txlen++] = 'T';                // ASCII Code for T   
    1 O2 F) f9 T& p7 w
  103.     _mqtt.txbuf[_mqtt.txlen++] = 'T';                // ASCII Code for T    * d% [- B0 @' {
  104.         //协议级别
    1 p9 G: Y$ ?( d/ S- J0 f
  105.     _mqtt.txbuf[_mqtt.txlen++] = 4;                        // MQTT Protocol version = 4   
    & S! @( I; q& E* y2 `
  106.         //连接标志
    & {; T' ]" @6 I- S/ I( E6 |
  107.     _mqtt.txbuf[_mqtt.txlen++] = 0xc2;                // conn flags ( k) N* e/ h. k  A% I
  108.     _mqtt.txbuf[_mqtt.txlen++] = 0;                        // Keep-alive Time Length MSB   
    , H: K$ b( F4 ~6 q4 `% q- I) _
  109.     _mqtt.txbuf[_mqtt.txlen++] = 60;                // Keep-alive Time Length LSB  60S心跳包  
    " b6 t" c" g2 L' `$ x5 d# a& _
  110.         
    : G9 ~- w+ J( s7 f7 e! B  i( y# u
  111.     _mqtt.txbuf[_mqtt.txlen++] = BYTE1(ClientIDLen);// Client ID length MSB    3 @# G2 N' C* ^) w9 O
  112.     _mqtt.txbuf[_mqtt.txlen++] = BYTE0(ClientIDLen);// Client ID length LSB          7 P# N' o/ a8 X& a1 {
  113.         memcpy(&_mqtt.txbuf[_mqtt.txlen],ClientID,ClientIDLen);4 K% F& C  V" X9 Z5 ]$ v4 b' H
  114.     _mqtt.txlen += ClientIDLen;5 ~7 ^- J4 d+ R. I# ]" y  W7 U! m

  115. 0 G# ~: M1 G' v
  116.     if(UsernameLen > 0)
    ) G9 `* R$ F  g9 W, C4 l% U/ A
  117.     {   
    % |) w) X6 M; F/ b) N' F
  118.         _mqtt.txbuf[_mqtt.txlen++] = BYTE1(UsernameLen);                //username length MSB    5 N& H* l. k# W3 }* L4 f* W4 Z
  119.         _mqtt.txbuf[_mqtt.txlen++] = BYTE0(UsernameLen);            //username length LSB   
    # x( n  m$ v% k( o' G
  120.                 memcpy(&_mqtt.txbuf[_mqtt.txlen],Username,UsernameLen);2 p( i4 P( X8 Z" c& A7 U4 R
  121.         _mqtt.txlen += UsernameLen;. d9 d# y% y; `$ U  G0 ]1 _
  122.     }
    / t, b6 l9 \9 B

  123. 0 q0 P. [/ H  @5 o$ ]% @
  124.     if(PasswordLen > 0)
    1 }" j- ?* l: u; h* o% A) `! O
  125.     {    ( T$ Z0 A- }3 B$ R% ]. R! x! @
  126.         _mqtt.txbuf[_mqtt.txlen++] = BYTE1(PasswordLen);                //password length MSB    6 x6 Q7 t0 M# M
  127.         _mqtt.txbuf[_mqtt.txlen++] = BYTE0(PasswordLen);            //password length LSB  : O7 ]! K3 i! k5 V* b2 S* ^2 t: Z* c
  128.                 memcpy(&_mqtt.txbuf[_mqtt.txlen],Password,PasswordLen);
    ) ?4 d/ k, y9 w% \
  129.         _mqtt.txlen += PasswordLen;
    : S7 o- V8 a; I4 b% F5 A! G
  130.     }    - u0 b# c3 }$ m% p. ?) \7 ~# f  s
  131.         
    3 t4 x8 W# S' a' i1 I: _& K9 a
  132.         u8 cnt=2;; L9 y: h; n: ~0 X& y$ l& O4 Q9 F
  133.         u8 wait;
    / i7 d7 J: m/ ?, d1 ?: b* G
  134.         while(cnt--)7 l9 v3 t6 T0 P9 [
  135.         {
      \/ K9 `# u; \  \' ^+ v5 W/ h1 {
  136.                 memset(_mqtt.rxbuf,0,_mqtt.rxlen);
    + @. j$ {: u* S$ g1 ^4 O' W
  137.                 Mqtt_SendBuf(_mqtt.txbuf,_mqtt.txlen);$ g( w+ L7 J( R+ x) ~7 M2 ?) ~
  138.                 wait=30;//等待3s时间
    ! ~& \8 m7 P( p# f$ I
  139.                 while(wait--)0 @+ g  K8 X# J  B* J$ m
  140.                 {
    % f9 v7 {! N6 I8 y/ [. X/ V
  141.                         //CONNECT
    ) }* ?8 R( z$ v2 e* M& t
  142.                         if(_mqtt.rxbuf[0]==parket_connetAck[0] && _mqtt.rxbuf[1]==parket_connetAck[1]) //连接成功                           
    ' x+ L  H2 u. E, p: J' p
  143.                         {
      o0 l4 d5 `3 T; W& @
  144.                                 return 1;//连接成功
    3 |! x! T& G' ~! _# d: M; _& @1 Z
  145.                         }# K; p. h8 _+ w' |9 s. ~
  146.                         Delay_ms(100);                        % }! ?& D  L6 K) ^, i) O+ L
  147.                 }
    2 W/ J# l4 {  P3 D; N
  148.         }0 q+ U3 j2 i5 _0 V
  149.         return 0;3 |4 m) I: |; ?$ }
  150. }; ^$ }- S# {2 o2 n5 v/ J

  151. 4 Y# m9 x5 ?( z$ s  G; _
  152. ; L: x/ m9 @! Y) Y" J
  153. //MQTT订阅/取消订阅数据打包函数& ^; o5 h' ]8 F  Q4 }+ S
  154. //topic       主题 * G' P# v+ c/ \/ L  S
  155. //qos         消息等级 3 m) g8 i$ M! W3 {" ~
  156. //whether     订阅/取消订阅请求包! W( r/ R+ x+ F  _/ |1 @# h7 W% B
  157. static u8 SubscribeTopic(char *topic,u8 qos,u8 whether)
    7 s; a/ i" }1 x. F0 n
  158. {   
    & u( x8 X4 m# q7 J& H0 c) G! R
  159.         _mqtt.txlen=0;
    ; n* K5 c9 a. C+ t) R+ ^/ {4 w; G
  160.     int topiclen = strlen(topic);
    : t) Q, z% M: \
  161.         
    0 k( a% V  _; i$ B9 y2 h
  162.         int DataLen = 2 + (topiclen+2) + (whether?1:0);//可变报头的长度(2字节)加上有效载荷的长度
    * b: J1 r9 R' C& q" {! r+ B
  163.         //固定报头4 y% m. _% t# O. Q" H$ O6 ]9 a+ e
  164.         //控制报文类型
    / e. ]2 L/ P3 v- t3 _5 G
  165.     if(whether) _mqtt.txbuf[_mqtt.txlen++] = 0x82; //消息类型和标志订阅
    - s0 R: q& U- d8 g# d* ]
  166.     else        _mqtt.txbuf[_mqtt.txlen++] = 0xA2;    //取消订阅- ?5 B' I, T$ {
  167. 7 ~8 m' O4 M3 H' l/ o
  168.         //剩余长度8 ~! y2 m* I) P0 s, `" q) |
  169.         do
    ) j. M. ^3 o& v3 @
  170.         {
    " c' @4 q8 i# s( v: Y
  171.                 u8 encodedByte = DataLen % 128;4 Q  w% z, x# ^- _
  172.                 DataLen = DataLen / 128;) V5 z7 T. L1 [2 C. S2 p
  173.                 // if there are more data to encode, set the top bit of this byte
    , K, ^* v) {! j! C% m- k
  174.                 if ( DataLen > 0 )$ G/ x2 c& o9 i+ [4 z
  175.                         encodedByte = encodedByte | 128;
      A1 Q) @9 @( k1 T6 r
  176.                 _mqtt.txbuf[_mqtt.txlen++] = encodedByte;8 D& q& @- O6 T# i
  177.         }while ( DataLen > 0 );        / F$ N, [, \- R% j
  178.         : n; d7 o! C1 H9 @8 q* y2 O( j
  179.         //可变报头. A' Q5 C0 t& @' X* y
  180.     _mqtt.txbuf[_mqtt.txlen++] = 0;                                //消息标识符 MSB
    8 q* I5 O  L" r& y5 b
  181.     _mqtt.txbuf[_mqtt.txlen++] = 0x01;           //消息标识符 LSB
    5 G/ B7 p$ ]- x4 I, ]
  182.         //有效载荷
    # P+ @8 C2 k  j+ F0 `0 h
  183.     _mqtt.txbuf[_mqtt.txlen++] = BYTE1(topiclen);//主题长度 MSB
    0 Q- f; ]1 \2 m! c$ e5 k5 F8 S
  184.     _mqtt.txbuf[_mqtt.txlen++] = BYTE0(topiclen);//主题长度 LSB   " a7 Q" P9 ^2 o# Z) Q- |* C& e
  185.         memcpy(&_mqtt.txbuf[_mqtt.txlen],topic,topiclen);
    - y  o9 T/ l( I6 f+ d$ ~: {
  186.     _mqtt.txlen += topiclen;
    $ p+ _& h# W2 n/ ~1 U3 h
  187. ; v) a! k: r6 s$ \
  188.     if(whether)) H! i& F5 C( e/ I6 D1 R, e
  189.     {
    $ K5 S' f) h5 }) M; W' J- j
  190.         _mqtt.txbuf[_mqtt.txlen++] = qos;//QoS级别1 x2 O5 X1 Y( o' }8 Q9 }
  191.     }* G: }8 O2 @+ q7 P& {" {( K
  192.         
    0 C; u1 {# w+ j0 E
  193.         u8 cnt=2;
    # w5 Z; X. V; t3 T$ J
  194.         u8 wait;
    # [6 u; |. d& r3 w
  195.         while(cnt--)
    6 T9 V5 h5 p+ P' W
  196.         {+ ], ~* B6 y2 ]) b2 b4 n. r
  197.                 memset(_mqtt.rxbuf,0,_mqtt.rxlen);
    ) Y. z2 l6 c% D$ p7 Q
  198.                 Mqtt_SendBuf(_mqtt.txbuf,_mqtt.txlen);# I% N# f0 I7 A  E/ M- L5 G; X
  199.                 wait=30;//等待3s时间
    0 j/ F0 }2 _! w9 v0 J
  200.                 while(wait--)
    3 R* A6 W/ B- I" s7 k7 ?
  201.                 {
    , R& _2 _: A$ a% ?( H# `% B
  202.                         if(_mqtt.rxbuf[0]==parket_subAck[0] && _mqtt.rxbuf[1]==parket_subAck[1]) //订阅成功                           
    . d9 d4 y8 k& X* I) R0 G
  203.                         {3 z3 e, O. E3 J: Z
  204.                                 return 1;//订阅成功
    , _2 n' K  ^! b
  205.                         }
    % Z! [/ T5 e9 k
  206.                         Delay_ms(100);                        5 h( @4 N- x- V+ u0 o* o
  207.                 }) F3 x6 _# \+ m# H7 ~
  208.         }
    ( L: Q, \  |; H1 @9 I" w& K
  209.         if(cnt) return 1;        //订阅成功6 o6 G0 d2 I0 y4 e* l
  210.         return 0;
    6 {  c5 o. J  a
  211. }
    1 M' b& x3 _# l1 ?& h

  212. 3 j! k0 V% U$ `. O- i* y, G
  213. //MQTT发布数据打包函数6 {" V& J2 y# ?" y7 n1 o0 e
  214. //topic   主题 $ E5 O/ |" G" x8 W, R
  215. //message 消息
    1 K/ }5 b! s/ l8 \- s
  216. //qos     消息等级 1 z; {% Z6 S9 }2 d# j, x% z. X
  217. static u8 PublishData(char *topic, char *message, u8 qos)
    6 H2 t/ S! k1 T" d2 c0 l7 Q2 c, h
  218. {  
    , n& M" S8 k( \7 x1 t* }  C6 x
  219.     int topicLength = strlen(topic);    % P  U& k+ f/ i! K# A
  220.     int messageLength = strlen(message);     
    & W# {/ ]" T" `1 u
  221.     static u16 id=0;
    ! B$ S3 @  b9 D
  222.         int DataLen;
    ; I( ?( N/ U: }9 b1 X
  223.         _mqtt.txlen=0;6 F+ K6 Z9 |. }2 Q; Z
  224.         //有效载荷的长度这样计算:用固定报头中的剩余长度字段的值减去可变报头的长度
    / m9 o6 `. [: s; j" ]
  225.         //QOS为0时没有标识符
    ; N3 p8 L' l7 z  U1 Z7 X5 Z
  226.         //数据长度             主题名   报文标识符   有效载荷# q% R# z( a' U: O1 J( C# ^+ O
  227.     if(qos)        DataLen = (2+topicLength) + 2 + messageLength;       / C8 ?- D8 x7 k; ]7 d4 [
  228.     else        DataLen = (2+topicLength) + messageLength;   ' r" [. G; _3 b( \! x4 A" k
  229. . D  B1 o4 b5 ]: {' J" A: _
  230.     //固定报头  B3 Y( U7 V$ e+ z, z- x9 x: b
  231.         //控制报文类型
    7 d9 V4 g: W$ r' ]) S
  232.     _mqtt.txbuf[_mqtt.txlen++] = 0x30;    // MQTT Message Type PUBLISH  
    0 X6 I1 r1 u( w+ a' j/ y7 g
  233. ' F1 d8 f: i+ s2 K
  234.         //剩余长度/ o' N9 h4 a9 e" _9 k3 N
  235.         do
    2 E' t4 B- Q, _: L
  236.         {
    ) ?& o! s) F7 c: d# `
  237.                 u8 encodedByte = DataLen % 128;
    9 V: l8 h0 X. @
  238.                 DataLen = DataLen / 128;4 @$ O5 U, b. h' w7 ?$ n/ @
  239.                 // if there are more data to encode, set the top bit of this byte6 o* N4 ?4 P& z/ d" H0 p0 G
  240.                 if ( DataLen > 0 )
    + a! s" z' b$ [& T2 {# u! Z
  241.                         encodedByte = encodedByte | 128;
    5 M* n3 B7 ^, B7 G2 t
  242.                 _mqtt.txbuf[_mqtt.txlen++] = encodedByte;
    ( u# P; N- ~% c* Q' l) Q& Y: j
  243.         }while ( DataLen > 0 );        
    4 r! `. I5 f* @9 l
  244.         
    9 w2 K- l. |( G* w
  245.     _mqtt.txbuf[_mqtt.txlen++] = BYTE1(topicLength);//主题长度MSB1 g# r5 {0 f! t- a( F) b. h4 w
  246.     _mqtt.txbuf[_mqtt.txlen++] = BYTE0(topicLength);//主题长度LSB 9 |9 @& v, G: @* h$ w
  247.         memcpy(&_mqtt.txbuf[_mqtt.txlen],topic,topicLength);//拷贝主题
    - k# X  @& r- S5 n6 W5 e) r
  248.     _mqtt.txlen += topicLength;
    3 ^0 r. \( O4 K% o6 }$ c
  249. & C& r* I" ]! V) I$ r  h
  250.         //报文标识符1 `  O8 H3 y/ W% A5 P4 K! L
  251.     if(qos)8 h# P( e( U( H$ f9 B1 K3 ]
  252.     {
    2 f0 u2 w1 L% L1 m
  253.         _mqtt.txbuf[_mqtt.txlen++] = BYTE1(id);
    + f8 f# I  ~: X3 [2 O5 `! v
  254.         _mqtt.txbuf[_mqtt.txlen++] = BYTE0(id);2 g- ?0 J( R0 _) o/ v3 h
  255.         id++;. B2 b5 j3 d  L1 U5 q' c' p
  256.     }
    ) O7 c$ @+ t" W/ e6 ?5 E# g
  257.         memcpy(&_mqtt.txbuf[_mqtt.txlen],message,messageLength);
    ) j$ g8 F) r& v& j0 D8 k+ b8 B
  258.     _mqtt.txlen += messageLength;
    / e* l! [) J' t
  259. 7 ~8 P( @  ~/ R/ X
  260.         Mqtt_SendBuf(_mqtt.txbuf,_mqtt.txlen);
    . I& R6 ^" U) h: _2 Y* R
  261.     return _mqtt.txlen;+ E) ?9 J; H0 Y' T2 G& D4 h7 |7 W6 F
  262. }
    ; l: Y" U' @) e

  263. 7 E1 ^# E% {) d& T. G
  264. static void SentHeart(void)
    . w3 A6 ^% ^, v; g, F) f/ |+ y
  265. {
    3 Q* p2 w8 V5 f* f. k5 g
  266.         Mqtt_SendBuf((u8 *)parket_heart,sizeof(parket_heart));  B3 |9 M1 `& ^, [' E2 V
  267. }
    5 `7 O& u" f9 _6 `$ C/ p, A) d
  268. / g' ?+ |0 ^$ \: K
  269. static void Disconnect(void)
    ( k  U1 ]4 V6 h$ P
  270. {: m9 Q3 t2 G4 O, o; h
  271.         Mqtt_SendBuf((u8 *)parket_disconnet,sizeof(parket_disconnet));$ Q0 ^; \$ F* W) w
  272. }, o  t1 G) V+ _8 ]- [7 o9 |- T

  273. 7 M# h' y& e5 [; c5 X$ f! t$ Q
  274. static void Mqtt_SendBuf(u8 *buf,u16 len)1 x  M  \% c$ d
  275. {5 F( t: }- k7 e
  276.         #ifdef _DEBUG_MQTT
    ) o: v* O- J) ^# q  U+ n+ Q
  277.         Usart1_SendBuf(buf,len);: i9 N9 N) \6 A
  278.         #endif% s5 j( F* m8 }9 X$ S- ]# |
  279.         Usart2_SendBuf(buf,len);1 B. K! N9 m9 l! q( K% c
  280. }        
    " O! t& R/ P2 Z4 J
  281. 4 v+ m) u# B  ~) a
  282. /*********************************************END OF FILE********************************************/
复制代码

  m/ `7 k6 E  R8 X$ I, smqtt.h部分* \/ x& ?* P, h& ~4 v6 S2 Q; T# {
4 J. _1 M. p, x! o
  1. #ifndef __FY_MQTT_H_3 O. F# P! J" P& P/ x  d- m2 P
  2. #define __FY_MQTT_H_
    " d7 p! S1 v! r4 F9 m
  3. 7 F) z( E  I5 e# s/ O
  4. #include "fy_includes.h"# k/ g3 f' k( F4 r- A

  5. 6 U% y, a8 G; X
  6. 7 K& j, H8 s1 K% ?0 {

  7. 3 Z  I. m- {3 v; L5 L: d3 `
  8. typedef struct' \4 y* T1 h; U9 Q) ]
  9. {8 L. f" d  p5 }1 G- p. ~0 t& m# I
  10.         u8 *rxbuf;u16 rxlen;
    : {, ], F2 {; s, U6 `4 p% C
  11.         u8 *txbuf;u16 txlen;5 A' h9 J5 A0 u0 X
  12.         void (*Init)(u8 *prx,u16 rxlen,u8 *ptx,u16 txlen);
    4 }. C: F' N9 {: p
  13.         u8 (*Connect)(char *ClientID,char *Username,char *Password);
    " c. H! z( H3 Y+ e
  14.         u8 (*SubscribeTopic)(char *topic,u8 qos,u8 whether);  U) ~3 b4 B4 {4 [1 ?# L1 n, n
  15.         u8 (*PublishData)(char *topic, char *message, u8 qos);( ^6 l- C2 y9 f& q% E- g7 |3 W7 J) x
  16.         void (*SendHeart)(void);
    6 l- F; _) f  u
  17.         void (*Disconnect)(void);
    & g% k" ?& K" n4 X# V6 o
  18. }_typdef_mqtt;
    4 a9 ?& Q& @+ u! e  S9 p' W
  19. 7 ]5 j- {: k4 k/ I
  20. extern _typdef_mqtt _mqtt;  B& t9 q5 u1 V2 X3 ]# X
  21. 7 p: S& p: b7 t8 I7 W/ u( y7 ~
  22. #endif
复制代码

1 k& X- y+ `: B1 R8 P5 a, l+ ?, l- w5 ~* r" f0 D* g
6 T, ~$ p# c$ x5 p" a
4 i% Y, t' w1 y8 ?/ P3 L3 q
  R1 w8 g0 F) G" W3 d& l; m+ l
赞 收藏 评论0 发布时间:2022-3-16 11:31

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版