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

【经验分享】STM32F1内部FLASH读写例程

[复制链接]
STMCU小助手 发布时间:2021-11-27 09:29
1、环境

STM32F107RC核心板 + Atollic TrueStudio + Win8.1

2、STM32F1系列单片机分类

打开参考手册第三章,可以获知:不同储存容量的单片机有不同的FLASH分布,而主要分为以下几类。1、low-density,2、medium-density,3、high-density,4、connectivity line。我们需要根据使用的单片机容量,确认其FLASH分布。

下图中,Table 3是STM32F107RC规格书上的关于兼容性的描述。从这里以及规格书上文描述,我们可以知道:

STM32F107RC属于connectivity line。


4 h' T0 B5 O. B# F& D$ N+ C; q1 R0 D+ a- `; t( O8 Y) U

3、硬石STM32F1开源的源代码3.1 stm32f107_flash.c
  1. /**
    ( h# {. d9 P1 Y; W7 k. m1 t
  2.   ******************************************************************************+ b& N* B* b& K: f
  3.   * 文件名程: stm_flash.c 6 T0 q, z: w: W% t7 _/ Q4 Y
  4.   * 作    者: 硬石嵌入式开发团队
    ) |. P2 V4 d9 Y, I
  5.   * 版    本: V1.0
      V) ~4 H& i8 w. }7 O  ]; F
  6.   * 编写日期: 2015-10-04, I  e+ z0 Q4 U. Y
  7.   * 功    能: 内部Falsh读写实现
    , u3 Z5 X8 K2 W$ N; ^5 b8 p
  8.   ******************************************************************************- _8 |% ^4 ?0 R9 M7 I& B/ U5 \
  9.   * 说明:
    * s+ Z) t- D( X: s( H' |
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。/ B, [5 }% s* L# A! c4 S
  11.   * ' c+ P& h! l% C0 z; }7 n8 z" R
  12.   * 淘宝:/ E+ g# F3 y" g9 y9 B
  13.   * 论坛:http://www.ing10bbs.com
    5 ^, }- s9 k1 L7 K5 z6 h
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
    * A2 O% \4 p: r& O9 X4 G
  15.   ******************************************************************************
    8 D$ a& ]1 e. M% m
  16.   */0 E1 H# ]0 |" U1 D7 Y
  17. /* 包含头文件 ----------------------------------------------------------------*/" `' R8 ?# ~9 b( \* Q" V* s
  18. #include "stm32f107_flash.h"$ o+ B1 V, P" u0 Q5 m1 h* k
  19. ( P2 U, p/ f6 m( r, i
  20. /* 私有类型定义 --------------------------------------------------------------*/
    / v# v( y9 F- C! t1 g2 a) U
  21. /* 私有宏定义 ----------------------------------------------------------------*/# ^. A- z+ c; C4 u5 X* p
  22. #if STM32_FLASH_SIZE < 256
    9 \# y& L, {7 o9 D
  23.   #define STM_SECTOR_SIZE  1024 //字节
    - f9 p7 c7 e6 V- T/ a) L  \% }
  24. #else 6 k2 N* L+ t. y' `+ s: @6 s
  25.   #define STM_SECTOR_SIZE         2048, Z0 n- Z  j6 v9 w) ?) k
  26. #endif
    . K$ o! v' E) F5 l1 i

  27. & @6 N$ Q& U' u6 {8 H0 X0 a* l5 D& W
  28. 4 _3 @/ d, u) n$ r0 {( V5 h
  29. /* 私有变量 ------------------------------------------------------------------*/
    0 }2 {' _+ s# e, Z4 ^# i
  30. #if STM32_FLASH_WREN        //如果使能了写
    # e! \/ b* @) j! r/ Q
  31. static uint16_t STMFLASH_BUF [ STM_SECTOR_SIZE / 2 ];//最多是2K字节* b5 d% A; i1 `; k! Z6 q
  32. static FLASH_EraseInitTypeDef EraseInitStruct;
    8 e* y1 s7 j0 J
  33. #endif
    ! @$ s( V& x% f- {3 r' l

  34. - f" [3 m! o1 R) m& b
  35. /* 扩展变量 ------------------------------------------------------------------*/
    8 v* ?* X9 h1 T# f
  36. /* 私有函数原形 --------------------------------------------------------------*/3 G' Z! v; Y: A6 A, |
  37. /* 函数体 --------------------------------------------------------------------*/
    0 H3 I+ b7 c3 G8 q2 w
  38. /**8 |: \% x% ?4 }, }
  39.   * 函数功能: 读取指定地址的半字(16位数据)
    5 _' s# }) Y/ r+ z) k/ P! p
  40.   * 输入参数: faddr:读地址(此地址必须为2的倍数!!)0 d$ j. x0 q8 f$ l$ i7 p5 Q
  41.   * 返 回 值: 返回值:对应数据.
    & G8 m: w% b$ o; @- k& E  Y& Q
  42.   * 说    明:无" O) D8 a, b: j; Z% y  j' U
  43.   */' ~2 K+ t/ [, }1 a+ A+ ?, ?7 \
  44. uint16_t STMFLASH_ReadHalfWord ( uint32_t faddr )
    6 p" Q1 c* R" P2 ?( m
  45. {
    ; ^. w; y3 A- b
  46.         return *(__IO uint16_t*)faddr;
    5 C9 R7 K2 s4 m* n& Y6 [
  47. }, f: \+ d, W7 A8 K4 B

  48. 3 t7 n* l& N* a1 \$ m. Y4 c5 D7 k9 T
  49. #if STM32_FLASH_WREN        //如果使能了写   ) N; x, Q/ B3 m3 i4 t! Y/ C" U
  50. /**
    1 b" h* n/ ?, S8 |7 i' s
  51.   * 函数功能: 不检查的写入' C; s6 r1 r) E, V4 y
  52.   * 输入参数: WriteAddr:起始地址
    & J5 d; x0 v8 u& P" o
  53.   *           pBuffer:数据指针
    4 }) d: b* k2 [/ H% M' E5 Q
  54.   *           NumToWrite:半字(16位)数
    3 ~2 ]7 @9 A( r# u8 f
  55.   * 返 回 值: 无
    " O1 Q+ [( G/ v
  56.   * 说    明:无
    , {4 u. ^7 M6 T' B! q
  57.   */& q' k- e' t0 p, m( _
  58. void STMFLASH_Write_NoCheck ( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite )   4 }: l6 f% r3 m: V, A/ @1 S
  59. {                                           + i. _( [' l3 e" c( }* c2 }" t
  60.   uint16_t i;
    , R9 D( ?8 I9 |3 ^$ o- T% `
  61.        
    9 ]' d# m/ O" e4 w
  62.   for(i=0;i<NumToWrite;i++)0 x- y1 ~, n3 i5 n# v8 g
  63.   {
    8 y) ?) j5 E& r7 `, @1 \
  64.         HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,WriteAddr,pBuffer[i]);
    6 C+ u! y" g: j. J8 k+ y5 l3 p
  65.         WriteAddr+=2;                                    //地址增加2.  T3 g8 W  i& T' ]4 \9 \
  66.   }
    6 G2 d1 Q9 a/ ~. A1 A/ J2 c/ k
  67. } 4 ^) S7 J) D" [! }

  68. 7 G9 |; _: w$ Q- }
  69. /**
    # ]1 _* i& |" G
  70.   * 函数功能: 从指定地址开始写入指定长度的数据4 k3 |% l6 Q9 \8 B0 f
  71.   * 输入参数: WriteAddr:起始地址(此地址必须为2的倍数!!)
    % o+ B4 r9 v( P
  72.   *           pBuffer:数据指针
    , R$ l( [0 j+ ?1 F8 |7 E: K* k" R8 {
  73.   *           NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
    6 V1 R$ k+ P0 X" R, P" A! s' a
  74.   * 返 回 值: 无4 Q7 z" E; M. L" X% N5 O
  75.   * 说    明:无& F/ G5 j/ ~/ r7 U# L6 R5 C2 b
  76.   */
    & m4 Q: u' J6 ?' |2 H& {. ?$ i3 b  k
  77. void STMFLASH_Write ( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite )        " B; }0 Y( O8 j/ o  c( ~) Y
  78. {
    , G$ O% O( c: w0 h
  79.   uint32_t SECTORError = 0;
    0 J2 e% f# j! N6 l0 k8 B3 h& h; E
  80.   uint16_t secoff;           //扇区内偏移地址(16位字计算)
    # P% V: d* G1 F% F1 H% d1 N
  81.   uint16_t secremain; //扇区内剩余地址(16位字计算)
    . L% f# w7 o; H- F/ D4 v$ u
  82.   uint16_t i;
    ; o2 [& h/ Q$ S9 G! r* X/ ?7 o
  83.   uint32_t secpos;           //扇区地址
    / r7 ~7 e3 P' |8 O3 ?* O. d! G# D; H
  84.   uint32_t offaddr;   //去掉0X08000000后的地址+ u! V6 L. O3 Z
  85.         + o; @9 _, Z( T2 p4 K4 g! N
  86.   if(WriteAddr<FLASH_BASE||(WriteAddr>=(FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
    1 N/ L) G& |0 l8 E
  87.        
      v, W- x1 i, B" B$ Z
  88.   HAL_FLASH_Unlock();                                                //解锁
    + F3 ^) e6 ~7 J( l. A$ T+ u8 t
  89.         ! k% O# X0 Q+ U- |; c. Y
  90.   offaddr=WriteAddr-FLASH_BASE;                //实际偏移地址.
    . F3 v% s4 o  u  v% ~5 ^# h
  91.   secpos=offaddr/STM_SECTOR_SIZE;                        //扇区地址  0~127 for STM32F103RBT6
    ) M' M( y6 k% k' D+ [# w! C
  92.   secoff=(offaddr%STM_SECTOR_SIZE)/2;                //在扇区内的偏移(2个字节为基本单位.)
    0 C8 D0 i% f: w$ n* F4 |
  93.   secremain=STM_SECTOR_SIZE/2-secoff;                //扇区剩余空间大小
    ) s1 @* l$ R# Y% w! c
  94.   if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围0 B7 g4 C1 F) s& e' u! f
  95.         / b# U# z2 j/ S) v5 A
  96.   while(1)
    0 ~' e0 y! }4 l% ^5 v5 b
  97.   {& q; w4 A5 n4 Q5 @4 w0 k
  98.         STMFLASH_Read(secpos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容6 S/ R1 b& e) F7 l, d. D
  99.         for(i=0;i<secremain;i++)//校验数据
    $ l/ }) Z5 ~) G8 v3 J3 Y
  100.         {
    - K6 }  c5 B2 G7 d; q( m1 h
  101.           if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除
    0 h! z3 ?* {" ]( l' g
  102.         }
    ) B" e0 ~% g9 n
  103.         if(i<secremain)//需要擦除
    ( E5 y# x' c  F- Y* i/ u
  104.         {# K; A6 R5 j" Y2 O7 S
  105.           //擦除这个扇区3 ?1 \: r: r6 U, |  A/ C- }
  106.           /* Fill EraseInit structure*/
    7 Y( Y* Z3 ~# Q( T' @( N
  107.       EraseInitStruct.TypeErase     = FLASH_TYPEERASE_PAGES;; b; n% I; l/ E4 }( I5 u
  108.       EraseInitStruct.PageAddress   = secpos*STM_SECTOR_SIZE+FLASH_BASE;
    1 m' i) i4 h6 z2 B+ @
  109.       EraseInitStruct.NbPages       = 1;
    , G- P) B6 Y7 Z4 K
  110.       HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);
    $ O- ]+ M. k; B6 U4 X& a* H
  111. 9 z' ~5 ?6 u" U9 F) o, ~" R
  112.       for(i=0;i<secremain;i++)//复制
    " \8 e0 _. y2 ^5 ^
  113.       {0 g- g' \  [8 `; X
  114.             STMFLASH_BUF[i+secoff]=pBuffer[i];
    2 g. a& z" F! m6 w8 o
  115.       }3 e8 \; p4 y7 Y* R% K% b% s
  116.       STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区7 B' p5 i6 [  e
  117.         }; ?, Q/ N! c3 G& a+ Y4 q
  118.     else7 H* U7 j: [  E. n; G
  119.     {
    6 ^. _3 y8 f, {/ n! `& e4 I# ?
  120.       STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.                                    . `9 t  n- ^" Y3 u- ^" b/ O; y
  121.     }0 A* |% G/ A# k* H1 S
  122.     if(NumToWrite==secremain)break;//写入结束了- I) W4 p. n2 O+ }9 V, K, J) O
  123.     else//写入未结束
    2 P9 C" C, I  U- @/ \- }
  124.     {. s# f3 b. {5 |8 R9 A" m+ w
  125.       secpos++;                                //扇区地址增1" w- f6 h7 D4 m# y# ~/ N
  126.       secoff=0;                                //偏移位置为0
    * K0 ?/ l" {& o) F1 {# x$ s0 [# t8 h
  127.       pBuffer+=secremain;          //指针偏移
    0 s% W# ]0 A+ \; n
  128.       WriteAddr+=secremain;        //写地址偏移
    ; X# K9 T0 W1 L/ u% Q% x
  129.       NumToWrite-=secremain;        //字节(16位)数递减
    ! ~( f3 t8 h) h; O
  130.       if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
    : k; p, s* S; w0 w1 o
  131.       else secremain=NumToWrite;//下一个扇区可以写完了
    7 z0 K! f) F, \$ O" g' `9 \
  132.     }
    4 ~( O7 Q4 x( u) i: R* u
  133.   };+ b( Q$ n0 I1 _5 U) V
  134.   HAL_FLASH_Lock();//上锁
    + o* U% I$ c* m- ?
  135. }
    3 Q2 i# ?; Y  \) B/ K( I
  136. ' j7 F9 K! g, W" V
  137. 4 c: L) u1 u6 z4 M0 \2 F9 K
  138. - `. [+ T2 b& t! O+ d( Y& u: s
  139. #endif/ H3 A( s2 x) }9 x1 n5 D& v

  140. 3 g, f" O4 J; D% F1 t1 L
  141. /**- S/ o4 g) O, q4 N2 _7 |
  142.   * 函数功能: 从指定地址开始读出指定长度的数据7 S& @7 [1 A3 F) s% A/ y
  143.   * 输入参数: ReadAddr:起始地址
    * H; [$ Q& n9 O5 l
  144.   *           pBuffer:数据指针
    ( }, F9 `0 {* h9 B
  145.   *           NumToRead:半字(16位)数
    % J2 k  d2 D2 f- [4 H" E" b
  146.   * 返 回 值: 无; [! V9 D+ Y3 O" L) S
  147.   * 说    明:无% u: F3 k5 f/ V: ?9 E
  148.   */
    ; j& @2 Q" D8 {# A( e
  149. void STMFLASH_Read ( uint32_t ReadAddr, uint16_t *pBuffer, uint16_t NumToRead )           * h* O* J( l% K" H. H; @7 i
  150. {
    9 G" ]$ J6 G/ ~! N% W' C
  151.   uint16_t i;
      C. n/ h1 q9 O, h; ]2 q2 M+ n+ p
  152. 4 m4 x' f. E- P
  153.   for(i=0;i<NumToRead;i++)$ U# t0 r5 k/ \/ Z. N1 v
  154.   {. d8 M/ F0 D8 j3 W0 {% {: r3 U
  155.         pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
    2 V* U; v) J% d  p& s& N
  156.         ReadAddr+=2;//偏移2个字节.) O, J' W" e8 U. J3 Y4 \1 `" u( m8 G
  157.   }: ^+ k1 c# v3 _0 E; K: i8 y
  158. }$ S7 v$ v2 j8 L$ V
  159. : ]6 x; e2 R7 R+ I5 i
  160. /*
    . y8 a# W  ?6 W( H4 P( O
  161. * 函数名:Buffercmp! d& n& G) K3 m( P
  162. * 描述  :比较两个缓冲区中的数据是否相等
    ; k0 |, n% h( C- B$ B8 v( N
  163. * 输入  :-pBuffer1     src缓冲区指针# x9 X: U: M; i, L2 p
  164. *         -pBuffer2     dst缓冲区指针
    6 a% p- v7 o- a, O7 `
  165. *         -BufferLength 缓冲区长度
    / [- T3 a3 i' e
  166. * 输出  :无
    2 ^  j. w& s. Q! m2 G9 G4 L
  167. * 返回  :-PASSED pBuffer1 等于   pBuffer2
    - \0 \8 f0 S( Z: e) W& g: e1 R' I/ H
  168. *         -FAILED pBuffer1 不同于 pBuffer2/ d6 F/ ?0 d" m% c
  169. */; i2 g4 A/ G3 J7 K6 Q
  170. TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength)+ i& y5 ~: L" N( E- G, O
  171. {) f9 p3 R3 D- ?+ c- G0 E
  172.   while(BufferLength--)# t7 c1 h& H. x8 F8 \( k& F" j% @
  173.   {
    0 P0 k* I- `- P
  174.     printf("data:%d - %d \n",*pBuffer1 , *pBuffer2);; ]& T  T; ?, A( i, e- w# j
  175.     if(*pBuffer1 != *pBuffer2)
    2 `+ D2 ^/ ~  L
  176.     {
    6 o8 S8 O1 k% u" V( d5 n
  177.       return FAILED;3 P  y9 v8 ?0 C7 t+ s8 K
  178.     }+ A1 I" i$ u$ J8 i

  179. 0 n( `. g5 M: P
  180.     pBuffer1++;
    0 O. R3 l$ ?3 F0 D' _/ k5 b7 |
  181.     pBuffer2++;
    % T& _& {9 y8 x4 ^2 V
  182.   }
    % r. J% g6 @+ N7 M1 _! G
  183.   return PASSED;3 O8 D2 u, [5 X9 Y! x5 f
  184. }
      O+ C8 U- `  v9 M1 N; j$ |1 ?
  185. : @* v, Z, ^1 i7 X5 J

  186. , {) y$ i- H' a7 b# n
  187. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码

3 t* h2 C  y  ?" t; C3.2 stm32f107_flash.h
  [5 s2 f4 h4 ^# a2 }5 |+ q; w* t
  1. #ifndef __STMFLASH_H__8 |* R' {0 q4 |2 h, v0 d4 [
  2. #define __STMFLASH_H__! [1 F! s( n& i' C  ^" o9 u, `

  3. 2 T$ B1 h( t( c* l# D7 ?) c
  4. /* 包含头文件 ----------------------------------------------------------------*/
    * R/ R% o- J& W) d( t3 |
  5. #include "stm32f1xx_hal.h"& L; b0 ]: `7 X6 M" g4 B

  6. 5 X3 `4 V3 u* W! ^/ V4 V. b
  7. /* 类型定义 ------------------------------------------------------------------*/
    - X8 w8 z4 e6 T9 T* R9 v$ a& [
  8. /* 宏定义 --------------------------------------------------------------------*/, `, k" p  \+ o5 L- g
  9. /************************** STM32 内部 FLASH 配置 *****************************/
    2 B7 \! g# z* D2 [7 [* V0 x, |
  10. #define STM32_FLASH_SIZE        256  // 所选STM32的FLASH容量大小(单位为K)6 ~2 h1 z( R/ S/ U7 q( I' e$ c
  11. #define STM32_FLASH_WREN        1    // stm32芯片内容FLASH 写入使能(0,禁用;1,使能)
    - r& H6 T$ C/ R
  12.   ~' k! f- h0 t
  13. typedef enum( K8 [9 ^9 ?; a
  14. {
    * R* a% F9 x4 \! h' a, r
  15.   FAILED = 0,9 v- j) C9 c& M" M6 v
  16.   PASSED = !FAILED5 M7 g# W9 A. X3 F# o* E: F6 P' M. {8 g$ k
  17. }TestStatus;
    3 b2 r) D* z' P) ~
  18. ' r& o! K6 `' u. d
  19. #define  FLASH_WriteAddress     0x0803F800            // 写在靠后位置,防止破坏程序
    $ A0 E- _. s; f3 T; ~2 n1 U5 l: C5 R
  20. #define  FLASH_ReadAddress      FLASH_WriteAddress
    9 K+ [2 {* _8 B5 l6 k1 ~1 W* {$ f
  21. #define  FLASH_TESTSIZE         512                 //实际是512*2=1024字节
    / K5 K: A# E/ y0 k. Z5 l, m
  22.   o" m& N% d8 n' _
  23.   w( H1 G  K. [1 H- v
  24. /* 扩展变量 ------------------------------------------------------------------*/% L+ @! \+ Z$ M$ f
  25. /* 函数声明 ------------------------------------------------------------------*/
    4 T  V9 ?4 Q5 c* M$ Z
  26. uint16_t STMFLASH_ReadHalfWord(uint32_t faddr);                  //读出半字
    " X  v8 _, `7 E) G

  27. 8 r' ]  Q" B& `* Y7 @
  28. void STMFLASH_WriteLenByte(uint32_t WriteAddr, uint32_t DataToWrite, uint16_t Len );              //指定地址开始写入指定长度的数据3 c, w* a, [5 U, G8 [! f" l
  29. uint32_t STMFLASH_ReadLenByte(uint32_t ReadAddr, uint16_t Len );                                                                    //指定地址开始读取指定长度数据
    / ^5 F0 g4 Z( F, q8 |
  30. void STMFLASH_Write( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite );                //从指定地址开始写入指定长度的数据' b, m% `' H0 {3 O9 B8 q( z7 t7 s
  31. void STMFLASH_Read( uint32_t ReadAddr, uint16_t * pBuffer, uint16_t NumToRead );           //从指定地址开始读出指定长度的数据
    ( G' {9 ?. e6 u
  32. //static TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength);
    / W; @1 ~" M2 H' ^
  33. TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength);
    8 z4 ^6 ^5 o  [: V

  34. 4 O6 ~5 p+ }4 n  r6 K
  35. #endif /* __STMFLASH_H__ */
    ; P+ E0 M, P/ D- @6 x) _) m, F
  36. # R. G$ C* K7 B- w) F/ [
  37. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码
/ z0 a1 p- K' K
3.3 main.c4 A0 B8 z! @# q: |% ]+ r
  1. /* USER CODE BEGIN Header */
    * {! b0 q% N- e/ b" W( ~3 P  p$ e
  2. /**7 m: I+ o; e# k( W
  3.   ******************************************************************************$ _* K" @5 ?1 N3 H; f+ j6 M: }
  4.   * @file           : main.c- S$ d0 \" H* }' e
  5.   * @brief          : Main program body
    4 [; W6 e" _1 d2 P( e0 U) @6 |
  6.   ******************************************************************************3 V. s  I- z( n
  7.   * @attention
    + y! {& H5 m0 S* D' F( [
  8.   *
    7 a4 K* E: T4 U4 A9 Q( I
  9.   * <h2><center>© Copyright (c) 2019 STMicroelectronics.
    1 H3 ?7 J8 ^* b2 E- B. @' |
  10.   * All rights reserved.</center></h2>* [0 s. @, t4 v1 F
  11.   *4 K/ r7 [& z5 O4 x( Z
  12.   * This software component is licensed by ST under BSD 3-Clause license,
    2 H1 V1 N! v9 m0 m- r3 i* _
  13.   * the "License"; You may not use this file except in compliance with the
    ! l7 h1 l5 G' V5 L$ S6 [
  14.   * License. You may obtain a copy of the License at:
    ) Y$ ^, Q  z! U( R
  15.   *                        opensource.org/licenses/BSD-3-Clause
    1 E$ V" V( J: Q* m$ M( {
  16.   *' N  D$ K& v) |+ I6 X1 e; B
  17.   ******************************************************************************
    & b0 f7 H+ s+ t8 J; z- r  Q
  18.   */4 j/ i5 t. j  Y  ?+ ]: G
  19. /* USER CODE END Header */
    : k9 K. `* E$ F4 X) p) F: Y
  20. 7 o/ s) O* H$ y. _% b( R. h
  21. /* Includes ------------------------------------------------------------------*/
    5 m  }* Z7 K* k, F! T! V
  22. #include "main.h"& o, L& [3 y5 k" i  A6 @
  23. #include "can.h"2 T5 x, j4 o. z1 @1 a
  24. #include "dma.h"
    7 _: y7 b. }  d( ]* n/ u
  25. #include "lwip.h"
    $ @9 y6 V: v# a6 Z& c1 E# T
  26. #include "usart.h": H# x$ o9 w2 t' g8 ]: R8 b
  27. #include "gpio.h"6 j5 h& {* B4 K8 q5 N& {

  28. 4 X9 w2 Z, Q. \3 _4 t3 _
  29. /* Private includes ----------------------------------------------------------*/
    # D) ^0 G5 r' l8 c+ Q, X
  30. /* USER CODE BEGIN Includes */
    1 O9 P# L: I5 J( x- i
  31. #include "string.h"
    , G; }# n: ]8 B2 c
  32. #include "tcp_echoclient.h"  I9 Y# _: `2 h0 t

  33. , V7 d& i3 c* F$ V0 i9 N9 v9 h
  34. /* USER CODE END Includes */
    3 _+ G3 _& o5 m( Q- D3 \

  35. ! _: `& H" `, W3 q. P) e
  36. /* Private typedef -----------------------------------------------------------*/
    % B7 o5 a' ?) r1 L/ C/ {
  37. /* USER CODE BEGIN PTD */: Q1 @" \+ {9 w" C! }# r3 G8 E

  38. 5 Q1 x, O+ d( h1 `
  39. /* USER CODE END PTD */# a4 w  g) C) n/ C- R. S+ Q3 b+ [

  40. : \* P3 x" c. i2 [# y! i; _: m$ U0 S
  41. /* Private define ------------------------------------------------------------*/* m5 O* d# y6 B& A# [
  42. /* USER CODE BEGIN PD */% n5 N. D9 v2 v6 }% ^' G  V
  43. #define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))
    0 g+ a/ j7 @, h
  44. / q2 d4 r* ]( a" ^+ |7 ]
  45. /* USER CODE END PD */7 K$ ~4 w8 ?' v; p1 l

  46.   t( x# y1 V# D5 R& w7 T
  47. /* Private macro -------------------------------------------------------------*/
    8 N$ {9 `7 [% l
  48. /* USER CODE BEGIN PM */+ f" `+ P( d& D7 i: J  C

  49. / ^; H& B0 k% u$ ^: w- Y. K
  50. /* USER CODE END PM */
    / }6 a* u* C$ |* S- n6 B4 c# f# \0 I2 y

  51. 9 l% ]3 j4 C# J7 K" f
  52. /* Private variables ---------------------------------------------------------*/. h% v. J. A6 ]  g: K! [/ ~
  53. 4 Q) ^3 q# I4 U  F+ @
  54. /* USER CODE BEGIN PV */
    * Q  ~- \6 m( E2 t/ l
  55. uint32_t  counter_10ms, counter_50ms, counter_100ms, counter_200ms, counter_500ms, counter_1000ms, counter_2000ms, counter_5000ms, counter_10s;
    ; G! z7 I- X) ~) b# ~8 k" T- i
  56. uint8_t flag_1ms, flag_10ms, flag_50ms, flag_100ms, flag_200ms, flag_500ms, flag_1000ms, flag_2000ms, flag_5000ms, flag_10s;
      E( |/ q/ {# g/ N
  57. uint8_t b_KeyNumber;
    3 G6 R! [3 s% e/ f( z: v  J

  58. ; x+ w2 @7 H4 y$ U; j0 ]9 e- w7 \5 F
  59. uint8_t a_DtuInBuffer[100];! Q* m, V: b# |: i( Y; @5 |. |
  60. uint16_t b_DtuInBufferRxCnt;4 K/ p0 L7 w/ W/ _. H) w4 h0 E

  61. & Y# N! p! U& I: i
  62. uint8_t a_DtuOutBuffer[100];( p/ k. s6 V/ \7 M( G/ J
  63. uint16_t b_DtuOutBufferRxCnt;# \* E+ R7 [8 e2 k) E: H
  64.   y. d0 f+ {; P. Q) N/ f
  65. struct netif gnetif;
    , G6 ~: Z8 p9 w0 b  G
  66. extern struct tcp_pcb *echoclient_pcb;) k% N7 d& P+ _7 d+ ?7 V6 n
  67. uint32_t status_TCPProc;
    " j/ L  @; N* d, j* r/ j7 H+ h" C

  68. # r2 J1 N% |, J( |; x% b' {; s

  69. 8 Q; [/ _0 n0 H
  70. uint8_t a_SocketConfig[7];
    3 L) a% ?8 t" ^. P' d
  71. uint8_t a_SocketHeartBeat[60];
    ! g& B6 W; p  w; R" I6 x' U
  72. uint8_t a_SocketHeartBeatInterval[2];
      c( H* H- l3 _( i  M$ a1 H
  73. uint8_t a_SocketRegister[60];3 `. J# j8 u  E

  74. 7 o* U7 s$ n4 g, D$ t" `
  75. uint8_t a_DtuInOutConfig[2];6 y6 e) d7 h. E4 A
  76. * ^/ _$ l3 q9 V+ ~% T% H  g. A( _
  77. uint8_t b_WifiMode;
    9 o3 t% k8 d+ C$ m+ F+ u4 f
  78. uint8_t a_RouterSsid[20];
    & P6 J2 Z* }, ^4 `2 a$ r
  79. uint8_t a_RouterPswd[20];
    # M; @( S# f; A0 W! [
  80. 3 |0 F6 O) U- C7 ^0 ~5 b  X
  81. uint8_t a_Rs485Config[5];
    1 G0 W$ ?4 O8 `; ~; R
  82. uint8_t a_CanConfig[5];/ t- F- g) V4 Q8 s7 s3 H- y
  83. 9 l- a% O% Q7 }! x8 {! s
  84. uint8_t flag_DtuConfigUpdate;7 {% ^/ q  v& q, C' g
  85. uint8_t flag_DtuEthReady = 0;
    0 d" _' @6 ?5 G! q
  86. % i+ R0 u8 U  d' T
  87. uint32_t b_HeartBeatPackageCnt = 0;
    # q& S. x5 Q8 ~, A; f

  88. ; e! f4 D8 ^7 ^  C2 k
  89. uint32_t b_232STM32ParamConfigBusyCnt = 0;        //尝试通过串口和STM32交互时候,会让出相应时间,优先处理6 B! x& K+ ~8 D) V9 v! \

  90. * k9 B1 T# ]  |+ _, e) E0 C6 R6 l
  91. /* USER CODE END PV */2 C  H! y) K4 N( H5 X% l  k

  92. ( ]5 U: U* h8 b) _9 H  F& h
  93. /* Private function prototypes -----------------------------------------------*/
    . K+ {* _8 I8 `! p
  94. void SystemClock_Config(void);
    * t! s$ X- Q$ ?% e/ \
  95. /* USER CODE BEGIN PFP */
    # j! J9 F, N8 }. ?0 ^# \! n, F0 D

  96. , G8 N7 a* }- @8 S! }. y3 j
  97. /* USER CODE END PFP */- v' x6 g# _( p. x2 Q- M* K+ q

  98. : i- y3 Y5 _4 t2 a
  99. /* Private user code ---------------------------------------------------------*/
    $ f2 b6 p% s& W; C0 T" v/ B9 A
  100. /* USER CODE BEGIN 0 */% R2 {2 l  C6 D
  101. void Task_HeartBeatPackSent(void): k, [# ?% X" h$ [' v, o& N
  102. {
    5 y, j5 E6 F; x7 @; m5 L( B. G
  103.   uint16_t b_interval;
      O$ {" L0 i* n2 k. q3 o7 p

  104. 4 {2 S- ?( y- a1 A  _( T
  105.   b_interval = (a_SocketHeartBeatInterval[0]<<8) + a_SocketHeartBeatInterval[1];0 B. Q) T$ q5 C( l/ z
  106. . J# U/ a. I0 k  h1 S2 v, _  M
  107.   b_HeartBeatPackageCnt++;4 K& x& J8 d6 t/ P7 g  U7 ^1 J
  108.   if(b_HeartBeatPackageCnt>=b_interval)
    / H' K; h9 v# c3 J" x
  109.   {
    8 }; z, p4 _. T3 M' s$ a
  110.     b_HeartBeatPackageCnt = 0;: n) p4 Q, m# C1 e

  111. & d* ~2 Q9 O4 J2 l& |% h' O

  112. & P6 }$ Y( F" D% ]/ G1 u
  113.     if(a_DtuInOutConfig[1]==1)
    $ n6 A$ U/ e3 ?4 e* H
  114.     {0 b2 N& _- B# {% f: m
  115.       if(flag_8266DTUReady==1)
    9 D% ^1 M! Z, J# V5 ~& i- j
  116.       {. ~3 M2 m, R) ]
  117.             HAL_UART_Transmit(&huart3, a_SocketHeartBeat, strlen((char*)a_SocketHeartBeat), 100);. \9 p/ J# Q2 A7 g& O
  118.             printf("\r\n");
    * z) J. u- h) ], ?, E
  119.             printf("\r\nA heart beat package is sent.\r\n ");
    ' d1 v  b; L1 c) M$ H& n& n
  120.       }$ S* g- M7 ~) Z( S$ ^
  121.     }
    & G/ G2 D6 g# n; ]# X6 E7 i
  122.     else if(a_DtuInOutConfig[1]==2)
    , m* B* ?, a& Y& E& `7 t4 p) d9 b
  123.     {
    : x9 C* o3 E  @
  124.       if(status_TCPProc>=2)
    & J. K" \2 l% ?7 A
  125.       {
    8 p4 y6 E. W+ @5 e' S' Y
  126.             tcp_senddata(1);
    & I, |7 Y; h( a" t( x# u8 P, p
  127.             printf("\r\n");+ K' E1 p4 h4 Y- x1 ]6 E# Q
  128.             printf("\r\nA heart beat package is sent.\r\n ");
    $ d: c: B( ?+ u1 K
  129.       }
    0 W: Q, c0 X& s" M) z/ y
  130.     }
    * [- N4 K& l9 r# n5 M4 C4 m
  131.   }+ @1 F" I; ]9 l& w
  132. }. \+ j) P+ n/ J9 X! J
  133. void cleanDtuInBuffer(void)
    4 _+ a' _  X, X
  134. {3 k6 y% t5 P8 y! m2 j7 p
  135.   uint32_t i;
    1 f8 d0 }- X( R# |+ ^  r' R7 l" c
  136.   for(i=0;i<b_DtuInBufferRxCnt;i++)
    " j7 `' K* F1 B  R$ _# n' y
  137.   {
    ! L' P5 [. ~. ]2 ^2 w! ~: x/ P
  138.         a_DtuInBuffer[i] = 0;
    5 ]  c  d. r9 j7 J
  139.   }
    ' O9 j# {( U: N0 T1 {
  140.   b_DtuInBufferRxCnt = 0;
    5 n  e' I1 O$ g6 Q
  141. }
    9 ?" f# w6 ?1 y$ o) G# S
  142. void cleanDtuOutBuffer(void)
    6 M! Z: ?- a3 H: C/ l! R
  143. {
    ! k" l/ T1 p: X. ^2 q; j$ y2 ?3 o) k
  144.   uint32_t i;
    % q8 R9 y8 ^  l# {
  145.   for(i=0;i<b_DtuOutBufferRxCnt;i++)
    + M! T. _, k. Y
  146.   {" X, l! G, Z. V! N3 X% z
  147.         a_DtuOutBuffer[i] = 0;
    $ a. @; X; u6 Y/ I
  148.   }2 @" R/ z& T) V$ |; X0 o$ I
  149.   b_DtuOutBufferRxCnt = 0;
    3 {* f( L0 ]( {+ Y) r
  150. }
    * V) d, L- G' j, m

  151. 4 J' e, i. Y5 g/ V# Y. ?
  152. void Task_DirectTransfer(void)& R$ W9 u  X7 q" g
  153. {$ v: M6 {- ~: t: H0 j1 j8 V
  154.   uint32_t i, k;/ y1 E/ R, R$ c! {0 v% ?
  155.   //把数据输出到以太网或者WIFI
    / ~6 y/ x( \  R$ T& s
  156.   if(a_DtuInOutConfig[1]==1): Q/ }& Y, Q$ T6 t# C
  157.   {+ b9 g1 _3 B2 i% ]
  158.         if(flag_8266DTUReady==1)
    1 B4 r) R" n' U; O  w! j3 e. p+ G
  159.         {
    . h! Y4 z- p8 b
  160.           if(b_DtuInBufferRxCnt>0)
    2 {" @- n7 U4 p, q" `
  161.           {
    $ O0 B8 t9 t2 ]# O
  162.                 printf("\r\n");
    7 o7 N0 H* z! d7 Z' |- _
  163.                 printf("\r\nData sent to Wifi: ");! K2 A" S5 W2 J( r* z3 _0 X$ S
  164.                 HAL_UART_Transmit(&huart3, (uint8_t*)a_DtuInBuffer, b_DtuInBufferRxCnt, 100);+ P! L; o9 ?) C4 c7 z/ f( K+ i/ d
  165.                 HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuInBuffer, b_DtuInBufferRxCnt, 100);        //debug
    9 k2 _3 _( {2 Z# a) r1 \0 O
  166.             cleanDtuInBuffer();3 F& D' U( d0 u* @; e' }
  167.           }
    4 t! L* f7 O- P% \6 T5 r) R
  168.         }
    1 w: o- \4 n2 u( M/ ]+ C
  169.   }+ c& B, m9 U. D" V9 F
  170.   else if(a_DtuInOutConfig[1]==2)& l7 I, B% e7 A9 G+ m; H3 w
  171.   {
      H# S( x& ?$ v! @% \6 i
  172.         if(status_TCPProc>=2)6 a; E( Y7 U6 U, E! ^5 q
  173.         {
    % G( U4 G( r& t* Y: W6 C; H4 L. n0 g) C
  174.           if(status_TCPProc == 2)
    7 f8 i0 ]0 L* G4 m+ d: i6 ], V
  175.           {
    ; W" Q0 l) V1 F( }
  176.             tcp_senddata(0);        //专门发送注册包1 `6 |- O. S6 M- q# l6 a" R
  177.           }& H( H( h  B0 Y- @9 I- W
  178.           if(b_DtuInBufferRxCnt>0)9 F; k6 M5 \' k$ B+ P
  179.           {
    % v3 i' @' r0 F9 |+ G. n
  180.                 if(status_TCPProc <= 3)' E+ q( A) l8 i! T
  181.                 {# H( h. B+ V, g
  182.                   tcp_senddata(0);+ [0 W3 C( e9 P& j: z
  183.                 }
    + A( ^" k. P+ ?, N$ A
  184.                 else( y; M7 R6 O9 Q! v' U
  185.                 {* x/ Z9 {. c4 f* H5 ]
  186.                   status_TCPProc = 0;
    ) l, x8 r: p6 ]
  187.                 }* H# C- W7 r- c$ X- h0 Y
  188.                 cleanDtuInBuffer();$ y8 `- n7 {6 ~0 v
  189.           }
    ) D  }" R  E! u
  190.         }0 q6 i1 R6 {$ P5 q
  191.   }' r& g9 |$ a5 O8 G5 l

  192.   v4 J/ n# H% R/ _* e1 x

  193. ' h$ D( K3 x' s3 E0 A4 J; S$ [
  194.   //把数据输出到RS232,RS485或者CAN
    3 D/ f( X2 n5 e
  195.   if(a_DtuInOutConfig[0]==1)
    ) {# d" a. X! K' N* j, Z
  196.   {9 G+ F  Z- k- V
  197.         if(b_DtuOutBufferRxCnt>0)
    9 I$ l+ B- H( O% N* B
  198.         {: g$ G- U. L- v. F8 ^; e' {9 y2 D! u
  199.           HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);2 f! P4 H. A' F5 i) U
  200.           cleanDtuOutBuffer();5 T6 k" ~  e  O. N" E, ^$ n; V
  201.         }; e; v4 S# _$ w
  202.   }
    + Q5 {% D3 @* |+ s# z) ]/ w
  203.   else if(a_DtuInOutConfig[0]==2)+ |/ F% c* X. P" D3 x/ ^' m
  204.   {+ b' I0 ?, p7 n7 Z
  205.         if(b_DtuOutBufferRxCnt>0)2 _" K9 @( l' B. P7 @2 Z- @
  206.         {
    # e7 N" E; `( M  \
  207.           printf("\r\n");
    + Y' G% L1 ~+ a6 U+ C+ G4 Q
  208.           printf("\r\nData sent to RS485: ");
    ' d. w: \& L0 o+ k1 G
  209.           HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);//debug
    3 G3 Z7 A. X$ r3 }. V' H
  210.           RS485_TX_MODE();
    : K. D/ }* M- }4 N
  211.           HAL_UART_Transmit(&huart5, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);1 j8 i$ [$ X3 e% X) v+ ?
  212.           HAL_Delay(1);
    1 y) Y; F/ [, E: h% a
  213.           RS485_RX_MODE();
    - F" ^+ ~6 G! H3 w. e
  214.           cleanDtuOutBuffer();: x) p* r) u! f% F7 S; Q
  215.         }
    ( s0 Y) k+ x4 G1 k' p$ D
  216.   }, o0 m) E/ n: {/ h! Y0 ^
  217.   else if(a_DtuInOutConfig[0]==3)
    ' K% E5 n0 f( I
  218.   {0 F, c% G- j; x1 K3 H
  219.         if(b_DtuOutBufferRxCnt>0)
    5 z- p1 _9 j- k8 H
  220.         {; q- u; a1 G; h3 |  L
  221.           k = 0;
    . c  e/ t9 Z1 b) }1 W1 S
  222.           if(b_DtuOutBufferRxCnt>8)
    , I- r  o( W; O6 [1 N
  223.           {9 _6 j) A: }% W# ?
  224.                 for(i=0; i<8; i++)
    $ D) s! K9 ^* f* `1 O
  225.                 {' Q# _& R1 {8 V1 ?
  226.                   Can_TxData[i] = a_DtuOutBuffer[i];" q- A3 X0 x5 I5 W' Q" h$ ~9 r
  227.                   k += Can_TxData[i];& K) Q# F8 T' u; ~6 m% `. Q: H
  228.                 }! e+ O+ G- ?1 g  m- i
  229.           }
    ( m0 q3 O' S# y* j
  230.           else
    % T, m+ o! e6 f! _
  231.           {
    4 i3 l7 M) e& z1 {& A  t
  232.                 for(i=0; i<b_DtuOutBufferRxCnt; i++)' {0 x& a& T0 g8 a1 T7 z) A3 v
  233.                 {: i; z( s0 m" L' J, J8 q
  234.                   Can_TxData[i] = a_DtuOutBuffer[i];
    6 r  G# {; j7 b6 l5 `% x
  235.                   k += Can_TxData[i];
    " }8 b+ ?+ {4 Q, a" \' H9 ^
  236.                 }  L; L9 t" T# n  o) {
  237.           }- ?6 N( N; H" @/ D4 K2 b
  238.           if(k>0)
    3 J* E/ R, q4 M
  239.           {
      ~8 ^( a, U) y! ~- F
  240.                 if(b_DtuOutBufferRxCnt>8)6 i7 o* y( g7 N
  241.                 {6 u) v! b" G" g9 t* \' w
  242.                   Can_TxMessage(0, Can_TxHeader.StdId, 8, Can_TxData);
    # F) K8 K5 I' k6 {2 |/ N
  243.                 }
    7 B* V- e$ L; g- [9 r* N, B
  244.                 else
    & x6 Z# L' c( R9 a/ ]; L$ c
  245.                 {
    % b% n$ j" a5 o; {5 I) O$ {
  246.                   Can_TxMessage(0, Can_TxHeader.StdId, b_DtuOutBufferRxCnt, Can_TxData);3 O0 Q; t2 ?  N
  247.                 }$ D5 p3 `0 j& @: y( y( T
  248.                 ArrayLeftShift8bits(a_DtuOutBuffer, &b_DtuOutBufferRxCnt);
    0 {" k. @3 c1 u2 V) z9 A
  249.           }! _# Q7 [* q. f9 g# ^1 A
  250.           else
    8 s5 j/ Q  C8 U3 X3 Z
  251.           {
    $ ~% K7 Q- }" s/ v1 J
  252.                 b_DtuOutBufferRxCnt = 0;
    5 I2 r- x2 |) [& W
  253.           }
    + N. v4 [' r3 J  ^, f0 R  }
  254.         }) L! O0 E* x. ]! q0 r2 ]
  255.   }- |4 o/ B2 c; z& j8 R  U
  256. }7 e; d' K/ d) `8 ]0 s
  257. void Task_DtuRedoConfig(void)
    / l5 }, F0 W' M: S
  258. {
    * m; p4 C' y. G3 s+ O
  259.   if(flag_DtuConfigUpdate==0)& k1 x/ P2 e( d# \( b
  260.           return;% O. n& `6 S- ]4 V5 z, c2 I9 a
  261. 9 Q8 \2 Q: A+ n: d+ A8 z3 U
  262.   HAL_Delay(10);' {9 i: P, {# g. c
  263.   printf("Re-initialize ETH, WIFI module, RS485...  ");* V- q9 C# q* V7 [/ L  [
  264.   //ETH:
    1 {. \$ q) {) }+ d: V) T& l& P
  265.   if(status_TCPProc >= 2)
    # Z- b- s7 U  e9 I8 @4 o
  266.   {; h( B! E! y  o" b
  267.           tcp_echoclient_disconnect();8 _3 w- Y& G4 @& R' }4 S
  268.           status_TCPProc = 0;8 c8 x9 {! k8 H3 j
  269.   }
    2 W5 O: c6 y  i3 e) [
  270.   //ESP8266:
    : ~* i" n) b. A2 A
  271.   if(Status_NodeMCU>=6)) E  v. o0 {# w$ m% E+ n. F
  272.   {5 O" c8 `$ r! b
  273.           sprintf((char *)a_8266TxBuffer, "+++");                //esp8266 接收到这个+++会停止透传模式& q  g& v* p9 A% y
  274.           HAL_UART_Transmit(&huart3, (uint8_t *)a_8266TxBuffer, strlen((char *)a_8266TxBuffer), 100);# S- c( s  P& P* |( r
  275.           Status_NodeMCU = 0;
    7 B3 v( a$ Y# }1 \. L
  276.           HAL_Delay(100);% W% l' o2 n2 a# w6 _7 M+ J
  277.   }
    # V3 q; }3 W/ d2 U) w
  278.   //485
    - X" \& }% H9 b# c3 X8 V  h
  279.   //MX_RS485_Reconfigure();
    % P! \6 s* T1 a1 F4 M* J1 Q
  280.   printf("Completed.\r\n");! q( c4 `  M9 p4 T9 i$ J% v
  281.   //5 C7 _& i- _+ L2 A6 D
  282.   flag_DtuConfigUpdate = 0;, _0 ~0 B( i7 ?8 f2 b( I
  283. 7 `3 M/ i, D2 P2 C& F  J* M
  284.   HAL_UART_Receive_IT(&huart1, &b_232RxByte, 1);0 J9 m- G( p, S' n, o
  285. }
    * N& M3 m$ F8 i2 ~! D5 H
  286. /* USER CODE END 0 */0 v5 f$ e) ]% c7 U; J5 m% k2 q

  287. + S# M/ j% ]  w
  288. /**! `# P! I- s! f0 H9 r5 |8 w- ~
  289.   * @brief  The application entry point.3 \, ]" }3 R: L# p5 n
  290.   * @retval int: o9 Z: E+ s" K% p+ s+ O, Q
  291.   */3 e/ a$ y0 R# Q" i. [% R
  292. int main(void)# [. z- S2 c1 C. y1 {
  293. {0 {9 f  ?5 x9 C
  294.   /* USER CODE BEGIN 1 */
    ; |- P) y. J3 k9 ]; a
  295. : d" a0 R4 _4 v5 i+ V  _
  296.   /* USER CODE END 1 */' A3 @' @' D. f
  297.   
    - Z4 v4 k' H0 C. j& z7 p

  298. * x3 l0 H7 d; G9 ~6 T2 g1 V2 E+ ?
  299.   /* MCU Configuration--------------------------------------------------------*/
    : r6 R* n  b5 T" B* k" i" b- r) v

  300. * \+ ~$ a( ~# N; X0 ?+ n# f  }. l4 R
  301.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */' l1 `9 _( L+ U; d
  302.   HAL_Init();1 c* Y3 r) x8 @5 u

  303. $ W6 n# A3 k8 J" k- [0 C
  304.   /* USER CODE BEGIN Init */
    * z0 t0 J0 J- f. P0 E$ N" [

  305. " \( H" g# b% f* [% J/ Z$ F
  306.   /* USER CODE END Init */
    ! {+ P) o1 S! @, z0 J" L1 \

  307. : B! c3 V' p3 F- [5 K9 l& r4 ]0 [
  308.   /* Configure the system clock */- C* A) {" M- s% l
  309.   SystemClock_Config();1 \* A4 O% g& l/ v' h, f$ [
  310. ) _% T$ g9 E9 U4 N( A( b4 @
  311.   /* USER CODE BEGIN SysInit */$ @7 @# l( F. Q5 |7 _

  312. 4 R3 @+ i1 |+ j5 s0 r
  313.   /* USER CODE END SysInit */
    6 U7 e* P) d) A$ L/ G! @
  314. / b% p. j8 I" L! J( a( B: g
  315.   /* Initialize all configured peripherals */# L- k/ O% _$ Q
  316.   MX_GPIO_Init();$ `, Y& _. s" }* d4 k  b2 ?
  317.   MX_DMA_Init();1 Y* m3 V+ P* d, R3 ?; W! f
  318.   MX_USART1_UART_Init();
    - K: {# @8 |) t* k5 O
  319.   MX_USART3_UART_Init();
    ! T5 M  q) ]+ `
  320.   MX_CAN1_Init();
    1 X# S, ]2 }3 P0 f' |, l
  321.   MX_UART5_Init();1 [: R" J$ H, G. t. V
  322.   MX_LWIP_Init();
    ; K8 ]$ Z7 Z7 ?1 G
  323.   /* USER CODE BEGIN 2 */
      O7 b5 z+ k# T7 k

  324. - r) X- K: ]/ M) y% {3 |
  325.   RS232Interact_Init();
    0 Z( I# N7 N4 G0 b+ C
  326.   printf("Hello. STM32F107_DTU project: DTU. All in one.\n");
    6 A6 [$ {6 _& P# J) B7 c

  327. : [; p& M, o/ [, y, m
  328.   HAL_UART_Receive_IT(&huart1, &b_232RxByte, 1);1 L, o+ D4 \# a- b" f9 n
  329.   HAL_UART_Receive_IT(&huart5, &b_485RxByte, 1);8 s  i+ n5 u6 t
  330. ! B0 \9 j! I4 ?( w1 n( B. K7 G
  331. " e9 L. e9 K( A% Q4 ?1 s7 @
  332.   sprintf((char *)a_8266TxBuffer, "+++");                //esp8266 接收到这个+++会停止透传模式
    - @* g) i# x0 G" s& o
  333.   HAL_UART_Transmit(&huart3, (uint8_t *)a_8266TxBuffer, strlen((char *)a_8266TxBuffer), 100);+ d# }. ]7 E; K+ j- z: J
  334.   Status_NodeMCU = 0;) F/ A" W1 g' B5 P/ Y' u* S
  335. + Q/ i6 v+ P- L7 c: J* s: Z
  336.   status_TCPProc = 0;* @% U0 I: [8 y1 b
  337. : W( [( ~/ q; R- [- }
  338.   RS485_RX_MODE();$ k5 y& |0 [, P, y
  339. 1 |  A4 `' _: Q6 t+ |: Y; B% J
  340.   CAN_Config_User();% ?; Z  h- J6 \& V' Q
  341. / R0 s! i1 Q& W
  342. . H# p/ l( A  R# T2 n& T
  343.   /* USER CODE END 2 */, e& v% E, p7 Q/ \  A8 j. }& l- W

  344. , T) |  `* h" [
  345.   /* Infinite loop */
    & f, Z& k0 p$ S3 x$ a; W
  346.   /* USER CODE BEGIN WHILE */
    $ d: c! c. o! o5 Y6 O
  347.   while (1)# {5 t7 C" P9 ^9 o7 k
  348.   {
    : z7 q) ], ^$ ?) U
  349.         if(a_DtuInOutConfig[1]==2)
    5 a# A! Z" p+ q4 G2 _
  350.         {' p4 _7 g7 z. k; e0 V; s
  351.           MX_LWIP_Process();4 L/ j: ~$ l- n4 d2 u
  352.         }
    9 f4 X* b) r: k
  353.         if(flag_1ms ==1)1 }/ Q6 ^' S; b
  354.         {: X& o3 A! A  H
  355.           flag_1ms = 0;$ O5 g  r( N+ Q/ w
  356.           Task_232PC_Interact();% z/ ^- }' J6 L9 h" y' n$ ]) k
  357. * Q' \; {" G0 v) `6 |
  358.           if(flag_DtuConfigUpdate ==1)
    . Z5 ^. {7 Z/ S" C; H$ }+ p
  359.           {0 H! M  J3 ?" x" J$ |. X
  360.                 Task_DtuRedoConfig();
    ' i8 D9 F* o# D/ O6 w+ e
  361.           }$ H! f! S. i% i& J! i! [% Q0 S
  362.           if(b_232STM32ParamConfigBusyCnt>6)
    ( I0 F5 L0 d! F: x8 B3 a
  363.           {
    7 `2 }* B3 y4 z8 H0 a
  364.             Task_DirectTransfer();
    5 K7 ]& m8 q& C5 O6 p4 C4 A* q# q
  365.           }
    7 i, w7 X; E- G* h$ G, P
  366.         }
    ; E% ^- u) d- ^
  367.         if(flag_10ms==1)
    / c4 P; Q, J2 ~" K; X5 h) v. o8 e
  368.         {
    $ L9 t/ t3 O. R. W3 C! G
  369.           flag_10ms=0;
    % l! Z1 ~  A5 c' ?3 `
  370. ' U* l3 P( r; v5 N# w; r3 y
  371.         }
    4 ]2 @5 [5 ~! L9 v) q
  372.         if(flag_50ms==1)        {                flag_50ms=0;            }
    1 m$ m% n# v) J5 n3 {' l$ E
  373.         if(flag_100ms==1)
    ; o4 f8 V: v2 [8 H
  374.         {
    1 |, M0 B3 R) z, h2 G* w; T
  375.           if(b_232STM32ParamConfigBusyCnt>6)5 K2 y% T$ Q. {; B5 _% I
  376.           {
    / {9 I% R. v2 e3 M* v
  377.                 if(a_DtuInOutConfig[1]==1)* @2 b) d$ ?7 B6 G; a
  378.                 {
    1 I1 s/ }" ~- |! {# ~- C0 N
  379.                   if((flag_ProcNodeMCUActive ==1)&&(status_232PC<12))* B3 x$ m* \& Q  t7 g3 W) v3 A
  380.                   {! _' e! |4 C2 `  e. x9 q
  381.                         Proc_NodeMCU();- T7 L+ j# d+ Q  o
  382.                   }) }1 h2 _: O: n6 o
  383.                 }
    # a- T8 i: d7 S" |: q; D# n
  384.           }
    ) f7 \' K+ E4 ~+ W3 K' @
  385.           flag_100ms=0;
    + h* A% w0 Y; P6 d: @
  386.         }% w4 |5 v/ [$ g2 k0 U2 n* `9 d
  387.         if(flag_200ms==1)        {                flag_200ms=0;            }
    ) q. ?: K* \* P/ T/ v) j6 p
  388.         if(flag_500ms==1)        {                flag_500ms=0;                }
    3 l# j2 U; m6 A, [- @* A
  389.         if(flag_1000ms==1)
    3 s3 {% `. \3 m5 u' h( R  p/ a
  390.         {* y0 I0 [7 I" W  u: W8 D
  391.           flag_1000ms=0;3 k0 d, l; }  ^
  392.           HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);, r2 V8 m! }6 T) J% b: ]5 e7 O
  393. 1 l/ [# C( t- D( T3 x, I6 R% M" x9 |
  394.           if(b_232STM32ParamConfigBusyCnt>6)
    - v9 D1 k% G# n' a4 Y  w
  395.           {0 u2 m- A) z2 x$ w% q5 A
  396.                 if(a_DtuInOutConfig[1]==2)4 Q- Z: l/ t- R/ l" e& r) v2 |. y
  397.                 {& }3 v9 R3 @0 p+ T' g
  398.                   if(status_TCPProc<=1)# X" A& c* q& F- X' f8 Z9 Z6 d7 e
  399.                   {
    , X8 T' y6 u4 Z/ p, T- l$ k
  400.                         printf("connecting to TCP Server...\r\n");
    8 ~0 H" S3 F8 q) j; `5 k
  401.                         tcp_echoclient_connect();: e2 N2 {; w6 ]# D
  402.                   }0 X+ W3 j, K/ r4 z
  403.                 }
    ' ~8 \% w8 k1 D# C6 G
  404.                 Task_HeartBeatPackSent();8 m& k5 b$ i; B, E' \" P1 @
  405.           }( G7 a  T# R5 i) o7 i
  406.           if(flag_ProcNodeMCUActive ==0)
    $ t2 ~- A( x5 k' Z
  407.           {
    + v1 R& C5 _. x' y
  408.                 flag_ProcNodeMCUActive = 1;
    ' T, ?2 e7 Y( X# v+ J
  409.           }4 Y' P: v7 o9 ]+ H  o! A4 g: |
  410.           if(b_232STM32ParamConfigBusyCnt<80)  w6 Y, A9 l* {
  411.           {
    2 I* p" S/ W4 l1 \' e( q0 n
  412.                 b_232STM32ParamConfigBusyCnt++;, A+ c( _& M6 f/ k
  413.           }
    4 C: K: a: v. I$ _5 F
  414.         }
    / j1 K7 q1 X  w6 @4 m
  415.         if(flag_2000ms==1)
    4 E6 M/ P8 r; x0 N  R3 x8 ?
  416.         {
    , j# K. D, Y# `! N
  417.           flag_2000ms=0;2 `' i3 H) @" B5 h! X' l

  418. & n+ R9 Q8 L7 K2 ]2 z! C" Q
  419.         }
    1 o) v' n* z7 I
  420.         if(flag_5000ms==1)
    , r6 i1 ?0 y$ F5 o
  421.         {! ?4 ~# h5 F0 d) b: U. U" Q  C
  422.           flag_5000ms=0;7 W& w- E3 {1 A' `2 c  C3 y- G2 J1 ^
  423.         }# E4 }0 k) r- \# X! S- I

  424. % @2 T, \$ L9 K% `
  425.         if(flag_10s==1)
    ) Z9 S; }( T& X9 i& c" Z* E+ ]
  426.         {
    ' H/ Y8 g/ K6 z- n2 _9 E) u
  427.           flag_10s=0;2 A# ~5 e4 L" G& E! r3 Y
  428.         }
    8 ?2 V- y$ q2 Q0 h' p
  429.     /* USER CODE END WHILE */
      e; K9 }5 ^2 [0 F6 x: w
  430. 9 V% W# e5 `% z- h# m% Z0 O7 ]' c
  431.     /* USER CODE BEGIN 3 */; m; r8 p- d. _0 _. _9 I3 I
  432.   }/ f) u" L5 M# K. h. W/ ?
  433.   /* USER CODE END 3 */& i$ L: i. g* j8 t# u) ~
  434. }# A4 M: ]# {+ t1 X6 ?. E8 g
  435. 8 ]4 O) e7 }0 H- z- h  F
  436. /**' H0 {. j8 m) V# L9 R0 Q1 U$ ~
  437.   * @brief System Clock Configuration) H% @5 ^+ q3 |% O7 T0 c5 Q) Q4 g
  438.   * @retval None
    & J* `( K, J  D8 D/ s) s& C
  439.   *// U. H- X, ^, s8 Y
  440. void SystemClock_Config(void)  [9 A( b' g- U8 c% Y' P/ ]! C* w
  441. {, X/ J! V7 k# k8 _. H1 I
  442.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    $ _; i: ]& f4 B) d( b
  443.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};. n/ i9 Y7 \1 {

  444. 1 `+ K9 M. P2 r9 z! v+ k
  445.   /** Initializes the CPU, AHB and APB busses clocks * d$ g7 U( B" ~6 K! s
  446.   */
    & v; d* R- K5 L& o
  447.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    3 U3 r( I& R  G7 v
  448.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    3 v& |# j, N# X' L2 z5 ?
  449.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;; \. P8 E5 T; N* v& t
  450.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    2 G& c; u! i; Z7 l% _: \
  451.   RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
    # S5 e0 e8 D6 e3 r2 P+ C
  452.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    ( F0 ]& f6 ]$ O* J9 L% f
  453.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;0 e9 s& ~% K5 u2 j# {
  454.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    8 U9 ~* H. a- o; r  ~0 ]
  455.   RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;8 }. A* \: q! w3 T3 \4 a% p7 r' |
  456.   RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL10;  E. a4 K  W* f+ O. i
  457.   RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV2;) @7 k- T! t6 Y! z. {8 Q
  458.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)& v: K9 I4 {' \! N  n6 {
  459.   {
    9 n, O9 w* J5 ?, v! x8 X3 b+ }
  460.     Error_Handler();! d, P+ {* D0 r7 m$ R& f, V
  461.   }
    ; N- `) `( ~$ t9 W( k+ I
  462.   /** Initializes the CPU, AHB and APB busses clocks   ?" S' e9 ^! n9 W3 [: c* c. T
  463.   */  n6 P; U7 ?  N* q8 D+ o4 j
  464.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
    3 x8 m, }2 ], C7 k
  465.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    8 R5 p7 W# y( [* X. D6 d' j
  466.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    ! n3 V5 u4 U+ m' R1 r; B- n
  467.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;$ Y7 V6 h+ s  W- _5 y+ E0 p5 Z
  468.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    . |: i7 I2 W+ Z; ^
  469.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;$ Q( w( [) ~; y" y

  470. % l$ y" P9 L/ b0 {1 Y
  471.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)' b1 V- G6 R  w
  472.   {" x* u+ r+ y& E/ v- q0 ?# e# l
  473.     Error_Handler();9 [" O+ A3 w5 c: X+ U: e
  474.   }
    ! ]: S' w7 s$ U: D: k
  475.   /** Enables the Clock Security System 1 X8 q8 s4 D9 _" ?' H( Q: ]1 A
  476.   */
    / E6 }- V+ d" w" G- K+ B$ X% E8 C7 M
  477.   HAL_RCC_EnableCSS();8 v' M8 p& K. q: |; |
  478.   /** Configure the Systick interrupt time
    2 m) j4 j3 C/ }* H9 L
  479.   */" p* [+ f6 D. B1 `& a/ q6 h! y- \
  480.   __HAL_RCC_PLLI2S_ENABLE();8 @$ \- W8 H* N8 P
  481. }
    . `+ ]3 Z# M: Z. U* a# e

  482. 7 _5 q4 L4 ?6 Z
  483. /* USER CODE BEGIN 4 */- f2 y7 U6 y) g7 L( N) M+ s$ k

  484. 0 G2 d, }/ P; U% z7 g8 {6 f1 a  o
  485. /**% a- V( ?7 I3 J
  486. * @brief HAL_SYSTICK_Callback()
    . T  N1 [* C6 W! j4 g* N- c5 I* |
  487. * SW timer triggered every 1ms.& B: i5 A! [! C. X  j
  488. */3 |" |9 M; N9 ?# O
  489. void HAL_SYSTICK_Callback(void)7 i3 P. [' x3 b% B4 X+ {
  490. {6 E7 f* `8 I7 |" v$ z9 L! q0 ~
  491.   flag_1ms = 1;2 C" P; d' {3 m3 d
  492.   /*update counters*/& m5 U" s7 W5 d& B
  493.   if(counter_10ms<9)  {    counter_10ms++;  }
    / Q7 [1 h3 X4 x6 R
  494.   else  {    counter_10ms = 0;    flag_10ms = 1;  }0 R- Y# h1 S$ f5 i! g* G3 y
  495.   if(counter_50ms<49)  {    counter_50ms++;  }
    , ?0 f/ T# b+ B- W. ~5 s1 X
  496.   else  {    counter_50ms = 0;    flag_50ms = 1;  }
    5 `6 p$ _+ N9 f$ y+ I
  497. * |) q- |6 I" s0 u* f
  498.   if(counter_100ms<99)  {    counter_100ms++;  }! K$ @, Z% z* A. j9 |/ k/ V
  499.   else  {    counter_100ms = 0;    flag_100ms = 1;* h# y: w, D- a8 k( ]
  500.         if(counter_200ms<1)        {          counter_200ms++;        }6 D8 A, v- P; z. v  u
  501.         else        {          counter_200ms = 0;          flag_200ms = 1;        }
    / @+ Q% X1 g/ w! e/ I% Q0 u- t; {
  502.         if(counter_500ms<4)        {          counter_500ms++;        }
    ) F9 j4 x. x# v" f9 q1 T8 a; I( g* }
  503.         else        {          counter_500ms = 0;          flag_500ms = 1;        }
    9 d( t6 I0 B0 [, b0 @( q" p* \: X
  504.         if(counter_1000ms<9)        {          counter_1000ms++;        }
    5 E! I* B6 o: L$ q' X
  505.         else        {          counter_1000ms = 0;          flag_1000ms = 1;        }
    8 P% `$ m% v6 Y0 j4 W( }
  506.         if(counter_2000ms<19)        {          counter_2000ms++;        }
      J; R% Y: O5 O, U% [/ ^
  507.         else        {          counter_2000ms = 0;          flag_2000ms = 1;        }/ B! a3 Y" Q( K: j" \+ J  L6 I
  508.         if(counter_5000ms<49)        {          counter_5000ms++;        }
    ; @1 W& Z+ Z" m6 L5 l$ @
  509.         else        {          counter_5000ms = 0;          flag_5000ms = 1;        }6 E1 m4 C0 H) ]
  510.         if(counter_10s<99)        {          counter_10s++;        }
    " }2 u6 B8 v  X9 n" K7 u/ E
  511.         else        {          counter_10s = 0;          flag_10s = 1;        }: v. I6 h$ I# e# K
  512.   }9 l4 R3 ~3 h0 {3 N* w( [, |3 ~
  513. }* [' `# o8 \1 h$ f6 B# `# V

  514. $ Q( N; |1 Z: ?1 _
  515. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)/ C+ E! V# v" y! W( H
  516. {
    % M4 F7 r; g& @6 {) A: }
  517.   if(GPIO_Pin ==GPIO_PIN_13)
      p1 h/ n* l& ]6 h- I! I- A
  518.   {9 c4 g! _- Q1 L% c0 _4 q7 m2 [7 q7 y
  519.         b_KeyNumber++;
    % g& _1 Z/ ^9 q6 W6 P6 g2 V
  520.         if(b_KeyNumber>=2)
    5 a) x$ u- r- j. U4 I, a' a
  521.         {# p# I/ `! R' A( J
  522.                 b_KeyNumber = 0;
    7 ^1 e/ M+ u5 P
  523.         }
    - p& u4 c7 x" X$ \

  524. 5 f- A$ X& O" V/ R; Q7 L$ F% I* W( c
  525.         sprintf((char *)a_DtuInBuffer, "a simple package\r\n");' t4 I/ j4 d( q4 L& Q9 ~/ h
  526.         b_DtuInBufferRxCnt = strlen((char *)a_DtuInBuffer);7 Z/ d2 a- T) b) m5 J( F( q

  527. ! Z/ [4 b% a3 x! R% s3 n  L3 |0 l; l
  528.   }
    7 Y" {5 z* C2 M" @' l: x5 l  u
  529. }% j/ f( [! |& o7 i, E
  530. ! f  i  E# ?. x' A  T
  531. /* USER CODE END 4 */7 v0 U7 {( J4 b: {' ~+ w6 q& a" A& I7 W& g
  532. 3 \) M  {- t& Q0 v: e
  533. /**, T7 |1 X0 R0 _; m
  534.   * @brief  This function is executed in case of error occurrence.
    7 _+ ~6 |3 M$ w
  535.   * @retval None5 o$ N0 j/ u/ l  a3 L3 S; n2 N
  536.   */& b6 a; a( o- l( a2 B& ?3 R; X
  537. void Error_Handler(void)
    7 d1 U$ V* N/ T& A. D
  538. {
    7 J. R" e6 l& [7 A/ x/ p# ^
  539.   /* USER CODE BEGIN Error_Handler_Debug */8 w( w  t* a9 }$ `% T
  540.   /* User can add his own implementation to report the HAL error return state */; _" P# e  G+ M: j) z' |- y
  541. 1 {9 x" ?4 L, |1 ~+ X
  542.   /* USER CODE END Error_Handler_Debug */
    0 c2 ^2 S- D3 q
  543. }. E; X, v6 e( T+ u" S. W
  544. # ^3 C. ~" G: c5 q. j; A- y
  545. #ifdef  USE_FULL_ASSERT
    ( w3 M4 S; v; e" u3 f/ O! b
  546. /**
    1 X. R  l, Q9 a/ l
  547.   * @brief  Reports the name of the source file and the source line number
    $ g& n* k* s; \! Z
  548.   *         where the assert_param error has occurred.
    ) M: I( `" c2 X( R
  549.   * @param  file: pointer to the source file name! F; h# M0 i) G( I$ N+ k9 O
  550.   * @param  line: assert_param error line source number
      m6 x2 C' q/ E& ]$ t* [- z
  551.   * @retval None
    . ?0 D* h2 H$ Z* r% ~3 N$ B
  552.   */
    ' i/ }8 G/ x7 N1 @, c- a1 Q
  553. void assert_failed(uint8_t *file, uint32_t line)
    9 l! O7 q% J( E" q, H9 r: p' A
  554. { # v+ Z  l; {/ u# m+ j3 a; v. x6 Q
  555.   /* USER CODE BEGIN 6 */
      I3 _) S! @$ `
  556.   /* User can add his own implementation to report the file name and line number,3 V8 Y0 g- z3 D+ y) o% O
  557.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */! X8 P' ~, S. F
  558.   /* USER CODE END 6 */
    1 T" |: Z9 N  R# V; P
  559. }" Q3 \; \. A5 D( a2 S' i) E1 Y
  560. #endif /* USE_FULL_ASSERT */
    / m  T: s; D6 J9 R6 ^0 A& @0 O

  561. 2 c" |* R$ R2 Z5 r+ ?# H
  562. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码
1 k1 T9 L1 H; N0 g, Y' k0 T
4 试验结果

开发板上面的指示灯亮了,同时使用仿真器观察接收数组的内容:


% r) M* p# a1 z! Y* q7 v2 e; o. `+ @1 ^% s  u! n2 L5 \) B2 _+ h
收藏 评论0 发布时间:2021-11-27 09:29

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版