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

【经验分享】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。

' C3 C, M9 e2 W9 J
3 c3 n2 n6 |6 @' v# C

3、硬石STM32F1开源的源代码3.1 stm32f107_flash.c
  1. /**
    ) U( @# f: {- b3 f4 ]
  2.   ******************************************************************************
    ( i1 I( O7 u  t. B
  3.   * 文件名程: stm_flash.c , {/ P9 h  o! L" W
  4.   * 作    者: 硬石嵌入式开发团队) K$ r1 m0 O9 [) n# K3 Z2 M! {+ J
  5.   * 版    本: V1.0
    7 \% k1 X- b6 c5 @- J! q
  6.   * 编写日期: 2015-10-04. _: D( y8 w3 ~  G) o/ Z
  7.   * 功    能: 内部Falsh读写实现
    . k1 ~4 v& E" ^* u- V% @5 N
  8.   ******************************************************************************& g+ n0 p. n+ K0 G2 n) J
  9.   * 说明:
    ) |' C- }. E& i
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。$ G0 S  R; K% n) f# F: Q3 C
  11.   *
      R% q! w7 b$ p3 L9 r4 W( _
  12.   * 淘宝:
    ) i/ R+ T+ L0 k$ Q
  13.   * 论坛:http://www.ing10bbs.com
    , n# a1 w3 J# v
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。# b0 i% p1 O8 T$ J# V1 x8 A
  15.   ******************************************************************************' Q( S: c( m4 f" c7 N
  16.   */
    & }% F+ e9 _5 s# b2 ~
  17. /* 包含头文件 ----------------------------------------------------------------*/4 h( b: f- ]6 d6 f; i5 j( G0 `
  18. #include "stm32f107_flash.h"/ \3 s8 N6 c% t. }; }* u! O' \

  19. # }2 W, X! P2 f8 g# P
  20. /* 私有类型定义 --------------------------------------------------------------*/
    0 j* \! k0 l* R" l+ k
  21. /* 私有宏定义 ----------------------------------------------------------------*/4 R9 \2 O9 x! p! H
  22. #if STM32_FLASH_SIZE < 256
    . }2 r" d2 v! J' x
  23.   #define STM_SECTOR_SIZE  1024 //字节$ s+ o, L7 _. y6 X1 U' k
  24. #else 4 o/ A, h; [6 F, b; J: K5 {
  25.   #define STM_SECTOR_SIZE         2048
    ' p; M; F4 g& }' v  I
  26. #endif
    / T1 I2 K. M& f4 n" t  e

  27. + k$ h; W+ U& A! @
  28. # v2 X/ c; g: P) @
  29. /* 私有变量 ------------------------------------------------------------------*/
    * }. b$ H4 d* p0 c
  30. #if STM32_FLASH_WREN        //如果使能了写 * \: B, e; a9 y# Y8 z  o/ L: \
  31. static uint16_t STMFLASH_BUF [ STM_SECTOR_SIZE / 2 ];//最多是2K字节
    # ^1 Q: a' j" N8 D8 w
  32. static FLASH_EraseInitTypeDef EraseInitStruct;7 f/ E" w5 A7 s0 x& u
  33. #endif
    , ~; N% y: q1 n& ?, y
  34. " A( n7 M' b. J! S7 q! b
  35. /* 扩展变量 ------------------------------------------------------------------*/
    ' k9 e- J: L. D# g, `/ o0 N
  36. /* 私有函数原形 --------------------------------------------------------------*/
    ! C. s$ y9 y4 ]6 N1 s  z
  37. /* 函数体 --------------------------------------------------------------------*/6 E: T$ V- P8 ?6 l- e* F
  38. /**( c& n- U% v/ x3 B( F
  39.   * 函数功能: 读取指定地址的半字(16位数据); \6 z3 {( J( C
  40.   * 输入参数: faddr:读地址(此地址必须为2的倍数!!)
    2 X3 J1 M) t5 M; {7 e
  41.   * 返 回 值: 返回值:对应数据.
    ! @6 _3 K: t  X$ z2 j
  42.   * 说    明:无
    ; v- A, C' G' q+ f0 D# z
  43.   */0 T6 i6 h- X- o' {3 D# l  l
  44. uint16_t STMFLASH_ReadHalfWord ( uint32_t faddr )
    1 c4 v# J  I- X' k  i* ?
  45. {
    $ w1 h% D+ F* u
  46.         return *(__IO uint16_t*)faddr;
    - n4 {/ Z4 b$ C
  47. }
    7 \( M" j7 C! t; X' X
  48. ; k  |& l* t) I8 }: u
  49. #if STM32_FLASH_WREN        //如果使能了写   
    ) {: }" J/ N. P5 _- @
  50. /**
    : }# I' T% S. @) |6 x/ k7 Y
  51.   * 函数功能: 不检查的写入
    % u, v4 j+ P- [
  52.   * 输入参数: WriteAddr:起始地址7 J# f, S% w+ _0 q
  53.   *           pBuffer:数据指针4 T" K$ p  ^* `; G9 v. Y2 ]
  54.   *           NumToWrite:半字(16位)数$ Y! Y. u6 ?' _! \  ^
  55.   * 返 回 值: 无
    0 m0 y% Y) H7 ]/ \/ T# ^# z7 d
  56.   * 说    明:无8 B" r0 d6 C: [3 R; S5 V
  57.   */* b! X$ u% ?) C  r/ l7 H' s$ S6 F
  58. void STMFLASH_Write_NoCheck ( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite )   1 D& N' N& z3 O: z
  59. {                                           
      f7 s8 }4 C  r" t+ u* L
  60.   uint16_t i;
    + R/ y1 _% m9 a; E9 D, Q; O
  61.         5 z7 \# d7 w2 b0 P3 \& E1 q; r
  62.   for(i=0;i<NumToWrite;i++)
    , X, h6 w0 L; ^) U, i6 j  v
  63.   {8 r( Q. S5 o' k) N8 y+ \" k8 w
  64.         HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,WriteAddr,pBuffer[i]);
    # q& u6 m; Q! k) L( L
  65.         WriteAddr+=2;                                    //地址增加2.0 c1 Q, N, U( m& J, q
  66.   }
    . a+ i3 J) R. v! v" I
  67. }
    ( U3 r3 j* V3 V8 a+ E

  68. ! e0 g3 \) V3 l( ^. q' c9 s
  69. /**5 ]& S# d( P" A  O
  70.   * 函数功能: 从指定地址开始写入指定长度的数据4 t; \* G( q& M3 S) e
  71.   * 输入参数: WriteAddr:起始地址(此地址必须为2的倍数!!)
    : o; X% c( u* L0 H# t+ \  E6 V
  72.   *           pBuffer:数据指针
    * L) ?3 @: q9 I9 U
  73.   *           NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
    * h( _8 ?0 Z+ u; C
  74.   * 返 回 值: 无. F4 b: m' _1 ]9 p( v9 }. a* T
  75.   * 说    明:无; w- f" u  L) `  ^! n, m; I4 V
  76.   */) e7 e0 _+ @7 O6 r  e
  77. void STMFLASH_Write ( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite )       
    # r( f0 a: ]7 e) J+ X
  78. {2 L) \, J7 Z; i" D
  79.   uint32_t SECTORError = 0;# K: a4 f( g# V* R* C6 S
  80.   uint16_t secoff;           //扇区内偏移地址(16位字计算)% l5 t4 L, q& `
  81.   uint16_t secremain; //扇区内剩余地址(16位字计算); W* e; _- N8 ~" V! Y4 s
  82.   uint16_t i;
    " |8 L% ]9 D% t) t7 I1 ^/ {
  83.   uint32_t secpos;           //扇区地址
    ) j/ R9 g- v+ h( S8 s2 w
  84.   uint32_t offaddr;   //去掉0X08000000后的地址
    . [1 o5 R+ B0 H6 m; H+ ^  u
  85.        
    5 P8 B' E2 s  ~: ^
  86.   if(WriteAddr<FLASH_BASE||(WriteAddr>=(FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址4 X! \! s1 c8 B* }4 ~! [
  87.        
    7 U8 @7 c. F( I- {$ I+ X, P, ?5 @
  88.   HAL_FLASH_Unlock();                                                //解锁2 v% M2 U' q( ]; O1 A: ?! A
  89.        
    # d- q; s& t( N% i6 Z' ^3 M. {
  90.   offaddr=WriteAddr-FLASH_BASE;                //实际偏移地址.) ]* Z) y' I8 q1 z4 d
  91.   secpos=offaddr/STM_SECTOR_SIZE;                        //扇区地址  0~127 for STM32F103RBT62 m9 y6 O/ G6 u' n1 ?* v/ ]9 G
  92.   secoff=(offaddr%STM_SECTOR_SIZE)/2;                //在扇区内的偏移(2个字节为基本单位.)
    0 s- V9 ?2 A# r8 n/ X7 ~
  93.   secremain=STM_SECTOR_SIZE/2-secoff;                //扇区剩余空间大小7 x$ C$ W1 E. E' x7 U" U
  94.   if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
    ; m; H' @" S4 J8 d5 E
  95.        
    2 U7 F5 i& p* N; p5 k
  96.   while(1)
    0 _) j' \2 Q2 d* G3 y8 D( J- K
  97.   {2 L: h5 {+ |' [$ m
  98.         STMFLASH_Read(secpos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
      M7 F+ X/ e: _& ?, M/ h
  99.         for(i=0;i<secremain;i++)//校验数据! L+ J+ u6 R! {! i3 b. L
  100.         {
    & ]% E% q/ C: _5 e- r& f3 A+ a$ a
  101.           if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除) T# ]* B# {# F; J
  102.         }
    8 q/ e  S7 u5 g0 o, ?& }8 }0 w
  103.         if(i<secremain)//需要擦除
    - x! L8 q! }" P- X6 S5 U+ V
  104.         {
    6 ]' b" u4 y5 H6 I7 Q, r
  105.           //擦除这个扇区
    " \! B: q. h1 V1 F
  106.           /* Fill EraseInit structure*/6 u, A: J+ N+ U6 Q* {/ T
  107.       EraseInitStruct.TypeErase     = FLASH_TYPEERASE_PAGES;
    ' a3 V) \0 z6 q: W4 P
  108.       EraseInitStruct.PageAddress   = secpos*STM_SECTOR_SIZE+FLASH_BASE;
    # V5 q* U, E  b
  109.       EraseInitStruct.NbPages       = 1;/ Y! l7 b+ |* |! T0 m& j
  110.       HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);' f9 o' W; `5 x6 B, e) x) k
  111. - [% w7 u* z1 W
  112.       for(i=0;i<secremain;i++)//复制
    3 z  k& f: U$ ]- V3 [2 ^
  113.       {. z* S1 [# ?; W. D! s# E& C
  114.             STMFLASH_BUF[i+secoff]=pBuffer[i];
    ' |1 {* A. v, H1 @* k/ U$ A+ S
  115.       }+ Q+ t0 S: F1 M
  116.       STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区8 p2 a' q- _- w6 e6 h6 @* L
  117.         }! V* ?( F* D- w! _
  118.     else! A; H; ]% i/ l6 ?
  119.     {
    1 h2 p( H6 G# e; h1 g6 R4 z
  120.       STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.                                   
    / `- c  T. J9 K1 @; v
  121.     }) z+ u* I# c. D3 W0 I
  122.     if(NumToWrite==secremain)break;//写入结束了
    : {$ f9 `0 f- b& [. Q( i+ g( I
  123.     else//写入未结束4 R( G" V4 G  g4 S+ ]; A
  124.     {
    % }( w/ F8 }8 C7 {( O1 q0 O3 A3 J  T) E
  125.       secpos++;                                //扇区地址增1
    + k7 M2 k7 G8 I( D
  126.       secoff=0;                                //偏移位置为0
    4 X" y- H/ }5 N4 V5 _
  127.       pBuffer+=secremain;          //指针偏移0 y" W9 O+ H( S/ m3 {/ j: y
  128.       WriteAddr+=secremain;        //写地址偏移- d5 E+ v7 Y' x- N. z$ W
  129.       NumToWrite-=secremain;        //字节(16位)数递减: d- e) n3 z4 b6 J" y
  130.       if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完5 o. p; m( P9 v8 g- p) b5 O
  131.       else secremain=NumToWrite;//下一个扇区可以写完了' R( z% Z* F: F% R& W% ?
  132.     }
      ~5 F- [/ H9 P* s
  133.   };
    : a) N! n$ ~4 I) V
  134.   HAL_FLASH_Lock();//上锁
    2 {) |/ W: A' g' ?  y: V
  135. }
    , U5 N: u: L% P3 c4 K$ u- C

  136. * b, H2 N( ^5 m: H1 l0 I. {

  137. ' F8 G/ a& \% z( @$ K9 o

  138. ! @0 t0 R- f5 Q& P9 L3 U
  139. #endif& I. p! e; {3 T$ `# v' {9 B

  140. + Y3 n: {1 _' t
  141. /**$ v& N4 f) T& o; p, B9 ^" ~. s
  142.   * 函数功能: 从指定地址开始读出指定长度的数据5 \, ]' J' F, @% l
  143.   * 输入参数: ReadAddr:起始地址  o, K6 x6 v2 }$ A
  144.   *           pBuffer:数据指针- _8 e+ u$ j' c. X$ {9 ]
  145.   *           NumToRead:半字(16位)数
    " u+ p4 N) M; \* L% j# }, G0 s2 A
  146.   * 返 回 值: 无
    : V% p3 {7 ]4 L' x' @
  147.   * 说    明:无
    ( D' l* C# r2 u( o  d; i
  148.   */
    ! t) m& W0 }5 J# f, J/ \3 R+ y
  149. void STMFLASH_Read ( uint32_t ReadAddr, uint16_t *pBuffer, uint16_t NumToRead )          
    2 P& U+ Q3 ^+ B0 ~4 d5 O" S. r' [
  150. {
    ) U' p8 v3 y0 k  i
  151.   uint16_t i;
    4 L/ a* F* s! z9 o, x
  152. 0 r% E+ ?) r6 O$ X
  153.   for(i=0;i<NumToRead;i++)
    1 G+ f# K" X0 T; C- V3 N
  154.   {
    ' F) T, f& K) w+ q5 ^3 m
  155.         pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
    " [9 L8 G1 U) P1 O) Y! @( J9 g) m2 I
  156.         ReadAddr+=2;//偏移2个字节.8 d2 b! I9 }6 c$ x
  157.   }& ?! h0 J3 {5 t: ~1 e. W* P
  158. }
    / `- J# F$ T4 ~
  159. 2 u) u+ g8 K/ J+ L+ M- \2 O
  160. /*
    5 \" x9 i' I1 L! ^
  161. * 函数名:Buffercmp
      ?2 K) U5 [9 E7 ]
  162. * 描述  :比较两个缓冲区中的数据是否相等8 f! F  o7 s9 d- I; ^. H. K
  163. * 输入  :-pBuffer1     src缓冲区指针
    ' F9 |7 ]" \9 z7 G7 l9 e- Z
  164. *         -pBuffer2     dst缓冲区指针1 j/ t; Q& ]' N& \
  165. *         -BufferLength 缓冲区长度; G3 o7 e5 g5 t! V
  166. * 输出  :无, G7 f/ e0 K! K* v4 ?$ E
  167. * 返回  :-PASSED pBuffer1 等于   pBuffer2
    ) N0 ~( B3 u) e- L+ c$ a5 c
  168. *         -FAILED pBuffer1 不同于 pBuffer2
    3 o8 W0 x1 C6 J5 }( @& v* E/ ]8 X7 i
  169. */+ l( f0 m1 j; v/ {
  170. TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength)
    , J- c; n1 ~% ^1 [" t2 h
  171. {% z# [, Y/ k: Y/ B3 V# ~9 m
  172.   while(BufferLength--)
    + h& S1 `$ ?" i# p; L
  173.   {
    ) w3 X. e/ r3 K
  174.     printf("data:%d - %d \n",*pBuffer1 , *pBuffer2);
    3 a9 i+ B+ j. ^  A" K  s
  175.     if(*pBuffer1 != *pBuffer2)
    - m1 o8 ?' ~4 b
  176.     {* X* V8 j- ~$ \* H" G
  177.       return FAILED;/ U& a) U( _; }! C+ L
  178.     }
    ' c/ O1 [+ ?, u" H8 Y) d
  179. 6 ~8 J3 A4 W% u8 e5 |% y
  180.     pBuffer1++;) e: d/ x9 Y, w, ?( S: e1 a
  181.     pBuffer2++;9 L7 b) p, U' L! F! |
  182.   }$ q/ N: k: w+ E9 i0 a0 q5 q
  183.   return PASSED;% d' M9 s1 U& y3 s- n! Z% P
  184. }5 ?0 h1 [1 f* B1 |5 J

  185. 0 G5 U/ R9 K1 H  ]

  186. 1 A0 `/ L% d6 V$ \$ g& }" ]
  187. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码

0 v; i4 O; B9 [. u0 M  O: A3 g3.2 stm32f107_flash.h
) @. @/ ^: {3 [$ s
  1. #ifndef __STMFLASH_H__* ?5 \' d" T' B  z
  2. #define __STMFLASH_H__
    5 a& S$ J- v% `1 ~! ]  T: h
  3. ) Y) Y+ n8 v# y+ X
  4. /* 包含头文件 ----------------------------------------------------------------*/
    $ U9 S/ B0 W; W. `3 M+ m
  5. #include "stm32f1xx_hal.h"0 y) W" d$ O# r

  6. / _2 U  [' p7 S4 F( a0 G
  7. /* 类型定义 ------------------------------------------------------------------*/
    7 b* a# W. E+ u, ]5 r6 J
  8. /* 宏定义 --------------------------------------------------------------------*/
    & o' P+ n4 i9 q9 D3 m# s
  9. /************************** STM32 内部 FLASH 配置 *****************************/
    5 A  a9 m+ a  G$ m  p; r
  10. #define STM32_FLASH_SIZE        256  // 所选STM32的FLASH容量大小(单位为K)
    ; z. T3 L* A7 x( v5 G
  11. #define STM32_FLASH_WREN        1    // stm32芯片内容FLASH 写入使能(0,禁用;1,使能)& `( V/ w4 U8 X1 }# a

  12. $ E; H+ I4 C3 [* Q& J# E+ l& F9 |
  13. typedef enum; k- {* v, x! R( H1 ]! A
  14. {! A' Y. ]  C0 Y9 }
  15.   FAILED = 0,3 P5 l; ~$ _9 s7 P. y9 d
  16.   PASSED = !FAILED! Q% ]' M+ Q' d+ w  K4 D  U
  17. }TestStatus;
    $ I: I- x* ]/ G! N# J0 w

  18. ; E* X& P4 l9 C0 e3 {* }8 ?
  19. #define  FLASH_WriteAddress     0x0803F800            // 写在靠后位置,防止破坏程序7 p  u/ q4 \  p# U& V( Z" g. U
  20. #define  FLASH_ReadAddress      FLASH_WriteAddress* e$ X/ S* S  d
  21. #define  FLASH_TESTSIZE         512                 //实际是512*2=1024字节
    - V# k; H4 l: `# A  X1 ^

  22. 5 G4 P$ ?# ~" n5 r' L

  23. 1 P- X- y* e  R
  24. /* 扩展变量 ------------------------------------------------------------------*/
    3 k: u. f8 Z5 t6 l6 U  }
  25. /* 函数声明 ------------------------------------------------------------------*/
    " n! f- m- A9 S6 c
  26. uint16_t STMFLASH_ReadHalfWord(uint32_t faddr);                  //读出半字
      |4 G# a. z+ C, q4 D& G  G
  27. ' L  T5 G( e0 K+ r
  28. void STMFLASH_WriteLenByte(uint32_t WriteAddr, uint32_t DataToWrite, uint16_t Len );              //指定地址开始写入指定长度的数据( P) D$ ]3 h3 }# m* a  B
  29. uint32_t STMFLASH_ReadLenByte(uint32_t ReadAddr, uint16_t Len );                                                                    //指定地址开始读取指定长度数据6 _: O$ c* Q8 g$ d
  30. void STMFLASH_Write( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite );                //从指定地址开始写入指定长度的数据
    $ j( }+ a) ]* t+ i) R
  31. void STMFLASH_Read( uint32_t ReadAddr, uint16_t * pBuffer, uint16_t NumToRead );           //从指定地址开始读出指定长度的数据
    # B! }, P9 B, y8 D
  32. //static TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength);
    . K) W# h6 K5 _" m2 n
  33. TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength);- g2 @0 `2 S8 h

  34. 1 _' f  f; P2 Z/ t. Y
  35. #endif /* __STMFLASH_H__ */& _* i* r5 V4 l" O, N0 r
  36. 4 Z8 r) ?7 }, J
  37. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码
! N4 ?0 Y8 X+ e! v  t; ~
3.3 main.c
: P3 Z* f6 I- U; @% g) ]6 [
  1. /* USER CODE BEGIN Header */
    % \% g: t* r$ ]( X( d' d
  2. /**
    8 Y  _4 _5 \/ W  ^0 T- z
  3.   ******************************************************************************5 n2 J" N: k2 g* r9 O' P8 W# Z2 _2 y6 w
  4.   * @file           : main.c, L# W  h0 H9 {- S  }- o4 u! W1 K  ^
  5.   * @brief          : Main program body: u+ p; j( v3 s; \" W$ [1 j
  6.   ******************************************************************************
    1 B1 [5 Z( u* H+ P+ g1 a* e- p" ?
  7.   * @attention7 e! H5 s% v/ B0 c: ^( ?5 d
  8.   *
    ) i0 i  m0 f$ g4 |8 F4 v
  9.   * <h2><center>© Copyright (c) 2019 STMicroelectronics.
    3 Q' S0 B, g4 D! @& W. p
  10.   * All rights reserved.</center></h2>/ g& r! j! _) c% C9 ~" r
  11.   *" G1 t# T9 w: b6 w' ?  {* X! R
  12.   * This software component is licensed by ST under BSD 3-Clause license,4 v6 r* R) h6 x- S' h; P/ k* f  d
  13.   * the "License"; You may not use this file except in compliance with the
    2 {: I" L' R+ U, m
  14.   * License. You may obtain a copy of the License at:% r6 s6 l( Y/ j2 k( F* F
  15.   *                        opensource.org/licenses/BSD-3-Clause
    ) {# K0 d6 W" q7 Q- G
  16.   *8 ~7 C3 P! {) J2 [( p
  17.   ******************************************************************************
    ! {! f& q8 }! R& A6 ~' {
  18.   */  W8 p: s8 J6 Z
  19. /* USER CODE END Header */
    ' \+ F/ V6 `# J. [, D

  20.   z0 J/ I$ I# J6 T$ |, g
  21. /* Includes ------------------------------------------------------------------*/& f5 Y. e! z; x: p8 G% K! U
  22. #include "main.h"- l" S$ F0 W8 u$ A
  23. #include "can.h"
    + x4 U) |8 @; H  @1 g, D
  24. #include "dma.h"
    : [% s9 C- r  D0 T
  25. #include "lwip.h"1 p- i  g, n4 d5 z% \" [( F
  26. #include "usart.h"7 I" v  U( x' y  @/ ]
  27. #include "gpio.h"
    , L: q; d2 \) t0 x' y! A4 Y
  28. 4 ^+ v, f* Z9 r8 Y* s* n
  29. /* Private includes ----------------------------------------------------------*/" M4 n: L% n) Q( F- R
  30. /* USER CODE BEGIN Includes */3 F5 J% w- X- G) y
  31. #include "string.h"
    : J  d9 x7 g9 }5 }9 ?- W8 b0 u
  32. #include "tcp_echoclient.h"
    - r/ C& ], c8 v' J5 O) _* ?. Q: h$ {0 g0 L

  33. 8 P; _( j. l* \
  34. /* USER CODE END Includes */( E2 W2 F% N7 C/ f7 Z6 |

  35. : g; [) ]$ x# G9 o) H) K0 q) K
  36. /* Private typedef -----------------------------------------------------------*/
    ( z. w( x1 ]" F  R9 Y& ?
  37. /* USER CODE BEGIN PTD */+ T; j8 h. v- _* T. D

  38. 9 i7 K4 q( n( x7 ?" E! w4 {
  39. /* USER CODE END PTD */
    $ i4 g0 M" ^9 [) h3 q' h

  40. 7 A) I! h7 o2 d) h$ G. R
  41. /* Private define ------------------------------------------------------------*/
    8 o4 }1 f+ z8 U7 D! E
  42. /* USER CODE BEGIN PD */* C( e* B, n, w$ ?- P
  43. #define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))0 e8 w% S9 n% i6 `6 F) J
  44. - |" \# C+ u8 a0 r* l
  45. /* USER CODE END PD */
    2 \( c* u7 a# l) z, i( r

  46. 4 Q1 q& u7 i; N% \* H8 G
  47. /* Private macro -------------------------------------------------------------*/: }. O- N$ ?% O) @. z0 T
  48. /* USER CODE BEGIN PM */7 B0 i: U' ^( k9 S. f
  49. $ O4 m0 K6 G  ^! I- n& \
  50. /* USER CODE END PM */6 j- q! F3 ?8 a9 t; E

  51. 0 x2 s1 c# a- s
  52. /* Private variables ---------------------------------------------------------*/" j0 h6 |# \  w, R* n, f

  53. * D  N( {3 ]! C! A5 k3 H: b
  54. /* USER CODE BEGIN PV */
    # X& F" O& W) @7 a
  55. uint32_t  counter_10ms, counter_50ms, counter_100ms, counter_200ms, counter_500ms, counter_1000ms, counter_2000ms, counter_5000ms, counter_10s;
    5 V5 M/ C* `, g# Q. q# E0 e& m4 Y
  56. uint8_t flag_1ms, flag_10ms, flag_50ms, flag_100ms, flag_200ms, flag_500ms, flag_1000ms, flag_2000ms, flag_5000ms, flag_10s;
    ' l& v9 [, C0 y1 d  \) f. h
  57. uint8_t b_KeyNumber;
    " l4 h  U. a8 k' x+ j
  58. ! }6 b; W2 O1 t2 Z3 w" W
  59. uint8_t a_DtuInBuffer[100];
    * {  j4 H, S% ?4 B* @6 i. e
  60. uint16_t b_DtuInBufferRxCnt;
    # Y: s5 h2 t$ b9 ^( e& ]+ y# Y

  61. 9 T, Q% n$ w( Y3 V
  62. uint8_t a_DtuOutBuffer[100];
    5 g+ k) M4 {5 D- V2 A! z2 W# G
  63. uint16_t b_DtuOutBufferRxCnt;
    , `8 o% L5 a2 k( F% Q: M

  64. 6 c) \* [& v# r' u5 g5 [3 k' J
  65. struct netif gnetif;
    4 r  c4 R6 o: }, F8 r) ^
  66. extern struct tcp_pcb *echoclient_pcb;
    ) X0 F+ C5 c2 l( X9 c8 ]
  67. uint32_t status_TCPProc;9 g) _; E! }$ l$ w0 J7 d) ^8 X  d

  68. $ G3 ?0 ]1 Z) ?- q3 o# o( D

  69. / f1 U$ D9 M$ k* h, j& w, [
  70. uint8_t a_SocketConfig[7];
    % p6 |, |$ e* f/ I& @
  71. uint8_t a_SocketHeartBeat[60];: a, z6 J* D, R- b5 a! G: i+ s3 X7 \7 P
  72. uint8_t a_SocketHeartBeatInterval[2];2 l3 z) x- f3 R; m
  73. uint8_t a_SocketRegister[60];
    - K. S, ^1 T" g# h
  74. 8 f2 f% g+ H+ e9 S  Q" v# ~$ m& B
  75. uint8_t a_DtuInOutConfig[2];/ C* Y4 b6 p& ]2 `3 t" o1 M# Q

  76. ' \4 Y7 H6 ~! p1 J
  77. uint8_t b_WifiMode;
    8 X) O2 H5 g$ _  |+ a
  78. uint8_t a_RouterSsid[20];
    - t; h# t* w" ^6 X1 g4 z* ~
  79. uint8_t a_RouterPswd[20];
    ) Y+ i0 P/ P. ]1 u/ V5 ~9 f' g

  80. ! U+ k& u5 F/ d- o5 z6 D# x7 B
  81. uint8_t a_Rs485Config[5];
    - G; r2 X4 ], Y- ?' y6 {+ Z
  82. uint8_t a_CanConfig[5];) s$ q0 b, u! H
  83. 8 q' y6 i/ S7 l: |
  84. uint8_t flag_DtuConfigUpdate;7 d( j% K: q0 z$ Q4 V
  85. uint8_t flag_DtuEthReady = 0;  o0 R* ?- A. Y" U
  86. : E7 L' S3 d) @. Y* f
  87. uint32_t b_HeartBeatPackageCnt = 0;
    4 V1 D# d% K& ^' j
  88. 9 M# ^9 \- [4 c! {! S' e2 f
  89. uint32_t b_232STM32ParamConfigBusyCnt = 0;        //尝试通过串口和STM32交互时候,会让出相应时间,优先处理7 X6 x" t# P. l' s# h0 B

  90.   u% b6 ~/ H, p" g* r+ L6 d
  91. /* USER CODE END PV */, d7 U: }; A, ]

  92. 5 \3 C$ _4 c+ [% O) o7 q! {2 [4 w
  93. /* Private function prototypes -----------------------------------------------*/+ i3 b. {; P& W6 [  d
  94. void SystemClock_Config(void);7 m; U- P' ^- B; J/ S3 s8 C
  95. /* USER CODE BEGIN PFP */
    + z. s. ~$ z2 B  j2 ~& [& i
  96. 7 E: P' e- V: o; ?* r3 y! w
  97. /* USER CODE END PFP */
    $ v2 ?4 s; F' k9 A0 X- a6 d

  98. 8 ]2 P/ p9 W) S
  99. /* Private user code ---------------------------------------------------------*/& m, o0 G: t7 {0 o; z" _9 t1 Y2 @
  100. /* USER CODE BEGIN 0 */
    & W) U( ^# m' D+ ~+ _9 `- N
  101. void Task_HeartBeatPackSent(void): @. ?2 N  q( p. y# y* `
  102. {- {: E6 ^* g/ ?* \- K" H
  103.   uint16_t b_interval;
    ; V9 `) S; M% W  _% W: Q

  104. $ W, J) Q& D# I) Y: t4 q3 O/ {
  105.   b_interval = (a_SocketHeartBeatInterval[0]<<8) + a_SocketHeartBeatInterval[1];1 W4 O& T6 _" H# F6 a

  106. ' J4 \. J- ?- [7 y% j+ z
  107.   b_HeartBeatPackageCnt++;8 e) z, z" j$ w5 l2 ]
  108.   if(b_HeartBeatPackageCnt>=b_interval)
    + n  t' z4 Q0 I/ `( Y
  109.   {9 x" h9 s) z. a8 H/ `6 O, s9 i% C
  110.     b_HeartBeatPackageCnt = 0;+ c( v' r5 |2 W$ B$ Q

  111. ' s' s' S7 i2 s2 u0 x6 D

  112. " ?1 Q% D9 N' k
  113.     if(a_DtuInOutConfig[1]==1)  O' p$ m7 O8 A5 H9 m( ~
  114.     {/ T  _6 S' {# Y. Q
  115.       if(flag_8266DTUReady==1)
    ! c8 x0 h( }. O+ C
  116.       {% A4 {" c, Y0 y% T- z# {* [$ l& H
  117.             HAL_UART_Transmit(&huart3, a_SocketHeartBeat, strlen((char*)a_SocketHeartBeat), 100);5 z$ E7 n, |2 J6 c7 H9 X, y0 \
  118.             printf("\r\n");
    : \* i  j. @7 j3 n& M0 O/ A
  119.             printf("\r\nA heart beat package is sent.\r\n ");: z" }3 D, Z6 B& d! N9 k( T
  120.       }' ~4 z$ K5 j8 a0 v1 V
  121.     }: m/ Q% {0 g  x. l
  122.     else if(a_DtuInOutConfig[1]==2)2 c" [7 ^% P" r8 J0 |
  123.     {: Z, y  _" J2 Q$ D; _
  124.       if(status_TCPProc>=2): R7 @. s$ j( k1 k( H
  125.       {
    + X. G# Q# z3 c3 S
  126.             tcp_senddata(1);
    . r3 Q# @$ A; r  G- T/ Y- ?
  127.             printf("\r\n");5 ?3 T  B5 f  D: I7 w  h
  128.             printf("\r\nA heart beat package is sent.\r\n ");/ Z) w$ Z# ^$ [! V& i* k
  129.       }
    ; c* C& h. U6 S* {: S4 B) b' D- b
  130.     }3 r7 ~( z& @3 ]4 o
  131.   }
    . B: A) i. o; P- z- W
  132. }0 e8 g6 Y& M) \
  133. void cleanDtuInBuffer(void)4 Z' f( }: b0 ~! {! H: D
  134. {# }- z- `0 [. t+ \
  135.   uint32_t i;& q) Y7 {7 a2 {* s' d! p# B
  136.   for(i=0;i<b_DtuInBufferRxCnt;i++)+ ?. Z8 S+ p% `' f) ?
  137.   {. n& `- [, R0 e7 @; _
  138.         a_DtuInBuffer[i] = 0;) O3 ^* P$ i+ O8 L
  139.   }6 h& @+ @! Y8 q7 g5 ~/ ]. f, ^* S
  140.   b_DtuInBufferRxCnt = 0;
    & K/ h# P' ]: [; q5 V! ~
  141. }- S0 ?' j! R* q/ ^# `* g. G
  142. void cleanDtuOutBuffer(void)# |/ |' t; w% }
  143. {0 e7 X2 ^4 o/ u/ W3 P
  144.   uint32_t i;
    : q( E; j* i" T) V; P
  145.   for(i=0;i<b_DtuOutBufferRxCnt;i++)
    - \2 t$ \7 y- L0 t
  146.   {
    . g- R  R' R% z1 P0 {& r+ a
  147.         a_DtuOutBuffer[i] = 0;
    & s* M  Z0 ~1 O4 X. q' _; t& y$ T) v
  148.   }4 Y1 W3 t) T& z5 L" h: d! B# u
  149.   b_DtuOutBufferRxCnt = 0;+ @1 Z6 ?9 r2 P
  150. }  F2 j  P6 c; e0 _1 ~
  151. $ H7 ~6 H) O3 \+ R
  152. void Task_DirectTransfer(void)
    . ^- ?) N& C* i% d* e
  153. {
    2 [6 w6 _4 B9 T" W4 N! o
  154.   uint32_t i, k;
    - ~. j( _" _! s2 D, `1 Z3 Z
  155.   //把数据输出到以太网或者WIFI' T7 f& R9 K2 x( i# I8 W# O" @$ ~: Y
  156.   if(a_DtuInOutConfig[1]==1)
    . ]- v$ `! E) r1 k- [6 A
  157.   {
      `9 ~# L! G# [- r
  158.         if(flag_8266DTUReady==1); @  `2 k  i0 [* w7 n
  159.         {
    4 J% A, y/ c4 a& s( {5 c( @
  160.           if(b_DtuInBufferRxCnt>0)7 Y3 u% m- g0 D% z' [* e  l
  161.           {6 s( m0 t8 H( W# o' B2 z' d
  162.                 printf("\r\n");
    ) s& S/ G5 s) m2 T. q3 V6 y7 |
  163.                 printf("\r\nData sent to Wifi: ");* E# N: }; o# ^4 N5 e5 s
  164.                 HAL_UART_Transmit(&huart3, (uint8_t*)a_DtuInBuffer, b_DtuInBufferRxCnt, 100);
    - n$ Q' P* _0 n: o, d/ `3 P
  165.                 HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuInBuffer, b_DtuInBufferRxCnt, 100);        //debug9 K- H$ k8 }# V- o- N; }
  166.             cleanDtuInBuffer();
    + ]! g/ u- M4 ?2 n3 C9 t
  167.           }/ S, @3 ^5 O* {. B
  168.         }
    # ?3 o# E3 ?1 P
  169.   }1 p# {+ g" Q/ x
  170.   else if(a_DtuInOutConfig[1]==2)
    0 A+ J" z" t# ^4 b( C
  171.   {" b0 E5 l; x& r1 d: N
  172.         if(status_TCPProc>=2)
    ! w" l/ V# n5 ]
  173.         {. U+ t' K# p* _. J/ @8 ~6 |
  174.           if(status_TCPProc == 2)
    . D3 a1 R3 t8 b" B7 p
  175.           {" B% s% _/ n6 v' X, u" E$ A
  176.             tcp_senddata(0);        //专门发送注册包
    ; a; Q2 d0 m8 i# t# @, A" a
  177.           }! ]3 I9 t) B1 K* F( Z5 A
  178.           if(b_DtuInBufferRxCnt>0)
    ) z- S; g5 p6 Z2 |* E* H
  179.           {) H4 N3 _5 g- k* I" {
  180.                 if(status_TCPProc <= 3)" i! d9 ]  E& H' @- ]( j
  181.                 {7 y0 j2 T" ]# t
  182.                   tcp_senddata(0);/ ^' |& V- a+ \
  183.                 }: G1 _6 ]  r; s
  184.                 else7 Z: j0 W9 Q( u5 r/ f" w' Y0 i
  185.                 {* @6 N$ }5 v- c4 W7 I- t3 \0 ]7 l; L
  186.                   status_TCPProc = 0;0 f, Q7 H3 o0 B3 c  ]
  187.                 }& K. |7 [  r5 g5 S8 X
  188.                 cleanDtuInBuffer();4 u4 x" G" \- a$ R1 {/ S1 m
  189.           }$ R. P* C6 y0 X3 h8 G5 E) p- ?& q
  190.         }+ J$ G; M/ T9 G& @
  191.   }+ x8 M6 m/ R3 u* C; ^! I: `! L

  192. 1 x1 z8 t4 L5 P+ Z" s
  193. 0 u! s9 O3 o0 k9 ~
  194.   //把数据输出到RS232,RS485或者CAN, a  B. G0 L7 l; ]
  195.   if(a_DtuInOutConfig[0]==1)* K5 A  ], Q( O7 E6 ~- m
  196.   {: {1 k3 ?( O6 I% Z$ z
  197.         if(b_DtuOutBufferRxCnt>0)
    # `" F. T) O' F" c5 r
  198.         {% I$ [* M. c, q2 B! {
  199.           HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);, N# x6 u9 y$ p) H( `; |% w4 |
  200.           cleanDtuOutBuffer();( a+ y2 _/ C0 c
  201.         }, N& O8 e, B* N& R* [' ^& d' ?
  202.   }" C7 }1 p! x' Y+ L. z" i" i
  203.   else if(a_DtuInOutConfig[0]==2)
    8 Q% J& B9 [2 b
  204.   {( _5 f( A! T* D
  205.         if(b_DtuOutBufferRxCnt>0); W0 b/ I( g. ]; {
  206.         {
    ; d; V  C9 X4 W& A
  207.           printf("\r\n");
    * ^- q  [  n- M: \
  208.           printf("\r\nData sent to RS485: ");  D# J9 G/ L+ x
  209.           HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);//debug
    8 ]/ Y: \- N4 F4 E1 K7 [
  210.           RS485_TX_MODE();
    / U( a; o0 X! c8 C) J
  211.           HAL_UART_Transmit(&huart5, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);
    / e9 B: v5 `8 y5 r3 Q; h& S  }
  212.           HAL_Delay(1);) }- B: v0 @6 v. L
  213.           RS485_RX_MODE();9 i. F. `5 ^4 [
  214.           cleanDtuOutBuffer();2 ?0 v0 b8 O5 |, X2 K5 M
  215.         }, W3 M, i" R9 x! Y! i' |. R
  216.   }2 r! m4 h4 o/ r4 b0 H: _
  217.   else if(a_DtuInOutConfig[0]==3)7 z( I2 Z8 z+ U/ Y
  218.   {4 D9 y" ]# A& i% s2 w2 v; z
  219.         if(b_DtuOutBufferRxCnt>0)
    # Q+ `& c) L2 ?4 k5 O
  220.         {
    ( I8 _) ^4 [9 H
  221.           k = 0;& L8 v% c: r. Z! R$ T: \1 J
  222.           if(b_DtuOutBufferRxCnt>8). v5 }9 I* e, `7 Y# v& t
  223.           {3 g1 @9 t9 E: R- O" {6 Q
  224.                 for(i=0; i<8; i++)6 G" E/ }  t" v$ N  N% \6 |+ Y5 R
  225.                 {
    * v6 A$ f) c. F3 S2 i, y7 ]1 t6 a: v
  226.                   Can_TxData[i] = a_DtuOutBuffer[i];7 w7 E' D& m9 [9 ^( J8 A
  227.                   k += Can_TxData[i];- U; f% z' N2 t5 e
  228.                 }7 }" {9 S  s+ s6 Q! F* a5 U, c
  229.           }) L# O2 o/ X. Q. L6 s
  230.           else
    * z/ Y5 I( J: S' U7 m$ ?
  231.           {: z/ |- w, l2 A. C; W  W! l% P
  232.                 for(i=0; i<b_DtuOutBufferRxCnt; i++)- H  j) h: J, u
  233.                 {
    # M  Z# v% W3 N  r/ c) {
  234.                   Can_TxData[i] = a_DtuOutBuffer[i];" S1 ]1 d, N6 O3 ^6 I* ]
  235.                   k += Can_TxData[i];9 t. ]. H) Q5 }$ W1 I0 V! V& m
  236.                 }
    ! g; Q' j6 A: M! X* w5 ]3 ?
  237.           }
    8 M6 y* Q* m& ?7 Q; x  {, P: _
  238.           if(k>0)9 Z  X3 c* D; t6 c+ E; l
  239.           {1 e$ H+ @" q6 K- U; v
  240.                 if(b_DtuOutBufferRxCnt>8)% J6 y4 j! M  ~  H$ |& D
  241.                 {
    2 [* f+ E, Q+ v( p
  242.                   Can_TxMessage(0, Can_TxHeader.StdId, 8, Can_TxData);% M+ U+ n1 X' Z6 `; l9 X3 s
  243.                 }
    - e! m, p5 @4 W, ~6 Q
  244.                 else, j0 b* ?- _7 ~7 x) r) ^
  245.                 {
    : H/ n0 ^3 I* x' R
  246.                   Can_TxMessage(0, Can_TxHeader.StdId, b_DtuOutBufferRxCnt, Can_TxData);
    : N! Q1 s1 }$ N$ G5 \
  247.                 }) ^; J" D) ~( D! ?: Y3 E9 o
  248.                 ArrayLeftShift8bits(a_DtuOutBuffer, &b_DtuOutBufferRxCnt);9 _0 v' |: Q8 W& q9 S, g, _
  249.           }
    0 Y" M% `6 z) p- {
  250.           else# Q6 N& X2 ^4 T2 H/ k  y
  251.           {
    2 a  W7 R4 Z" E5 O8 Z: a8 P
  252.                 b_DtuOutBufferRxCnt = 0;
    1 T. D; m; ^/ p" e- N; s7 O
  253.           }1 c3 P0 K& I) t. |& q
  254.         }
    $ M- k- C' H# `2 ^
  255.   }# a1 j8 k% O6 U8 \: N
  256. }
    3 t6 l& }& E# f7 ], n# C8 g' |5 ~
  257. void Task_DtuRedoConfig(void)
    ( j- X% T4 N% J4 d" G9 `  \& X# Z
  258. {: Q, s" e* m9 p" j* [2 r
  259.   if(flag_DtuConfigUpdate==0)8 s- u0 M! D: z  b
  260.           return;4 r. L, G' ^: s$ a  E# X

  261. / F/ r2 Q7 a+ m$ A3 i
  262.   HAL_Delay(10);
    " a4 ^! M  _" ]  K- J6 f
  263.   printf("Re-initialize ETH, WIFI module, RS485...  ");. {, Y8 q+ V) v! F5 ]+ r8 \1 u) S
  264.   //ETH:
    3 c0 R- [/ O, f9 J
  265.   if(status_TCPProc >= 2)
      X6 `+ v. n+ v
  266.   {8 s8 E' x8 b5 [4 m
  267.           tcp_echoclient_disconnect();- [+ L9 _/ z. ^" G. _; C
  268.           status_TCPProc = 0;4 j, q/ r( Y: c- S- Z
  269.   }: A# ^+ L) p% j4 I# U  s8 R( S# d' x
  270.   //ESP8266:
    : u: t* |( ?% b# z$ e+ M5 m
  271.   if(Status_NodeMCU>=6)
    / ?7 _- P" D3 ^
  272.   {
    : V7 `! ?/ D: W) B9 h) p0 G
  273.           sprintf((char *)a_8266TxBuffer, "+++");                //esp8266 接收到这个+++会停止透传模式4 U+ H9 G! L, N4 U! M- b
  274.           HAL_UART_Transmit(&huart3, (uint8_t *)a_8266TxBuffer, strlen((char *)a_8266TxBuffer), 100);% L. W3 Q: Q4 l4 d) s! \% O
  275.           Status_NodeMCU = 0;) S# O5 |+ g! N5 Q0 s
  276.           HAL_Delay(100);
    8 W8 h% O  Q" O7 E+ @/ {
  277.   }
    ! D5 w9 {' f9 m+ `( f: f9 S
  278.   //4853 b1 Y  w" R- h! q& \: q, C1 q7 c: T
  279.   //MX_RS485_Reconfigure();
    9 K7 C5 G/ G9 H# O9 m, T
  280.   printf("Completed.\r\n");
    9 G4 a1 o; F' p
  281.   //
    2 C# e7 Q  B; r" S/ p& L" N6 K- w$ U) @
  282.   flag_DtuConfigUpdate = 0;- N" S5 B4 {# Z) A" ^  v

  283. 7 B& c/ z; Q: r6 h2 w
  284.   HAL_UART_Receive_IT(&huart1, &b_232RxByte, 1);  @$ {: }0 w6 E$ x& y' [
  285. }2 |  i5 ~+ H) D& \
  286. /* USER CODE END 0 */
    # s5 b+ H. [% S# K( d8 ^
  287. 5 _% X1 }- G# D! Q' F
  288. /**
    0 U0 Q2 x: z4 o) N4 C9 E; Z- y: Q
  289.   * @brief  The application entry point.
    ; _. Y) Q6 y9 \9 @7 C1 T
  290.   * @retval int+ F- C  O* `% O  H2 {( ^
  291.   */# X3 m% B6 j! ~- Q
  292. int main(void)1 O8 S- e2 ^1 ]5 }3 ?: U
  293. {0 L- N* k' n" r$ @, m' V+ }
  294.   /* USER CODE BEGIN 1 */
    6 [. N$ C# P; o# s7 G1 |

  295. # m8 K4 V* ]2 g" {
  296.   /* USER CODE END 1 */
    - [% {0 G3 Q2 X6 }/ @8 ~; H. i% `
  297.   0 w* t: }; |  i! w- |
  298. # J  }8 H7 _$ Z) ]
  299.   /* MCU Configuration--------------------------------------------------------*/
    ( g8 `, [" f. w- c" ?
  300. ; m( m1 j1 w, i& W
  301.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */  _( H4 S5 p( @' ^
  302.   HAL_Init();
      u+ ]8 r7 r9 v. i, ?; W

  303. & g+ @" Q# {6 K& G- M9 ]" c
  304.   /* USER CODE BEGIN Init */
    # Z7 n5 m3 C3 b9 M0 h" M& i: ?0 W

  305. $ v5 X* v( t6 H0 Z
  306.   /* USER CODE END Init */" I( `! C; @; n# h; r' K
  307. - h* b  T& f2 l5 a* @
  308.   /* Configure the system clock */
    + K- K' F7 a% @3 F% K! u7 g# @9 t
  309.   SystemClock_Config();
    2 O& r% I6 u" x8 `
  310. 1 g0 r- u' b/ o1 f0 F. z( R+ x
  311.   /* USER CODE BEGIN SysInit */
    + k# d7 t( {# l- X3 K4 d. ^$ K
  312. " O" N: s. [; y
  313.   /* USER CODE END SysInit */( ^1 a6 H7 o( B% C, n! F
  314. $ U* s; ~/ V) N# [5 l, z6 }* [3 W' r, M
  315.   /* Initialize all configured peripherals */& j; w( C- O7 @. I. W& j
  316.   MX_GPIO_Init();% D5 J* A- Q" u! l& d+ |
  317.   MX_DMA_Init();5 ?7 i" O' Q3 N6 j
  318.   MX_USART1_UART_Init();
    9 S& S" m. r. V! h! r) X) ~8 w( W
  319.   MX_USART3_UART_Init();" D$ y! ~- P5 o* k
  320.   MX_CAN1_Init();
    3 R! p, w( v1 g" s0 B- E/ s
  321.   MX_UART5_Init();
    / @1 c- |7 F/ m
  322.   MX_LWIP_Init();
    ' m/ o% t0 U; O* |/ r
  323.   /* USER CODE BEGIN 2 */3 Y5 y3 Q# A% o

  324. , p- w/ [. H# J- [
  325.   RS232Interact_Init();# K0 \( N7 }' c- n9 u, Y# g
  326.   printf("Hello. STM32F107_DTU project: DTU. All in one.\n");4 @  L. G% F$ s
  327. 7 }- h1 r% x2 f! k" b! s+ Y
  328.   HAL_UART_Receive_IT(&huart1, &b_232RxByte, 1);5 V$ F$ V" g+ ?' e, m- y2 j) a% W! u
  329.   HAL_UART_Receive_IT(&huart5, &b_485RxByte, 1);
    ) r* P7 ]7 X: K% ^) C( {

  330. % Z. T: F" c) p. L! r; ]- G
  331. ' }0 t6 V4 c8 @6 X- H
  332.   sprintf((char *)a_8266TxBuffer, "+++");                //esp8266 接收到这个+++会停止透传模式6 n/ M0 N7 ]5 K1 f
  333.   HAL_UART_Transmit(&huart3, (uint8_t *)a_8266TxBuffer, strlen((char *)a_8266TxBuffer), 100);) u3 P+ X  _0 X! q2 b
  334.   Status_NodeMCU = 0;
    7 O' _. P# a0 O, k
  335. ) Z3 ~: A3 o2 f" x, I; ~( m' R
  336.   status_TCPProc = 0;
    / _# S5 k" S4 {; g; \& i3 y/ j5 l
  337. 3 o- Q7 S8 ^9 Y# N$ q2 a2 B
  338.   RS485_RX_MODE();
    6 c' E9 ]. \- ]; Z: w
  339. + ^2 n/ }* u0 f) _% v9 m
  340.   CAN_Config_User();
    0 _" X2 l+ L' n  {. u( Y/ C

  341. ( v- s  i8 |* Z" X+ T) w9 M

  342. : r9 n* `6 I0 n( f
  343.   /* USER CODE END 2 */
    6 b( i+ t( k/ Y6 m# W

  344. & k% O% ?- ~' h$ a
  345.   /* Infinite loop */
    ( B: r( x, v  a7 ?5 P! Z0 l
  346.   /* USER CODE BEGIN WHILE */" l: t% e+ b5 T4 k/ j+ ~
  347.   while (1)0 n" c6 R3 P. |! F
  348.   {
    7 K+ x* o+ z5 S1 T5 p; z
  349.         if(a_DtuInOutConfig[1]==2)
    + z1 V, Z: ]. H  X. H4 X
  350.         {2 [. M/ K: J4 t
  351.           MX_LWIP_Process();
    0 n$ q) ~6 U6 H6 ?' I
  352.         }
    4 _# v. E7 E% P  n- \4 |6 f+ m
  353.         if(flag_1ms ==1)
    4 a( d+ x4 F0 h  [+ X0 B* E
  354.         {4 Y/ h6 ?/ m1 S1 @9 {6 j8 D
  355.           flag_1ms = 0;
    % b- W: A, B$ {: B5 u1 }- o  ]
  356.           Task_232PC_Interact();  W- H8 |: k5 H6 H3 r
  357. & O1 X* m$ x: E
  358.           if(flag_DtuConfigUpdate ==1)
    8 R) F/ s9 m% ^1 u. R) j& j9 C
  359.           {, ]! f7 |0 _+ h9 q( N# ~
  360.                 Task_DtuRedoConfig();: B: P, Q% Z, m  g9 R% A+ G
  361.           }/ z1 e4 H2 K4 h
  362.           if(b_232STM32ParamConfigBusyCnt>6)
    3 Y. O; _0 k' a; J" g6 g( \
  363.           {
    # x/ E; h( K9 R5 [
  364.             Task_DirectTransfer();
    9 N' l' p$ O* ?' W3 }/ v
  365.           }' x) j. |( }/ {  U0 p
  366.         }
    4 B5 a' R3 g" w% t& p3 x+ z; k4 T
  367.         if(flag_10ms==1)
    ) g$ i- F% F/ e7 z5 V6 u- y0 l
  368.         {! J+ d. Q5 N# Q0 ^$ J
  369.           flag_10ms=0;
    4 u& \, e. @$ Q% \& n: _1 R
  370. . E. p  V. K' d% M6 K
  371.         }
    , A; C& m  Z$ K. _5 M8 f
  372.         if(flag_50ms==1)        {                flag_50ms=0;            }
    + r5 g' S, T6 Q3 W
  373.         if(flag_100ms==1)
    8 d. P9 L3 ]- _/ a8 E- K4 J
  374.         {2 X# p% L  \; u& r9 ^  `+ K2 W  R" s
  375.           if(b_232STM32ParamConfigBusyCnt>6)5 d) ]& x+ l( a
  376.           {
    * a5 u- D2 n, d5 I
  377.                 if(a_DtuInOutConfig[1]==1)
    , X" i% Y( g" i3 d8 ?8 L" U) x
  378.                 {
    * i, [" s2 P; S6 p" ^: I
  379.                   if((flag_ProcNodeMCUActive ==1)&&(status_232PC<12)), g2 W9 c' Y% t6 ]. ?- v
  380.                   {
    / H* y5 M0 B) L; T( Q
  381.                         Proc_NodeMCU();
    4 q5 F; e. C( [" D7 N
  382.                   }2 q  j/ J3 c% L5 ?/ `
  383.                 }
    . l6 E. ]2 V2 H9 ], t% R
  384.           }
    9 q) h3 P) ?7 a/ e5 a/ X# M
  385.           flag_100ms=0;
    % L. c, S- W# m! n  p
  386.         }
    5 z/ H/ p4 R' X8 v5 s2 M  `0 U
  387.         if(flag_200ms==1)        {                flag_200ms=0;            }9 p" k7 b- Z6 y+ C0 K6 i6 P
  388.         if(flag_500ms==1)        {                flag_500ms=0;                }
    5 ~5 c: h* h- h
  389.         if(flag_1000ms==1)
    1 r/ S  X9 e# A8 K1 ~
  390.         {  y4 Q3 J8 C! w+ U
  391.           flag_1000ms=0;
    - {5 v8 k" M, W1 A' ~6 r+ t
  392.           HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
    # F9 l$ S% U  Y4 i! y1 E
  393. " w5 g' q7 \8 X- W5 b0 {" q& h8 _& _
  394.           if(b_232STM32ParamConfigBusyCnt>6)
    4 b& r9 B- w: N5 ~1 z! s
  395.           {
    % m2 ~/ n+ i  S' p
  396.                 if(a_DtuInOutConfig[1]==2)
    - G2 A) S, B9 X- j, U. ~
  397.                 {! c. t4 m. _+ |; i
  398.                   if(status_TCPProc<=1)1 o  {) J8 h2 T/ V1 o
  399.                   {2 x7 {- h6 t3 \# B
  400.                         printf("connecting to TCP Server...\r\n");
    $ ?7 v. o: r  _. ^
  401.                         tcp_echoclient_connect();9 J' b- o% ^: y
  402.                   }
    , i( b8 t' g% T: Z8 n
  403.                 }
    8 x( \: b6 \/ n! q$ y
  404.                 Task_HeartBeatPackSent();
    ( R& J& c  O- I& \7 n
  405.           }
    4 E3 X: L& t; u$ M! L$ z  A
  406.           if(flag_ProcNodeMCUActive ==0)/ i) p' i, @$ e, Q, H6 j- m  J
  407.           {
    7 G# y9 @$ N& x: J
  408.                 flag_ProcNodeMCUActive = 1;% V$ W. t% j/ W* e
  409.           }
    ) e: S# _1 B' ]6 C$ a
  410.           if(b_232STM32ParamConfigBusyCnt<80)
    . P$ |: G2 T9 h$ Q! C: o2 s
  411.           {
    5 b9 y( t1 R7 {4 Z" e2 v3 u
  412.                 b_232STM32ParamConfigBusyCnt++;. A+ i. h/ i, h0 d/ [
  413.           }
    $ h7 k( S) E4 }# w( I' H/ F4 }6 x
  414.         }0 j1 j' U- N& H( k9 o5 w
  415.         if(flag_2000ms==1)
    % Y' a. U& H5 r
  416.         {7 V& a* }- S: ~( }- b
  417.           flag_2000ms=0;  G2 s9 `9 ]  W& F0 W
  418. 6 H% l( e& X) d: k2 g
  419.         }
    ! s3 E5 f9 t0 _& a0 W) t& l+ P5 c
  420.         if(flag_5000ms==1)& {9 ]& M, m/ k# @0 \
  421.         {. W, H" B" s" s3 I$ l6 p6 l9 z
  422.           flag_5000ms=0;6 T4 f! d1 }2 p5 Y8 [- O+ c
  423.         }0 m2 ]/ i9 m- [

  424. * p2 d5 c& o8 T# g
  425.         if(flag_10s==1)+ |8 ?- u9 h1 f5 ~0 X3 M
  426.         {
    $ |, }& t# z7 C# ~1 n
  427.           flag_10s=0;
    ( A4 h+ v4 k' T8 S" j' E) q& E
  428.         }
    * y" m- V' J+ h2 k1 I
  429.     /* USER CODE END WHILE */
    ; a0 G- J1 v$ i5 [: b$ t6 t3 h; Y
  430. . C9 m0 I7 s9 I: k' |7 h
  431.     /* USER CODE BEGIN 3 */9 u$ V4 j* l! {6 z& j
  432.   }2 p0 {" \4 l4 @( ^# ~, O
  433.   /* USER CODE END 3 */  e3 b/ J5 J6 e" i! Q1 ~
  434. }
    + t  y% P: v( d+ I; p0 F
  435. + q% Y% f( @0 |% O( ^
  436. /**
    : x* [( X% E& ~" J+ J
  437.   * @brief System Clock Configuration
    ) [# x5 Y6 H( U9 h
  438.   * @retval None0 E8 e* J1 t+ t: j8 x
  439.   */4 Z. y8 I1 y: [/ d8 h
  440. void SystemClock_Config(void)$ k% b, n$ K  U' u- T0 o' j4 i
  441. {# x% c" g, _$ A  b, W9 M& ?  d
  442.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};  V/ d( Q2 {2 i! I
  443.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    : H: b4 n, [) A+ {( ^
  444. 9 a# ?/ M" Y! {" J2 R
  445.   /** Initializes the CPU, AHB and APB busses clocks % ?$ T. M. L$ h" f
  446.   */0 X2 k) `2 k. _& |# X* }; u
  447.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    , @4 x9 O* i, K, y: Y
  448.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;+ G' ]5 N/ @. t: ^; Y
  449.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;$ [" b1 L* Y, }& X* V
  450.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;& X$ ^% S( [( Y4 e/ ]$ i0 g
  451.   RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
    ( p  _" F- z: P$ y/ i. n
  452.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    9 X6 S7 K/ o0 Y2 z1 p/ o1 C
  453.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;" u3 R+ x5 I8 |6 Q0 x
  454.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    * F/ h# h! U9 Y7 M
  455.   RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;9 \9 E$ m, I! D" u4 B5 f
  456.   RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL10;2 J7 J/ {5 R, j& O- w9 \
  457.   RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV2;: q. J9 E) |9 b( d
  458.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    3 r" n$ W# o1 M0 v- b- v; b! a2 A
  459.   {
    6 p  n1 {. @& F8 S
  460.     Error_Handler();
      P+ O9 o9 L6 ~% S2 ?# w/ N: ]
  461.   }
    5 I8 p. I- n: `$ ~# _- ]; ]
  462.   /** Initializes the CPU, AHB and APB busses clocks 1 r9 c3 F( B; u2 B) ?) j- W5 `
  463.   */4 x0 x: b* Y8 Q# F
  464.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
    ( q8 K& L* c2 F4 Z1 y0 N' Y. w7 L4 w
  465.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;/ A4 Y5 l! A( }/ ~/ \4 K
  466.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    3 V! }; ?/ ]) D* @7 ]% g. M
  467.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;- F9 k6 M7 \% b/ x: h
  468.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;& L) |. T; b7 y1 t% i; ?/ y- t
  469.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;! l% ~3 T; g1 Y, X" L; R7 G8 }
  470. , B8 k( X4 p6 q) W3 {3 X4 r
  471.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)$ f/ Q$ ]/ P, e! E; ~4 M  `
  472.   {
    9 f7 R# y, c  q1 y
  473.     Error_Handler();9 |, i0 v# q) q- i. l6 v
  474.   }" a) O, C5 A. @* L% [9 N
  475.   /** Enables the Clock Security System 2 {2 I# q7 u: a- }; d# f6 `0 v7 i3 R' k
  476.   */
    , G/ `' J  w5 C8 `7 w$ m! S2 S
  477.   HAL_RCC_EnableCSS();" f7 }  ?1 F; s5 F. |& }" u0 p
  478.   /** Configure the Systick interrupt time 7 [# F; I$ b, C* a
  479.   */
    , a+ ?' n8 r; j! T* |$ \  w) [
  480.   __HAL_RCC_PLLI2S_ENABLE();
    & U* P$ v' {2 b' p4 @+ P
  481. }9 d  V6 J+ f' c$ d
  482. * U4 l* f! C' b3 E& I
  483. /* USER CODE BEGIN 4 */$ L; c- }, \, G! y3 h, j6 I; ]

  484.   a( P! H) r! N# K1 @
  485. /**3 w2 V& }' ~& q
  486. * @brief HAL_SYSTICK_Callback()
    # Z# I6 x3 X1 Z3 j4 B' U
  487. * SW timer triggered every 1ms.6 \: p; ?( K+ n4 p
  488. */: c4 p- l5 V( V
  489. void HAL_SYSTICK_Callback(void)$ q' ]2 G6 B& d
  490. {
    . _. D, i9 v; P1 j
  491.   flag_1ms = 1;1 j# M3 u/ q) {  K$ L: e
  492.   /*update counters*/
    , K/ H/ t3 u0 f+ v' `2 z2 Q
  493.   if(counter_10ms<9)  {    counter_10ms++;  }' u0 m4 I7 P  x$ z% ]
  494.   else  {    counter_10ms = 0;    flag_10ms = 1;  }
    7 L$ X; z. c+ d6 x1 |( H" c
  495.   if(counter_50ms<49)  {    counter_50ms++;  }
    ! @6 C0 S3 o, L8 b) W
  496.   else  {    counter_50ms = 0;    flag_50ms = 1;  }% Q5 |. {, G& V2 \: R9 _/ ]9 |! g

  497. ( ]# d' [1 b" P/ I
  498.   if(counter_100ms<99)  {    counter_100ms++;  }& g3 i7 L# |3 K5 D
  499.   else  {    counter_100ms = 0;    flag_100ms = 1;
    9 Z" Q5 B, F2 t' A/ C$ D
  500.         if(counter_200ms<1)        {          counter_200ms++;        }
    1 ]  d; ]* X) |. M; r2 p
  501.         else        {          counter_200ms = 0;          flag_200ms = 1;        }2 H3 B. x6 Y! \+ _+ F% S: [
  502.         if(counter_500ms<4)        {          counter_500ms++;        }
    2 L$ Y9 j* {9 [6 W) K% `: U: }" g
  503.         else        {          counter_500ms = 0;          flag_500ms = 1;        }# I: _( N$ o( q" f" E( l
  504.         if(counter_1000ms<9)        {          counter_1000ms++;        }
    . D3 Z* b! G% |8 {5 L  n* L0 {
  505.         else        {          counter_1000ms = 0;          flag_1000ms = 1;        }
    $ K" d4 S! \2 g4 p$ N
  506.         if(counter_2000ms<19)        {          counter_2000ms++;        }
    . F3 n! I. D: ^7 s- J6 b, b
  507.         else        {          counter_2000ms = 0;          flag_2000ms = 1;        }# f8 d7 _' }- |0 q+ B% G
  508.         if(counter_5000ms<49)        {          counter_5000ms++;        }! E1 G* G9 b3 ?$ s, k
  509.         else        {          counter_5000ms = 0;          flag_5000ms = 1;        }& X3 z; Q' E6 G- g- |$ r
  510.         if(counter_10s<99)        {          counter_10s++;        }1 ^& w1 G) O" `, ]
  511.         else        {          counter_10s = 0;          flag_10s = 1;        }
    4 o3 B3 m1 t, A  u. k  Q
  512.   }* T) `! m, e/ G: a- v* k+ f' n
  513. }- ?8 Z7 ?+ F, O' ?
  514. 2 T( \' }' Q+ n8 B3 o
  515. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
      f- ^7 m% ^/ P8 t1 A/ M
  516. {
    ) i0 l% i" C7 G$ n9 M: ?
  517.   if(GPIO_Pin ==GPIO_PIN_13)* P, O# g% r% v
  518.   {
    , D: S, B* F4 C: u4 y0 I/ f+ D
  519.         b_KeyNumber++;0 S. [7 ^0 L6 g2 g
  520.         if(b_KeyNumber>=2)4 h' j6 }, `/ E4 E4 S
  521.         {" T! q" M$ H. R5 ^
  522.                 b_KeyNumber = 0;
    $ M2 }  P# ^! t' q
  523.         }% P6 u. C+ o, {

  524. 6 `: k8 A# U9 I9 x4 d
  525.         sprintf((char *)a_DtuInBuffer, "a simple package\r\n");
    9 s( r& \7 o' d- ?5 W9 d+ s4 R5 \% A2 V
  526.         b_DtuInBufferRxCnt = strlen((char *)a_DtuInBuffer);
    6 k% ]: g6 B* B* t) h! b9 S/ |
  527. / @6 @  K# b- C' E. A
  528.   }
    ! O1 z. [% ~0 ]' x& `' s" H; z
  529. }( u1 C: F( M% X, c' K' a  x) |
  530. % {* [, [* D6 d( `4 F4 |
  531. /* USER CODE END 4 */6 T7 n8 B) P+ S8 v) T4 k

  532. 2 W! ~: w% m( d1 e
  533. /**3 t: ~. E4 _& R+ X4 h7 P
  534.   * @brief  This function is executed in case of error occurrence.
    ; C' _0 |0 J+ W, M
  535.   * @retval None
    3 ]  @- s+ r4 k$ u) X
  536.   */5 T6 Q  g  T- u% i3 e5 S% ~
  537. void Error_Handler(void)( U1 d& U2 J) f/ U9 z# T; y
  538. {
    $ V$ K, E0 a1 d
  539.   /* USER CODE BEGIN Error_Handler_Debug */# i% E- A8 f, S) Z# @6 x
  540.   /* User can add his own implementation to report the HAL error return state */
    8 o  I8 q8 Q- A  a4 U9 _
  541. " W5 h% i4 w9 N8 ^+ U3 Q. l
  542.   /* USER CODE END Error_Handler_Debug */
    3 [4 y7 L# k/ \- w
  543. }. Z) Z% }' w0 J0 C: J  T5 i& V

  544. ( {# ?+ d: |9 ~0 }! x2 J  ^0 P
  545. #ifdef  USE_FULL_ASSERT% D) g2 |9 @" Y/ ?: }
  546. /**" c; N6 ]+ i2 B+ }. A+ F) g( @1 s
  547.   * @brief  Reports the name of the source file and the source line number! n" t9 J/ l+ e
  548.   *         where the assert_param error has occurred.7 |2 m3 X. _/ u# G
  549.   * @param  file: pointer to the source file name
    8 ^0 K. ~! A3 R% [& w" p# W5 M
  550.   * @param  line: assert_param error line source number
    , Q' e. {4 V5 U2 H8 J* O5 Y
  551.   * @retval None
    7 v) I- x* I+ W$ q. \( [( p
  552.   */
    ! N1 ^$ M6 V( {
  553. void assert_failed(uint8_t *file, uint32_t line)
    9 J: h) h& q& s  |. P
  554. { 2 U$ F, j5 y* U& V9 l& @; ^2 }
  555.   /* USER CODE BEGIN 6 */
    % r; E* C2 q& A$ B0 D! Y! o" t
  556.   /* User can add his own implementation to report the file name and line number,3 j$ [! N2 \; N
  557.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */8 C, O: \( y" x
  558.   /* USER CODE END 6 */5 ?1 M: H0 M* u  m% L. s$ Z
  559. }+ F  J% x( W. ?' R1 x. I
  560. #endif /* USE_FULL_ASSERT */
    ! i' k* h$ q1 d; y0 Y, M4 O

  561. 0 P3 Y. @, K+ [! H) Q; F7 B
  562. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码

* k  Q; i6 ^2 E5 R" c4 试验结果

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


1 |6 q2 z, n  k5 X) v3 j) s2 ~, W5 R0 s. ~( t
收藏 评论0 发布时间:2021-11-27 09:29

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版