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

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

# x( M& W2 L( J6 t7 n/ N+ Q

% P- V& B4 l/ M* I  R5 p; t, ^8 r8 `2 Y

3、硬石STM32F1开源的源代码3.1 stm32f107_flash.c
  1. /**$ X9 s; x  {, m: b0 ~  ^& }" F
  2.   ******************************************************************************, d2 ~0 }; f' @. ]+ u
  3.   * 文件名程: stm_flash.c
    0 B. q( ~& T$ Q* h: N& Z1 T
  4.   * 作    者: 硬石嵌入式开发团队& d  f; ?6 d3 X: c/ h7 o0 W0 H
  5.   * 版    本: V1.0+ y6 Z/ |- C; L) E% }  g- |
  6.   * 编写日期: 2015-10-048 d. j7 m: v6 P: W* w5 y
  7.   * 功    能: 内部Falsh读写实现
    / y3 C0 e, t( W
  8.   ******************************************************************************4 i# y) G: }4 N
  9.   * 说明:' g3 [) X8 z: X9 n: Y- e
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
    * t# u& e! I5 y: H# ~
  11.   *
    $ R  n" T/ Y) g7 M: j5 P# |2 \
  12.   * 淘宝:
    ( {5 g% |( w- j8 a
  13.   * 论坛:http://www.ing10bbs.com
    + H5 O$ E1 z' K; i6 M; ^
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
    9 r) H% a+ s: ?7 k9 O, u
  15.   ******************************************************************************. M  n9 E4 h7 q, M! z
  16.   */
    7 V. \4 {7 V( q
  17. /* 包含头文件 ----------------------------------------------------------------*/
    # i2 \3 V0 A  @5 t8 b& w% G; u
  18. #include "stm32f107_flash.h"
    9 E- k" P9 F% D$ K. ~9 a7 x

  19. ! Q, n2 q! O1 p8 J
  20. /* 私有类型定义 --------------------------------------------------------------*/& {/ v9 m4 T+ B/ |% S9 D
  21. /* 私有宏定义 ----------------------------------------------------------------*/
    : v0 \, H8 o# f0 `, w! C2 f- g8 N' `
  22. #if STM32_FLASH_SIZE < 256  d* N0 ^) k! [& ?% z% M
  23.   #define STM_SECTOR_SIZE  1024 //字节7 B3 v0 j  q1 R
  24. #else
    9 q2 ?) [: p& T7 A0 V* n
  25.   #define STM_SECTOR_SIZE         2048# `. f: g' S# r* s" @
  26. #endif
    ; J! T' \7 ?& x" C3 [5 C

  27. 5 v- ^# i. C+ A0 x! R) J  W5 W7 w4 o
  28. : j1 w. I- @7 \; U) S7 V& S& |
  29. /* 私有变量 ------------------------------------------------------------------*/* q- M: G+ ~7 e$ x
  30. #if STM32_FLASH_WREN        //如果使能了写
    4 L7 \9 Z: f5 o, h9 |3 x
  31. static uint16_t STMFLASH_BUF [ STM_SECTOR_SIZE / 2 ];//最多是2K字节
    2 Z* U4 n) X# N/ A; W5 g& ]
  32. static FLASH_EraseInitTypeDef EraseInitStruct;4 t0 V1 g1 R( c: i+ {0 Y+ ^
  33. #endif$ p  d+ @% X0 J* }
  34. 3 l* E: o  _6 f; |) r
  35. /* 扩展变量 ------------------------------------------------------------------*/
    & r% M) }. z; _$ Z+ ^: q* U
  36. /* 私有函数原形 --------------------------------------------------------------*/8 x/ U. x9 l* `" X* n" f4 D& n; h' V
  37. /* 函数体 --------------------------------------------------------------------*/& ~( _" ]6 e- R5 j1 B3 U' G+ g
  38. /**
    $ S: U! I5 c% g; M9 P3 w$ y& Z
  39.   * 函数功能: 读取指定地址的半字(16位数据)8 e5 e/ l$ m. v% x7 e  A
  40.   * 输入参数: faddr:读地址(此地址必须为2的倍数!!)4 }5 z& p# {6 Y9 F% j
  41.   * 返 回 值: 返回值:对应数据.
    . {" _* r) R9 f2 H
  42.   * 说    明:无: t) N4 w/ g# v) f
  43.   */
    , Y6 D% N/ ?2 A" o# p8 r4 x+ k
  44. uint16_t STMFLASH_ReadHalfWord ( uint32_t faddr )
    6 G& ?# l, d. V
  45. {
    ( N: Y7 W2 }  P
  46.         return *(__IO uint16_t*)faddr;
    5 |! L9 k' \2 s1 Z: q: v: g
  47. }
    0 |1 L# N, N. W, s) G

  48. 5 X$ i/ X. I! _# s: B- k
  49. #if STM32_FLASH_WREN        //如果使能了写   
    / @% y0 z0 ]. `1 Z+ o' B
  50. /**
    - v$ i3 H# p5 z& k/ p
  51.   * 函数功能: 不检查的写入1 I* k0 V7 G- }! j8 p* {
  52.   * 输入参数: WriteAddr:起始地址
    ; v  Y/ _$ e2 k0 C! {$ G
  53.   *           pBuffer:数据指针
    ! K$ P* S' F9 r# B' K( C% x, k
  54.   *           NumToWrite:半字(16位)数; z# N# S2 C/ o( P
  55.   * 返 回 值: 无
    4 [8 s; \) S  O) @+ u. D
  56.   * 说    明:无
    2 t: v0 ]/ n4 B7 {
  57.   */
    ! v$ f1 g1 c" {9 M* ~- n" W, d% Z  ^
  58. void STMFLASH_Write_NoCheck ( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite )   , n6 K$ l+ C8 o0 w; R
  59. {                                           
    3 K& l1 ?6 I2 A4 ]) l9 `
  60.   uint16_t i;6 \5 v, E$ n( b  t+ O
  61.        
    ' @: Q- @0 Y. S8 \. }
  62.   for(i=0;i<NumToWrite;i++)
    1 }1 K1 [5 b% |4 H
  63.   {) q4 D$ X7 a0 k! `
  64.         HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,WriteAddr,pBuffer[i]);6 q) T$ ~  _0 v; F0 u
  65.         WriteAddr+=2;                                    //地址增加2.
    " C) c9 d  P6 {# U
  66.   }
    ' f6 t2 k+ \  {" L# ~- m. P
  67. } ' W5 ?' k6 V5 `4 _: p

  68. 1 r. Z+ C6 ~- T) R' N. M/ \  Z& n
  69. /**1 \) p& D# U- V2 C
  70.   * 函数功能: 从指定地址开始写入指定长度的数据2 M2 i! A# \" {8 @# Z
  71.   * 输入参数: WriteAddr:起始地址(此地址必须为2的倍数!!)
    5 \/ W' @- n+ X) Y& Z6 u* g2 f
  72.   *           pBuffer:数据指针+ q, C+ Z$ T3 J2 n9 x
  73.   *           NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
    * u( P7 A: X% f% P( R& d
  74.   * 返 回 值: 无
    . Y: U& o5 J+ K  x+ p( @: F( B2 r
  75.   * 说    明:无
    3 l1 V" {# O; ]: B/ h5 t
  76.   */
    + Q0 Z3 \$ I" b5 k3 V$ J' X
  77. void STMFLASH_Write ( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite )       
    : I4 U% t' c) w  q* ]
  78. {5 ]6 r6 Z% C3 c% c
  79.   uint32_t SECTORError = 0;
    $ m- |5 n# O4 k$ Y8 x8 v3 v6 c7 M7 m
  80.   uint16_t secoff;           //扇区内偏移地址(16位字计算)
    / M% ~" E* H' W% \
  81.   uint16_t secremain; //扇区内剩余地址(16位字计算)
    9 B; p- k2 L8 y
  82.   uint16_t i;- Z. }3 R9 l4 E9 X; ]$ ]
  83.   uint32_t secpos;           //扇区地址
    , x& }( V! U  m. Z6 T
  84.   uint32_t offaddr;   //去掉0X08000000后的地址
    " V% o, P' x, o( I! w" N% K1 E5 E
  85.         - p- K6 g$ w7 ?( ?/ [
  86.   if(WriteAddr<FLASH_BASE||(WriteAddr>=(FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址; o+ l( ~: o4 z" F+ J. M( E2 k
  87.        
    ) M( i% J+ b* x% z8 W' \
  88.   HAL_FLASH_Unlock();                                                //解锁
    % b# G0 l$ W: @+ J5 D
  89.        
    * g! w# q; P3 v, c
  90.   offaddr=WriteAddr-FLASH_BASE;                //实际偏移地址.
    ( D% j' J( u+ z7 `  O
  91.   secpos=offaddr/STM_SECTOR_SIZE;                        //扇区地址  0~127 for STM32F103RBT6' p1 B9 c, ^# j9 `6 F6 ~' U; s7 Y
  92.   secoff=(offaddr%STM_SECTOR_SIZE)/2;                //在扇区内的偏移(2个字节为基本单位.): Y" Q; b$ ?* y3 n
  93.   secremain=STM_SECTOR_SIZE/2-secoff;                //扇区剩余空间大小  m0 Z9 j  ]6 x4 }' y; y" I
  94.   if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围  t: f9 `" Z: \: M  Y
  95.         * O/ C' e! A& `' T; S% v- a
  96.   while(1)- d6 q" T9 X( K7 _# b
  97.   {) {  f1 n3 n! O7 w2 ~* O
  98.         STMFLASH_Read(secpos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
    ' m( X/ ^2 @% s
  99.         for(i=0;i<secremain;i++)//校验数据; a0 \' L& e; E" k$ c2 \& j0 N2 ^
  100.         {# e  z! Y, t5 u2 {- Y+ d( C$ ~7 L: e
  101.           if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除- q) Q3 A% V+ X3 C/ U2 L
  102.         }
    / z7 M) o" r( M" l
  103.         if(i<secremain)//需要擦除
    : E# v. O2 X/ E6 t3 X  h0 {) `+ @# p
  104.         {
    - @% x, @% Z: h# o/ D, K
  105.           //擦除这个扇区
    / v" l/ G4 _: g- W: f) G
  106.           /* Fill EraseInit structure*/
    ) r. w. Z7 ~  |! Y9 [8 F: x+ K
  107.       EraseInitStruct.TypeErase     = FLASH_TYPEERASE_PAGES;
    ; c  Y! P) G0 y
  108.       EraseInitStruct.PageAddress   = secpos*STM_SECTOR_SIZE+FLASH_BASE;
    1 L0 [' Q8 |' N+ f
  109.       EraseInitStruct.NbPages       = 1;9 T9 F' \( Z. b
  110.       HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);0 D0 L5 R1 ~* C, n' B3 X, g# T- W
  111. 1 O' V8 S: U7 V. }1 {
  112.       for(i=0;i<secremain;i++)//复制
    - M5 O" |; X7 H3 Q1 K9 E" y9 W
  113.       {* W, Y* K9 S4 {3 D3 v: D+ S$ K
  114.             STMFLASH_BUF[i+secoff]=pBuffer[i];
    : E: k3 Z  N/ p- @2 Q, M. Q8 v
  115.       }2 H' I8 x" L. A9 p/ w9 C
  116.       STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区
    0 C) B$ [8 f" t
  117.         }
    , u0 d" K/ c8 K2 h: M
  118.     else6 \/ k& v4 D" ~. H5 R3 M0 Z1 y" o
  119.     {
    # z4 N" i0 Z% W' E' q6 L, y# y
  120.       STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.                                   
    $ P4 D# }& g! q
  121.     }2 d7 Q4 {6 O9 X1 C8 {
  122.     if(NumToWrite==secremain)break;//写入结束了
      }( L/ a: G1 g: U  ~
  123.     else//写入未结束
    9 Q: M1 R9 k8 Y1 F  R& r/ c* {
  124.     {
    # t* k5 i' h" \4 Y3 o- n
  125.       secpos++;                                //扇区地址增1
    - _5 a( U7 M& M& O. F% v& R6 v/ N$ {
  126.       secoff=0;                                //偏移位置为0, n1 N! i; e) _  K# O( {+ X
  127.       pBuffer+=secremain;          //指针偏移
    ' f- R( u% M1 E- H
  128.       WriteAddr+=secremain;        //写地址偏移
    0 k1 ~$ A2 m) ~( @) n
  129.       NumToWrite-=secremain;        //字节(16位)数递减7 P- p3 F% J2 s7 S$ r
  130.       if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
    * C- r* Z5 d  m6 `' B; \# _! e
  131.       else secremain=NumToWrite;//下一个扇区可以写完了
      z% p$ J" K/ P$ _, E# h7 t
  132.     }" W# [; m7 u9 Z! [1 F+ L
  133.   };
    - d9 \. v" e( {: i2 G7 P
  134.   HAL_FLASH_Lock();//上锁1 S8 q% j" S2 V3 I
  135. }. F9 y* [# ?8 s; l3 i0 J' [- H0 h
  136. ; y! K0 S# h# T6 p) E. s  Z0 P

  137. ( m/ i9 q! ~  G& h/ {
  138.   W4 m' N) G0 U& \+ b! w. s
  139. #endif
    5 n2 g  K* b  T5 m

  140. ; ^, r% k3 L, b4 Q3 p; }' R& e. D& x( }+ p
  141. /**
    ) \$ |4 R! H5 j2 D. v& w
  142.   * 函数功能: 从指定地址开始读出指定长度的数据+ _9 E1 L3 H$ u: I) w
  143.   * 输入参数: ReadAddr:起始地址. v0 l! [) V  w8 z  N
  144.   *           pBuffer:数据指针$ p) \, z! y* G. O$ R( p
  145.   *           NumToRead:半字(16位)数! j& P1 N6 J; M% T& p' e
  146.   * 返 回 值: 无
    " u/ R5 @  }% K; w
  147.   * 说    明:无) }' t& M9 S) B/ S" w0 o6 ?
  148.   */
    ( t' |, v" X( [
  149. void STMFLASH_Read ( uint32_t ReadAddr, uint16_t *pBuffer, uint16_t NumToRead )           ' ]# u! `% z0 T
  150. {
    % d9 n/ a) r1 Q. G& l5 I" Q7 V
  151.   uint16_t i;/ j8 b8 ]* I4 @- L: @# ]
  152. 2 m# Y  c6 j+ t2 P6 `# l8 f
  153.   for(i=0;i<NumToRead;i++)6 ?3 }' a1 R4 e# N4 |
  154.   {( J4 X, Y' ~6 U* F3 @# t/ w
  155.         pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.* g1 `! H0 n2 z
  156.         ReadAddr+=2;//偏移2个字节.
    ' Q1 d! _% ^6 {& r( @# |
  157.   }
      w0 ^& h* n" F
  158. }
    , M' z8 W! C% w) n8 j" [7 E/ L
  159. * r: Z. }9 B9 ^0 C  w. e7 e" u4 `3 J; U
  160. /*+ e) w5 i0 Q. V% [, k
  161. * 函数名:Buffercmp
    ' H! }- B8 Z9 J2 Q3 A. j( H
  162. * 描述  :比较两个缓冲区中的数据是否相等1 H' c* f* p9 o/ V) E& J
  163. * 输入  :-pBuffer1     src缓冲区指针7 f$ f" h! p& |! A5 ?" F9 I
  164. *         -pBuffer2     dst缓冲区指针. Z6 j; _' _! V$ E% E
  165. *         -BufferLength 缓冲区长度: E( D! L8 F5 V5 Y0 }8 _* f
  166. * 输出  :无; ~) Y. @% t- K% o
  167. * 返回  :-PASSED pBuffer1 等于   pBuffer2
    4 P# [0 M( k! H6 V$ w
  168. *         -FAILED pBuffer1 不同于 pBuffer2& H. N1 c+ r# F  F8 n  D
  169. */: D. B' `/ A, C. g7 w4 {1 S1 b
  170. TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength)
    # Y2 c5 B6 [8 K% s& c
  171. {
    ! b" B* A0 c0 u9 d; e
  172.   while(BufferLength--)7 f, N, n* ~) f; I4 h6 Q
  173.   {
    7 u% U4 `% o4 e$ V
  174.     printf("data:%d - %d \n",*pBuffer1 , *pBuffer2);
    / ~3 T2 Q7 c& _4 q  _* W/ w7 [
  175.     if(*pBuffer1 != *pBuffer2)
    , V1 R/ s) M5 e. F& v9 j8 o
  176.     {
    . ]( W% q. w4 {* h1 j
  177.       return FAILED;7 r+ }! Z7 A# w
  178.     }4 {* O" b0 C6 [3 n$ d1 g

  179. + ]8 x" z( d+ B# E4 R3 \
  180.     pBuffer1++;
    3 T. \3 U+ C! L: c
  181.     pBuffer2++;
    " N5 x, E# O: w+ `% X1 O
  182.   }
    + w+ \/ C4 B4 f, ^. h0 V
  183.   return PASSED;/ e; E( ~( D1 e, R" G, _+ c
  184. }
    5 W4 s) h# U" j6 h" u9 r
  185. # T& |( k4 V5 i6 f0 I, S! z5 V( h

  186. ' l  Q; p/ O2 ~* ?! g" i; E3 l
  187. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码

6 G& ?1 {6 L% \# X, o5 l3.2 stm32f107_flash.h; E/ y4 u" m: V$ w2 D6 N% ^0 k
  1. #ifndef __STMFLASH_H__  ~! g  [3 p& W' @
  2. #define __STMFLASH_H__
      L8 P; W+ U8 y: D* B: I% y

  3. ! _8 @8 l/ V- x1 Z: N; g8 S
  4. /* 包含头文件 ----------------------------------------------------------------*/
      m/ Z9 i; B$ V( E
  5. #include "stm32f1xx_hal.h"+ {  g# p% \  |$ I, v# n
  6. " @& w& H4 S5 O2 `% R
  7. /* 类型定义 ------------------------------------------------------------------*/
    3 K# b* n$ y- i# d9 N) N6 B
  8. /* 宏定义 --------------------------------------------------------------------*/
    2 A( O% y" x. A- c% t5 W
  9. /************************** STM32 内部 FLASH 配置 *****************************/
    $ D* ~" y1 o9 g5 B) w6 W; x
  10. #define STM32_FLASH_SIZE        256  // 所选STM32的FLASH容量大小(单位为K)1 F# q$ J- J( o6 s" p' M$ m
  11. #define STM32_FLASH_WREN        1    // stm32芯片内容FLASH 写入使能(0,禁用;1,使能)
    ; }2 Z9 y9 \4 c) Q
  12. 0 W5 X/ o: H$ |/ H8 Y
  13. typedef enum- H. _3 T3 }8 b  k+ i
  14. {" g1 r4 w2 C$ v. k  r0 E* u1 p. I- X
  15.   FAILED = 0,) H4 Z! ^" e! k4 h5 d
  16.   PASSED = !FAILED
    $ h7 p- Y1 Y( T5 ~+ ~9 ]
  17. }TestStatus;
    $ P8 u; ]: F$ @& P
  18. 0 m: G; Z$ [2 D/ ~- `
  19. #define  FLASH_WriteAddress     0x0803F800            // 写在靠后位置,防止破坏程序
    0 b5 a3 b* j2 s; [8 z# f
  20. #define  FLASH_ReadAddress      FLASH_WriteAddress
    1 _% M: u$ Z3 w
  21. #define  FLASH_TESTSIZE         512                 //实际是512*2=1024字节
    ' w( N+ D3 Q7 j; ?
  22. 9 }7 i' d, M, i* r

  23. 3 Y6 h- H+ ]7 @+ d  R( H
  24. /* 扩展变量 ------------------------------------------------------------------*/$ G+ \& X2 S) x% c
  25. /* 函数声明 ------------------------------------------------------------------*/
    * V3 ]% M1 y9 j  I0 n% n
  26. uint16_t STMFLASH_ReadHalfWord(uint32_t faddr);                  //读出半字
    7 x3 G1 r9 U9 _7 Q+ w* O  a' [
  27. % D* H7 T8 w+ W* y
  28. void STMFLASH_WriteLenByte(uint32_t WriteAddr, uint32_t DataToWrite, uint16_t Len );              //指定地址开始写入指定长度的数据
    / ?, t+ E9 ?2 X* w5 h; ^5 j
  29. uint32_t STMFLASH_ReadLenByte(uint32_t ReadAddr, uint16_t Len );                                                                    //指定地址开始读取指定长度数据$ r7 {3 k. e3 H, u! e1 T9 F
  30. void STMFLASH_Write( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite );                //从指定地址开始写入指定长度的数据  y& s, \* E- n, |; c
  31. void STMFLASH_Read( uint32_t ReadAddr, uint16_t * pBuffer, uint16_t NumToRead );           //从指定地址开始读出指定长度的数据+ }  q9 K% G" Y; {" |* G
  32. //static TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength);- G9 N' _7 F; W& U
  33. TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength);+ w3 f2 F' L& @) z4 \

  34. 2 a3 O/ s& x9 k6 T# Y+ \, ?4 A  _
  35. #endif /* __STMFLASH_H__ */
    + h- t6 t9 W$ \
  36. / {* Q( A: C7 I  F
  37. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码
0 J$ f/ n1 j  M0 A; k- W2 ]" Y
3.3 main.c$ o5 l7 a2 r4 r% \2 m* O
  1. /* USER CODE BEGIN Header */8 ^1 ~2 v5 Z6 r& o& d
  2. /**4 F+ V: q' b' {9 o
  3.   ******************************************************************************
    1 u# n' R, b5 i9 g' `8 g$ }. E' B
  4.   * @file           : main.c$ a1 o8 k" b* F! D; I( E
  5.   * @brief          : Main program body4 D5 ]$ c0 E0 l. X/ ^5 |7 f
  6.   ******************************************************************************, o9 t7 D% `5 F0 Y0 d. w  C
  7.   * @attention
    . I7 p7 `6 A4 u5 [$ y: c
  8.   *
      [8 E$ _. I* ?+ H
  9.   * <h2><center>© Copyright (c) 2019 STMicroelectronics.6 U% f8 `' B$ V5 C
  10.   * All rights reserved.</center></h2>) ^5 M3 U4 Y' K7 w3 k0 V0 w
  11.   *
    $ E7 R0 k8 v0 Y, n4 W% ?6 _) ?
  12.   * This software component is licensed by ST under BSD 3-Clause license,) L& E4 t  H" ?
  13.   * the "License"; You may not use this file except in compliance with the
    % j: O) u) E# f( t+ i1 n
  14.   * License. You may obtain a copy of the License at:1 N  s. `& ?3 O# U% m; I; |
  15.   *                        opensource.org/licenses/BSD-3-Clause
    5 ?" Y$ g' F( q. \
  16.   *
    " w6 h( [! L4 t5 N
  17.   ******************************************************************************
    " B# b2 h8 F/ L# l5 l
  18.   */
    7 _4 [0 \0 ]5 Q: `- f
  19. /* USER CODE END Header */" b  `& L% q: j
  20. $ ~# n, U/ B' A% T$ h9 z
  21. /* Includes ------------------------------------------------------------------*/( @, w$ s+ z) m; I* F5 d
  22. #include "main.h"- F: I* W9 y8 g1 w& }, I* [
  23. #include "can.h"9 z, _2 s% m6 J
  24. #include "dma.h"6 T& x8 H- B; f% T7 K/ E
  25. #include "lwip.h"' w( \1 ]) L4 y+ E- O$ G3 [# x( a
  26. #include "usart.h"
    6 G7 W$ H: c! ~8 x0 X8 t
  27. #include "gpio.h"
    % w3 [8 A3 F) o9 ^0 X

  28. 8 b1 [) l' c, j! |+ ?
  29. /* Private includes ----------------------------------------------------------*/
    ) W4 C7 v4 J' F9 o0 D
  30. /* USER CODE BEGIN Includes */  n, P2 D4 K' J& m2 o* W2 x: X! }
  31. #include "string.h"
    3 T& N# b" S4 Z6 E1 a8 s
  32. #include "tcp_echoclient.h"
    . Z8 @8 a9 S  K* R/ P6 K

  33. 5 k8 r5 B% q% N8 t8 B/ l3 o2 P
  34. /* USER CODE END Includes */: v% _0 Z4 g* i  a9 A3 _0 V5 n

  35. / }( x1 {5 F) n1 {  Q0 ?; K3 h5 S
  36. /* Private typedef -----------------------------------------------------------*/7 |( ]4 e! ], K- z7 ], a
  37. /* USER CODE BEGIN PTD */
    6 {5 q+ M' v) a" u, q
  38. 0 H7 `9 k" N7 I  ~" X
  39. /* USER CODE END PTD */) B0 m. }4 A0 D/ R7 L1 P
  40. 7 {- d/ s, a; c9 |1 d
  41. /* Private define ------------------------------------------------------------*/& W; c& x( g$ k: B
  42. /* USER CODE BEGIN PD */# f5 @8 Q, a3 k7 h' g$ e
  43. #define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))
    7 c% m* f# P, ?* M' B- T7 d" n2 E

  44. ; V# ]2 a& ~: j4 Y1 d; V% ^$ [
  45. /* USER CODE END PD */
    7 w- f2 Y2 Z8 w- i% h# K+ P
  46. & |) v% P$ D7 y1 T3 L
  47. /* Private macro -------------------------------------------------------------*/
    4 A6 O& g5 Z  g7 d0 c0 |1 y; p
  48. /* USER CODE BEGIN PM */0 c; w4 f3 o$ d) H8 k1 L6 T

  49. 9 U  N$ e( I" ~7 ?
  50. /* USER CODE END PM */
    1 A4 e' R) u( U) F3 b$ A" a+ @
  51. 9 z2 j7 ]2 D" r; `8 U7 |
  52. /* Private variables ---------------------------------------------------------*/3 M+ Z( d( |! F4 `/ [$ M

  53. : Q& q4 O3 M: \/ x/ P
  54. /* USER CODE BEGIN PV */
    & x1 }2 H0 F& K
  55. uint32_t  counter_10ms, counter_50ms, counter_100ms, counter_200ms, counter_500ms, counter_1000ms, counter_2000ms, counter_5000ms, counter_10s;
      S) G" l6 \. o8 L
  56. uint8_t flag_1ms, flag_10ms, flag_50ms, flag_100ms, flag_200ms, flag_500ms, flag_1000ms, flag_2000ms, flag_5000ms, flag_10s;
    0 Q: R& n/ b/ V3 r% S2 k) }& A
  57. uint8_t b_KeyNumber;- S. Z0 Y$ U7 v2 Q: f) p
  58. , x- O2 V: Q4 W4 y$ W
  59. uint8_t a_DtuInBuffer[100];
    ' v, g  Q- i" [2 _4 m: t
  60. uint16_t b_DtuInBufferRxCnt;
    % `; X0 Z- H, c9 W; D& ^

  61. # R1 i8 w, b+ n
  62. uint8_t a_DtuOutBuffer[100];+ H9 c# Q) H$ @2 L; O
  63. uint16_t b_DtuOutBufferRxCnt;
    $ X/ j  J' p0 ^5 }' k3 h
  64. ; y. h) ]1 X9 Z4 H
  65. struct netif gnetif;
    9 R( M5 \" ^0 o# ?
  66. extern struct tcp_pcb *echoclient_pcb;8 w+ }# ^- j( D# s* f5 n1 j
  67. uint32_t status_TCPProc;
    5 N' d* r" U4 W
  68. & W; M4 X1 ?# w. |& o5 J- l

  69. ( J8 U- \4 j; S% n$ @0 `
  70. uint8_t a_SocketConfig[7];
    # }# D+ `3 c3 T$ y/ K# k! A! ]4 g: `
  71. uint8_t a_SocketHeartBeat[60];
    ; W$ p1 v! ^( u1 R! G( |! l, K
  72. uint8_t a_SocketHeartBeatInterval[2];1 Y( J/ h+ c, H0 x
  73. uint8_t a_SocketRegister[60];- }# U/ L2 C# G

  74. + Z+ p3 B( G/ E& U3 j
  75. uint8_t a_DtuInOutConfig[2];8 h0 ^" S5 E$ r  Z5 z) A

  76. ; `' k, A0 `* T) t" x7 ~1 I
  77. uint8_t b_WifiMode;2 K* ^( |7 u/ ~) w& D4 r) i3 m& t
  78. uint8_t a_RouterSsid[20];
    , D; r4 J) q9 l! }+ o
  79. uint8_t a_RouterPswd[20];/ F& @( d6 A# G- Q8 r3 P

  80. 2 K7 D6 x3 G' G
  81. uint8_t a_Rs485Config[5];
    2 }; ?- Q) p! a/ l
  82. uint8_t a_CanConfig[5];
    : A% A( L9 m" T
  83. & S0 {3 k! I  ?* S9 y* T9 E
  84. uint8_t flag_DtuConfigUpdate;
    . d' g. ~3 L- z2 y1 E1 T# h% R. ^/ G' u
  85. uint8_t flag_DtuEthReady = 0;
    " f, m( V! O" z; x. y: X

  86. 9 K5 L: t, b5 o
  87. uint32_t b_HeartBeatPackageCnt = 0;
    - M1 n, S  L& w

  88. % r+ d! K) f1 J
  89. uint32_t b_232STM32ParamConfigBusyCnt = 0;        //尝试通过串口和STM32交互时候,会让出相应时间,优先处理
    $ o6 n3 P6 U0 K, n3 b, i0 R

  90. 8 }1 L4 ]3 T; i6 _( U1 {/ }% U
  91. /* USER CODE END PV */) N- d& m0 X) Q- q  o  v
  92. ' W7 _* M0 U, k4 I
  93. /* Private function prototypes -----------------------------------------------*/6 @% L' d1 K" N. j% x3 ]( ?
  94. void SystemClock_Config(void);7 w% @6 P  t: o) Q4 L8 K7 d
  95. /* USER CODE BEGIN PFP */
    0 A0 o$ a% S9 n- h
  96. ) F) @/ P" v: Q/ Z/ E' d7 W
  97. /* USER CODE END PFP */+ `# S' j8 V# O& n
  98. 9 t$ a& [/ Q& R' R, F1 i
  99. /* Private user code ---------------------------------------------------------*/
    7 U" j, X$ p- E* j
  100. /* USER CODE BEGIN 0 */- [% B/ c* v# d0 t
  101. void Task_HeartBeatPackSent(void)% X: \- i2 \% K& f* O. e
  102. {( o4 r' O! f+ Z: j. b
  103.   uint16_t b_interval;
    6 I/ }. G% V8 B: Q- b/ O+ P4 ~

  104.   u" l: L# c! d0 L9 F- N
  105.   b_interval = (a_SocketHeartBeatInterval[0]<<8) + a_SocketHeartBeatInterval[1];
    2 l$ P' r! Q' K2 N( ~
  106. / H- e& Y5 U& F7 N1 M) G% c1 i
  107.   b_HeartBeatPackageCnt++;3 l( u( y4 O3 e) S# Z1 w
  108.   if(b_HeartBeatPackageCnt>=b_interval)
    / |# k( s% q, Q! X" l: h5 d
  109.   {/ o# E# n  k% F$ C
  110.     b_HeartBeatPackageCnt = 0;7 j5 K0 Q, u* i6 x
  111. ( ^* t/ D: L$ F3 j- _
  112. , j# G9 f9 e0 k7 V9 y" k  h2 k
  113.     if(a_DtuInOutConfig[1]==1)
    & ~" K8 b. T9 ?# Y) K; {6 w
  114.     {; B* K+ y  C, W$ U
  115.       if(flag_8266DTUReady==1)& J8 }$ J2 }. A. i; L
  116.       {
    - h# A/ D4 ?; g, i4 ^1 \* I9 i+ R
  117.             HAL_UART_Transmit(&huart3, a_SocketHeartBeat, strlen((char*)a_SocketHeartBeat), 100);" S% }; U( w* s: e) |
  118.             printf("\r\n");
    : ], R: q- e( S3 g) U" j
  119.             printf("\r\nA heart beat package is sent.\r\n ");
    ; {- J9 W0 l* c$ J  W
  120.       }
    $ u- d) r1 N! ^2 K
  121.     }! j" z9 I" q) |
  122.     else if(a_DtuInOutConfig[1]==2)
      H/ g- t2 {8 o" }
  123.     {/ o" O! K4 d7 [
  124.       if(status_TCPProc>=2)9 F& T/ V1 i! V+ S% I  ^
  125.       {' g4 D' _# Y! c) X& t
  126.             tcp_senddata(1);( {  F  t% U+ B5 P# A! N
  127.             printf("\r\n");- B* X) E& T" m0 ]# r/ T# P
  128.             printf("\r\nA heart beat package is sent.\r\n ");
    " {0 [# `8 M, O: c9 l
  129.       }
    % w1 S' l' |# ]& M3 i' V
  130.     }- G* {8 y# |5 |& O! B+ l- j& J+ N, B
  131.   }: ]' {3 ~' y( w' l" S' c' [' }0 B
  132. }
    4 E4 k6 G& u5 `" y+ ]5 F) ]$ k
  133. void cleanDtuInBuffer(void)" |8 K' L& R. h( M3 E5 a
  134. {- d: H2 j5 J, ^- v2 c3 k; Y/ }6 B' a
  135.   uint32_t i;3 y% {5 j- h- X7 T1 f
  136.   for(i=0;i<b_DtuInBufferRxCnt;i++)
    % w! W* u. U( d$ j
  137.   {% a1 b8 S: S" o: i, ]( Z
  138.         a_DtuInBuffer[i] = 0;& e  L* g& e3 |& E6 o# b6 g
  139.   }* C+ Z4 e8 y' A6 Z2 Y/ Z/ A* t
  140.   b_DtuInBufferRxCnt = 0;
    3 ~& ^0 D+ k$ g/ `! ^. H
  141. }6 b$ i+ N% Q& S. S8 O9 W+ r# T
  142. void cleanDtuOutBuffer(void)4 h$ W5 A- z1 a$ S- E
  143. {
    ( a6 d# l) \) X& T
  144.   uint32_t i;
      V1 o- I7 c, S' N: G: I) f& V; C
  145.   for(i=0;i<b_DtuOutBufferRxCnt;i++)6 d' L& }7 v: z- v( `" b! T7 y$ a
  146.   {
    1 X. I5 E8 T; x# S+ N* O
  147.         a_DtuOutBuffer[i] = 0;
    3 d  o0 v- ^6 A. w0 M/ T2 E
  148.   }
    3 o5 L  |  P1 ^+ q5 r. K# `7 I
  149.   b_DtuOutBufferRxCnt = 0;
    6 a( g+ |2 b+ H2 \2 }# f
  150. }% ^! K, p4 N; Y% D) G

  151. : v6 f; ?5 T! ^
  152. void Task_DirectTransfer(void)/ R. L( E; W) J% [4 O* T
  153. {% h) m& A1 J, i% E
  154.   uint32_t i, k;
    3 A7 j  m7 K" b. H4 r8 Z
  155.   //把数据输出到以太网或者WIFI' J. u- F7 j4 [0 I9 M
  156.   if(a_DtuInOutConfig[1]==1)
    1 S2 C3 a4 q9 l" T
  157.   {! }% |& u' J  j2 o' v
  158.         if(flag_8266DTUReady==1)
    & l5 Y- S. g- L) U2 M+ z
  159.         {
    4 R0 ^4 S; {9 Q) H! i6 E5 G) Y
  160.           if(b_DtuInBufferRxCnt>0)* U- J+ P! V+ q+ }6 O
  161.           {
    2 \) I7 B* V. g* @% g& Z( U1 E
  162.                 printf("\r\n");& f" Y" W: [. ?' v
  163.                 printf("\r\nData sent to Wifi: ");
    4 q. I9 w2 G/ G/ `, v9 m
  164.                 HAL_UART_Transmit(&huart3, (uint8_t*)a_DtuInBuffer, b_DtuInBufferRxCnt, 100);, o7 C5 e) D. C2 z) B
  165.                 HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuInBuffer, b_DtuInBufferRxCnt, 100);        //debug- N0 v0 |  h+ k+ I( f7 w+ q' ]1 P
  166.             cleanDtuInBuffer();
    4 M' j5 |' u- N) p4 V
  167.           }: g- b" X; G3 a- N
  168.         }: A, v. W' i, n0 ^
  169.   }
    - W( {* B( R% u, j6 X) A0 \
  170.   else if(a_DtuInOutConfig[1]==2)
    / p0 E4 |6 _7 J6 G. q5 f
  171.   {: B/ \0 ^8 w; |. u* j0 h6 j
  172.         if(status_TCPProc>=2)
      H) g4 K( N0 H1 I1 X; h' }
  173.         {: k& t1 |$ f7 `
  174.           if(status_TCPProc == 2)+ R/ L- c% {. ]2 ?) H
  175.           {
    - H) U. P- W6 @! B8 B0 x
  176.             tcp_senddata(0);        //专门发送注册包
    : A, X' J" {# f1 ]% J
  177.           }
    ( y5 U) U" T5 O1 }- \  O& M1 J5 H
  178.           if(b_DtuInBufferRxCnt>0)# F* W2 ^; O  E' r( P
  179.           {4 J$ p( A7 x% e" e
  180.                 if(status_TCPProc <= 3), {/ ?5 B4 f! i
  181.                 {8 f5 Q$ x9 C  ~& @  h/ \
  182.                   tcp_senddata(0);
    2 ]: _  ]- R% Q+ t
  183.                 }
    * r4 l, v/ z$ x9 J* W
  184.                 else& M, ~! B# V+ m9 L, \" g3 |+ e
  185.                 {  l$ y) s% p; q
  186.                   status_TCPProc = 0;
    + S& j9 F; k. h
  187.                 }
    ( V  V# C8 D9 a2 O1 t0 I
  188.                 cleanDtuInBuffer();
    3 a/ F* ?2 [4 P8 X5 b0 j" j
  189.           }
    $ P; K1 Q; {% q! T, v1 y4 t
  190.         }% p1 \% i* @* t0 \1 o
  191.   }9 F- I8 B7 L' z9 I& {
  192. : d: Y' C; b4 u0 o% V# ^
  193. $ s! V- q$ }# D
  194.   //把数据输出到RS232,RS485或者CAN
    3 p  o; Z2 `2 i) n/ N2 t8 d
  195.   if(a_DtuInOutConfig[0]==1)
    & K& m) F( A! {0 W+ S) |
  196.   {/ }  W3 h6 L8 a& K$ {. Z/ D; I) @
  197.         if(b_DtuOutBufferRxCnt>0)2 }; T: O; `! k# E/ Y+ r6 z
  198.         {
    : S0 M( j+ D: Y& u, x8 o! v
  199.           HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);
    ; h& B; D: D7 u& ?, Z1 k
  200.           cleanDtuOutBuffer();
    & U' y5 `; n7 z* j! V. e
  201.         }
      z, C; ~! `2 K( P0 j' _9 [
  202.   }
    # S; d( X7 w, L, E6 n
  203.   else if(a_DtuInOutConfig[0]==2)
    / C* J9 Z1 b4 w9 e* [) }2 J
  204.   {3 f% n) ^% G2 E7 M" |1 G9 s
  205.         if(b_DtuOutBufferRxCnt>0)# W: u- J; p- p! X' G
  206.         {5 m7 e1 K2 X# s9 L/ Q- F
  207.           printf("\r\n");
    : U0 J8 N; y" ^4 T
  208.           printf("\r\nData sent to RS485: ");
    + g7 h: k6 c! n) I
  209.           HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);//debug
    ! @. p6 X0 B" e5 O. x
  210.           RS485_TX_MODE();0 U# R3 X; t: S0 [! \
  211.           HAL_UART_Transmit(&huart5, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);& J; X1 I. _" K6 \. E/ l
  212.           HAL_Delay(1);
    + O: `+ E2 X, [# O) t$ g  l6 W
  213.           RS485_RX_MODE();
    1 O4 O; o4 z$ k7 o/ {) g
  214.           cleanDtuOutBuffer();2 y1 z  X" n% ~4 w7 F
  215.         }
    ; g1 z5 h) i: {1 {! G4 W2 E& x
  216.   }
    0 b  n: \5 ^- M
  217.   else if(a_DtuInOutConfig[0]==3)! N, l7 N5 Y0 q6 l
  218.   {
    ! ]( w! u& c! t' k3 L: ~" b4 {
  219.         if(b_DtuOutBufferRxCnt>0). z* c" Z# G' F& w6 O% R
  220.         {0 \9 k  Q& N) [3 d5 }
  221.           k = 0;& E1 V; y! Z' J/ Q
  222.           if(b_DtuOutBufferRxCnt>8)
    % k0 [) p, L& T
  223.           {
    - H  T! F' z, ^  n& P, T" ~' X
  224.                 for(i=0; i<8; i++)
    & h4 L! t6 S4 a3 V
  225.                 {
    " \+ `" H( x7 g& f
  226.                   Can_TxData[i] = a_DtuOutBuffer[i];
    , u) b; {# I1 j. N5 _1 S% K
  227.                   k += Can_TxData[i];
    ( z7 ?3 B! }( P" ]
  228.                 }/ N2 {5 p0 w% D( `2 \) G+ o
  229.           }
    & O4 s( H3 v+ F# _1 `
  230.           else
    ) B/ F- w$ [  X, C8 q/ L( ]; s$ E( C
  231.           {
    - ]+ s0 P+ A& L
  232.                 for(i=0; i<b_DtuOutBufferRxCnt; i++)
    / K* M1 e" S( f
  233.                 {
    ( ]% w) Y1 a8 c( z2 D" J
  234.                   Can_TxData[i] = a_DtuOutBuffer[i];
    ! c5 J, H+ v9 l1 m6 C* H$ J. s0 T3 Z
  235.                   k += Can_TxData[i];# [+ A$ q( u6 T* q0 p6 w' V6 H
  236.                 }" z7 b1 A1 Q' }- m1 ?- o4 t
  237.           }
    : g" b; |; v( I" p: z  e) R- I, s
  238.           if(k>0)5 U( e1 N+ F/ i' x$ G
  239.           {; |; i( i9 Z" b/ R$ F
  240.                 if(b_DtuOutBufferRxCnt>8)
    9 k4 {7 B, H  m4 B3 G! V: z
  241.                 {
    : K9 u* A0 ~, X2 h- K  e
  242.                   Can_TxMessage(0, Can_TxHeader.StdId, 8, Can_TxData);
    ) A8 q( v8 D0 f
  243.                 }! H, D& {! c4 v2 P4 t5 E+ L
  244.                 else
    " r" H( q! E; v+ T$ v( P" y
  245.                 {7 t% j' D# _, g" \* N
  246.                   Can_TxMessage(0, Can_TxHeader.StdId, b_DtuOutBufferRxCnt, Can_TxData);4 B) z+ m  o/ M7 A; i3 P) p
  247.                 }5 }9 g3 Q! v  j! N. \! J) c: n' H) |
  248.                 ArrayLeftShift8bits(a_DtuOutBuffer, &b_DtuOutBufferRxCnt);
    7 U# h& t/ X1 G' J7 x" Y, s
  249.           }1 W! M' u( Z' D3 Y! l) a( m, n4 \% Y
  250.           else# R8 L2 @  u6 G; e$ e& m, j9 O. P
  251.           {
    / n  c) O( u' |+ ?
  252.                 b_DtuOutBufferRxCnt = 0;
    5 M$ q+ O0 O& L: g! y$ J
  253.           }& {! s6 @* [7 P
  254.         }
    9 h( B' G2 B! ]5 l# Z4 Z
  255.   }
    9 Y% W- g6 c8 Z
  256. }
    - i* ^, _8 D7 W- G4 R
  257. void Task_DtuRedoConfig(void). N3 G2 m/ L) Y0 G! @+ l( |/ |
  258. {
    8 M2 V& ~# X; F, {
  259.   if(flag_DtuConfigUpdate==0)* P  T& F9 h, B% c9 v' A& ^" a  Y
  260.           return;
    " q. A6 J# [( s3 U5 ?
  261. % I' M+ X3 ^( N' |6 |
  262.   HAL_Delay(10);
    ! C+ R; r  T( a" B4 j: ^: [
  263.   printf("Re-initialize ETH, WIFI module, RS485...  ");8 }) a& u/ J/ W, W; I& o; N
  264.   //ETH:) o/ t( R" u+ @
  265.   if(status_TCPProc >= 2)
    . h) m; X. t9 W  p' K
  266.   {  Y# o4 b' ~1 _( h; Z0 P: ]5 w* p
  267.           tcp_echoclient_disconnect();! V' a: i, ~9 ?# B% T
  268.           status_TCPProc = 0;2 `( S4 e  m" f' N% S
  269.   }3 p. E) \7 B( Z. S
  270.   //ESP8266:: g- v7 g% I& B; P" n* x
  271.   if(Status_NodeMCU>=6)
    ! A& i4 }3 N( U& a
  272.   {
    ; w0 A6 e& }! }9 ]3 L* c& M
  273.           sprintf((char *)a_8266TxBuffer, "+++");                //esp8266 接收到这个+++会停止透传模式2 O7 f) L' H  N1 y( Y
  274.           HAL_UART_Transmit(&huart3, (uint8_t *)a_8266TxBuffer, strlen((char *)a_8266TxBuffer), 100);
    1 ~1 t% a/ _1 T# V% a
  275.           Status_NodeMCU = 0;3 P/ R( ?! A" @- ~* r9 c
  276.           HAL_Delay(100);
    # J, k  Z& e6 M$ B, x7 d
  277.   }
    , u( \6 Z  Z9 {- E* T! T: B- e
  278.   //485
    3 I% n. A* |8 W. r* ]( _0 F
  279.   //MX_RS485_Reconfigure();
    5 C  f- A. V" S/ V5 _7 t& D
  280.   printf("Completed.\r\n");
    . h9 h/ ?3 n8 m2 C* S$ f9 I* g
  281.   //8 l) S! Z' j. v! Y- y0 d
  282.   flag_DtuConfigUpdate = 0;$ k% a) r+ u! @

  283.   Y6 ?3 s- i/ l7 O2 i
  284.   HAL_UART_Receive_IT(&huart1, &b_232RxByte, 1);8 x+ t; A6 q+ L2 X
  285. }
    / t( D% X$ a/ Y$ |
  286. /* USER CODE END 0 */# h2 R& K9 h" K7 \" {3 g

  287. ! z1 d" L/ |. f! n4 D# @6 B
  288. /**/ F7 C4 w& I6 ]7 s% |& i4 P
  289.   * @brief  The application entry point.
    / M" B# M% E/ x5 ]' H3 P; d
  290.   * @retval int
    ' U1 i* l  _# G+ I
  291.   */* {/ a+ G  A7 ?# }! F. E6 u
  292. int main(void)8 h0 b' `/ M7 Q7 E1 _) R3 D
  293. {+ O# i/ A; W$ D4 K) s; G
  294.   /* USER CODE BEGIN 1 */: _1 r3 l( N. S# t5 @

  295. % N. z: x  i6 `
  296.   /* USER CODE END 1 */$ c1 l# A2 T" Z- e, b. i
  297.   3 J3 V9 H4 |; u; h6 c
  298. ) F  I& B% E0 V* K+ g  G* [
  299.   /* MCU Configuration--------------------------------------------------------*/5 s0 T% |' @0 b4 p

  300. % _. A- d' |: G4 I+ \( I1 n# L4 j
  301.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */2 n+ }4 Q* _  T  p* I) e
  302.   HAL_Init();
    5 M$ F" c; x# d$ x
  303. # O4 q5 v- R  j- p% s
  304.   /* USER CODE BEGIN Init */
    4 P3 n  u7 @! A' R2 o
  305. , M0 }9 w% U. \7 x
  306.   /* USER CODE END Init */
    7 m, b8 k, z! O5 w" }4 a4 I
  307. ( O+ O9 Y1 Q& O: n' d7 B$ R1 w
  308.   /* Configure the system clock */% Z: ]% d4 j! ~' |/ j3 ^7 W7 c4 k  |
  309.   SystemClock_Config();
    ) Q, U  [7 b0 Z8 @( V, C/ E
  310. , O9 f! L  M6 Q% x7 d$ N
  311.   /* USER CODE BEGIN SysInit */
    5 R' k/ x9 i& @8 w$ l

  312. 5 `0 N2 X4 _4 F, a7 F
  313.   /* USER CODE END SysInit */
    1 c+ t/ d4 `3 y

  314. * V8 C* R  |( Z6 ~" K' u! [( \
  315.   /* Initialize all configured peripherals */
    0 b5 z% r* u8 p8 N! Y. M. f
  316.   MX_GPIO_Init();
      I& h# T* O4 y/ L8 Z
  317.   MX_DMA_Init();
    * C& r% i% {% \0 [" r2 @; B' y
  318.   MX_USART1_UART_Init();2 `7 g/ ^* [* I9 n- [
  319.   MX_USART3_UART_Init();! C' ^; b& L" x: M! m# t1 Q
  320.   MX_CAN1_Init();2 b. Y% j- t- {$ N1 p% b  \2 ^
  321.   MX_UART5_Init();$ i7 a! |5 ]+ D( _+ C6 [& |" Q
  322.   MX_LWIP_Init();, I2 j7 s: Z4 B8 R5 I- C0 X. c" L( c
  323.   /* USER CODE BEGIN 2 */; ?% U7 ^$ M2 l$ `! c  R6 @5 k

  324. + X+ f% [7 O' L
  325.   RS232Interact_Init();6 T, }: I) k# R
  326.   printf("Hello. STM32F107_DTU project: DTU. All in one.\n");6 S. G  |: c7 X. J5 u& i
  327. ( U& o$ c0 t; }' `  z
  328.   HAL_UART_Receive_IT(&huart1, &b_232RxByte, 1);
    , G# X- P/ ]9 T- b/ o6 t6 a# D
  329.   HAL_UART_Receive_IT(&huart5, &b_485RxByte, 1);
    ( p, h+ M* u- n4 z5 I9 p: l

  330. 3 L* P: }4 Y- V! m% h4 a

  331. : u% g. V- N9 R5 y/ Z
  332.   sprintf((char *)a_8266TxBuffer, "+++");                //esp8266 接收到这个+++会停止透传模式4 @! r; j/ C. T( I; j
  333.   HAL_UART_Transmit(&huart3, (uint8_t *)a_8266TxBuffer, strlen((char *)a_8266TxBuffer), 100);. ]$ x" l: ~( @0 @& p, q
  334.   Status_NodeMCU = 0;
    5 G0 ?2 V% O8 D+ b' b7 [

  335. 3 j4 x5 Z& Q. Y  i3 b
  336.   status_TCPProc = 0;, E, }5 r6 o% D5 V

  337. , U2 {) V8 s$ q+ j
  338.   RS485_RX_MODE();
    ) Y6 f( U7 a! S5 G: [/ x* y
  339. * X9 g% H9 v. Z
  340.   CAN_Config_User();
    4 Y9 j$ f/ L+ d$ f
  341. 4 U6 |0 |  J( C5 w$ R

  342. ) F/ z* z" f* e. {" A
  343.   /* USER CODE END 2 */8 G4 ~2 d$ V5 e( \

  344. 9 m7 I& o* `' w6 X8 B
  345.   /* Infinite loop */& e; j' t, q1 }2 q) r" F% h* f! b
  346.   /* USER CODE BEGIN WHILE */2 y) f/ G$ A( i# U2 n
  347.   while (1)+ c$ H. {+ R& {4 u
  348.   {" k  `% p" U! v3 B. F/ g5 n5 M* v
  349.         if(a_DtuInOutConfig[1]==2)5 v0 k. H, G( D7 {  H
  350.         {# }0 }+ A- n( W, P2 e9 Q) ^
  351.           MX_LWIP_Process();
    ( Z+ x/ d5 \8 w" E
  352.         }3 Q4 {0 g$ I+ d3 `. |$ v3 _$ l7 P
  353.         if(flag_1ms ==1)
    " }5 }7 m; S( `) z) q
  354.         {
    5 ]- `8 O2 j+ Y3 `
  355.           flag_1ms = 0;+ g* ~' d* W+ ?& a- A# g9 H, F* ]
  356.           Task_232PC_Interact();
    + ]& J: e2 N7 }0 B# _2 p; |9 D1 I# m
  357. 7 g0 Y0 A* `! o  s
  358.           if(flag_DtuConfigUpdate ==1)( y8 _& ?9 q* Y1 Y5 r% ?
  359.           {
    $ d5 |$ X5 H5 O/ [; r
  360.                 Task_DtuRedoConfig();* H" C6 V. x7 _3 r' \! N( v
  361.           }
    ; c6 A9 F4 q/ x1 V8 F$ i
  362.           if(b_232STM32ParamConfigBusyCnt>6)( x* Q9 ^$ G4 u8 d# R! L2 ]
  363.           {/ s* N- X1 c) i1 ]7 \) s
  364.             Task_DirectTransfer();5 C2 M) y7 O# @7 g& t
  365.           }. y- p! G+ K2 N3 D0 M
  366.         }. \% C& h& c: N8 q9 V& s
  367.         if(flag_10ms==1); [% ?4 Q3 f8 y" j+ N+ d
  368.         {
    ( l8 D6 ]) A" q, x+ f' ^
  369.           flag_10ms=0;; w( k% s2 E9 l+ s

  370. & s+ }- F) z8 F7 d! v" B
  371.         }
    ! c! u8 {  C' ~" x% V
  372.         if(flag_50ms==1)        {                flag_50ms=0;            }1 t3 }- v/ a- x3 p- q
  373.         if(flag_100ms==1)& ~# j" i$ l9 m% n4 m
  374.         {
    9 E/ Q. {* Q0 l; o6 i" V: a5 b
  375.           if(b_232STM32ParamConfigBusyCnt>6). W4 k. \* f* ~+ j
  376.           {
    2 R) R4 a% W5 a: @4 e) I
  377.                 if(a_DtuInOutConfig[1]==1)! ?5 j6 ]. N/ @0 h8 C% u# ]" A
  378.                 {
    ( L# K( A3 g: p* s- ~$ A8 ?
  379.                   if((flag_ProcNodeMCUActive ==1)&&(status_232PC<12))
      A/ Q1 T, o" {! n* f1 z  l' p, x
  380.                   {
    2 x  h+ K9 Q1 z9 X+ B- _
  381.                         Proc_NodeMCU();
    ) w/ x8 Z# o6 a2 f1 c
  382.                   }
    ' p, c; Z; [; R1 k* C: Y
  383.                 }
    3 M+ j9 b/ v. j: X5 g' W* }0 b' x5 \8 X
  384.           }* g' w( r7 m+ o1 a. q2 t
  385.           flag_100ms=0;
    7 h+ i* D& r# Y: |# o* H
  386.         }7 ?. C! ^% ^( i
  387.         if(flag_200ms==1)        {                flag_200ms=0;            }; y; c9 n+ }3 G. h6 k2 B
  388.         if(flag_500ms==1)        {                flag_500ms=0;                }* M5 P9 \. q$ g6 s- m
  389.         if(flag_1000ms==1)/ ?1 s# @7 Y  |! |
  390.         {  E5 [% N! U- B0 c2 }) x- i' b) n
  391.           flag_1000ms=0;" `9 M; E( w4 P5 O8 E8 N9 w% Z1 \
  392.           HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);: H4 ^6 l$ J3 y" V% t! o: d
  393. 6 ?& s2 j3 h& d. y" s- t2 l7 F
  394.           if(b_232STM32ParamConfigBusyCnt>6): w' E% c" N; O; f, [; B
  395.           {
    ) j# B% d2 k- ]. A' T" Q
  396.                 if(a_DtuInOutConfig[1]==2)  ]" I3 c0 U/ E2 p  I# H9 k( i0 [, U
  397.                 {
    : V; T( Y( O; Q4 U1 E% Q
  398.                   if(status_TCPProc<=1)0 D" t- E8 L2 c2 i, }& B# p
  399.                   {4 X8 N& B$ u" m/ t
  400.                         printf("connecting to TCP Server...\r\n");* X( V( ]. i. z" N) b$ T( B; G6 I
  401.                         tcp_echoclient_connect();
    9 ?/ T9 o! s: l
  402.                   }
    ) F- k: P2 J. q% R
  403.                 }
    * y' R5 U, C2 o% u6 c& d; A, L
  404.                 Task_HeartBeatPackSent();
    / S+ ]4 V2 S! ~! g$ X/ N
  405.           }0 Q0 m4 q! x) |6 `0 N  S3 L
  406.           if(flag_ProcNodeMCUActive ==0)
    4 p) J% u/ p3 p& a- `2 F
  407.           {
    & b! Q- E' `1 U6 j3 k
  408.                 flag_ProcNodeMCUActive = 1;; Z2 i3 U) w8 m9 V  h
  409.           }
    4 D" B' G( W1 Z+ ^- t
  410.           if(b_232STM32ParamConfigBusyCnt<80)! V% A" `7 G: [8 \% T: j: u3 Y
  411.           {
    0 X! |6 x9 X1 X9 D
  412.                 b_232STM32ParamConfigBusyCnt++;
    9 f/ O& H% j$ f: ?
  413.           }3 q1 X  W+ ~! b9 ?# x
  414.         }
      F. E" S+ M3 M9 I6 K5 T# f& _8 ~
  415.         if(flag_2000ms==1)' h% {+ E! e' B0 k  R) ^# U" E' s+ y$ N
  416.         {
    4 x* z6 ^5 Z2 j$ B' H0 y
  417.           flag_2000ms=0;
    & _9 w  ]* L0 J

  418. ( I9 m/ L9 t# X5 i$ A, m
  419.         }
    6 E- t- Q: Q- T5 \( c
  420.         if(flag_5000ms==1)
    + {  u: v9 _! ^! M: V# r% ]
  421.         {
    7 }: O& F' @& |0 `
  422.           flag_5000ms=0;  N/ ^4 v, k/ I( i
  423.         }( i% e6 b3 h4 A. k* x" b9 d9 K

  424. ) I- u: d2 ^! G$ m; D
  425.         if(flag_10s==1). |: i( L  p, p* U" Q2 E
  426.         {5 O( n# u5 I1 k5 ~& u
  427.           flag_10s=0;
      z$ ~# b/ Y  o5 [1 b
  428.         }
    9 w( y3 M0 Z$ P4 O
  429.     /* USER CODE END WHILE */; O3 P* m# |0 [$ K7 I
  430. * |& T; w' \+ s& Z4 {3 N
  431.     /* USER CODE BEGIN 3 */( z  i  h% b% M  d
  432.   }1 i- u; K: b  ^* `; `
  433.   /* USER CODE END 3 */0 ?8 c! ~1 n/ a4 U2 B" {3 [
  434. }; N' C. ~0 S! u1 o' ~; B, y0 I

  435. & o* w6 C2 f) a, q: ?4 `
  436. /**
    ( `% r7 R5 M4 Z) _  C7 |6 m5 a. m% R
  437.   * @brief System Clock Configuration
    ! y# `2 W3 T) M# j
  438.   * @retval None
    3 D3 r6 J! E1 T8 a3 @
  439.   */! L. c5 }) n' s/ F# f
  440. void SystemClock_Config(void)( y: r6 X5 Y6 R, ^* _* \7 l7 w) P: G
  441. {6 Y3 t* T$ p/ `
  442.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    ; x7 Z0 V5 Y2 ]5 Q, |) Q
  443.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};, h& @8 T8 e3 _
  444. 8 B/ v+ w# |1 c' B
  445.   /** Initializes the CPU, AHB and APB busses clocks ) l1 |+ T/ M* p3 Y+ p
  446.   */) H4 E4 m& }1 N! c: f0 Y
  447.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    4 D5 d7 m0 [6 Z: v, r
  448.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;5 ?" v1 z% c3 r/ n( [
  449.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;5 z- M- X9 ~2 j$ V; y
  450.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;1 L; B% L& S5 w; _% \  a
  451.   RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
    1 R- x! Y3 K# |: G
  452.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;/ G% Z" ]* I2 O
  453.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    4 R* s" \( i; l
  454.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;2 S* g' B$ f, _/ ?2 Q
  455.   RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
    % ^2 s9 {# `& M, H' b
  456.   RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL10;
    6 v0 W) u7 ]" D5 p' P3 S/ F
  457.   RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV2;  C( @/ l' q) g3 d; T7 {' `
  458.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    & E* i6 }$ ~! l+ i$ b0 E
  459.   {, }1 U1 |3 U, u! v& [9 V
  460.     Error_Handler();& p# t3 j8 |2 ~# t
  461.   }) G, A, k5 b0 ]( U. x, }
  462.   /** Initializes the CPU, AHB and APB busses clocks
    2 y8 Z# [% N& l; U0 T
  463.   */
      H" }$ `0 n" m7 y* I& b
  464.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
    ) Y3 L2 N- M8 h/ p, A
  465.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    - ]  |+ \9 @- L$ g% ~* s
  466.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;2 n! z0 I+ _( [7 i% u. o
  467.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;: c# @: |! a& J" A2 ^9 R7 k% B
  468.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;- P" I& S* J3 F- ^$ x
  469.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    ' m2 P- {, v5 u7 a

  470. 2 n- S, v0 Z% q0 c
  471.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)+ e4 ?6 G+ }4 z  d2 [' f
  472.   {
    4 u( b  i: T* o6 A! P
  473.     Error_Handler();8 L$ Z' K- X: V5 E
  474.   }
    * T4 ~0 Q6 X+ p; x0 R0 A
  475.   /** Enables the Clock Security System - C) o2 I, V: ~* Q8 f6 t
  476.   *// J8 ^  Q2 }, \; _$ Z
  477.   HAL_RCC_EnableCSS();
      [3 v* y) ?- L  H4 M
  478.   /** Configure the Systick interrupt time
    . J9 T, V- i6 i
  479.   */
    ; B7 O/ i. J. J9 W$ h
  480.   __HAL_RCC_PLLI2S_ENABLE();% e' Q# c3 p" o) @2 C
  481. }% `4 K$ v: e- _: P2 p

  482.   f; h* z* Q" Q* a4 L+ ^5 r
  483. /* USER CODE BEGIN 4 */$ r9 g* G0 v4 _  f
  484. # m$ s# h7 T# @" `& J! @
  485. /**/ t$ a8 u3 Q$ v3 ~' J+ M/ y0 C6 Q
  486. * @brief HAL_SYSTICK_Callback()
    ; N9 I5 J# Y& X, y- M. j
  487. * SW timer triggered every 1ms.& Z3 s3 z; T9 O
  488. */
    ( a6 O! c/ N! Q! Z/ Y8 b- A1 f
  489. void HAL_SYSTICK_Callback(void): n5 J; Z' O& T& V
  490. {
    $ Z6 C1 z7 r2 D7 I3 r# M
  491.   flag_1ms = 1;
    + D* v/ @5 J" |0 m+ K' V3 t& R
  492.   /*update counters*/* C- j6 q6 K9 r0 `" g
  493.   if(counter_10ms<9)  {    counter_10ms++;  }
    ( R2 D7 T" R4 L* C. h- I9 _0 K5 d9 `6 P
  494.   else  {    counter_10ms = 0;    flag_10ms = 1;  }
    - v5 P9 B! x. R
  495.   if(counter_50ms<49)  {    counter_50ms++;  }, n7 }! Q( W, R2 T4 j( Z) U
  496.   else  {    counter_50ms = 0;    flag_50ms = 1;  }# j) W. N; e  ~" z
  497. ( |; \6 X$ d2 ~
  498.   if(counter_100ms<99)  {    counter_100ms++;  }) t( i% l6 q+ _1 N5 L
  499.   else  {    counter_100ms = 0;    flag_100ms = 1;
    " Q& t9 }3 C, c; S7 N. }8 A
  500.         if(counter_200ms<1)        {          counter_200ms++;        }
    + n. [- o% u* ]9 M- L! }; G
  501.         else        {          counter_200ms = 0;          flag_200ms = 1;        }+ H0 G6 Y! f2 G" f
  502.         if(counter_500ms<4)        {          counter_500ms++;        }
    * ]3 {9 u; U7 X* ^9 g
  503.         else        {          counter_500ms = 0;          flag_500ms = 1;        }
    1 }  E4 d* F9 L5 ~
  504.         if(counter_1000ms<9)        {          counter_1000ms++;        }& |& [1 A1 ^  v* ?$ H
  505.         else        {          counter_1000ms = 0;          flag_1000ms = 1;        }
    9 z6 y$ B' c, U; t* h( Y, p
  506.         if(counter_2000ms<19)        {          counter_2000ms++;        }
    + \5 }7 [; l, [4 T) t  R9 w
  507.         else        {          counter_2000ms = 0;          flag_2000ms = 1;        }
    : @/ q0 e' ~( E4 i9 t5 j, ]! `
  508.         if(counter_5000ms<49)        {          counter_5000ms++;        }1 k' N' U. H' b3 k
  509.         else        {          counter_5000ms = 0;          flag_5000ms = 1;        }
    $ `% r: H$ w5 U2 Z0 X( v$ W
  510.         if(counter_10s<99)        {          counter_10s++;        }
    : f% y# L7 @% J8 {6 ^$ N
  511.         else        {          counter_10s = 0;          flag_10s = 1;        }
    $ K8 x4 d8 G: v  s- d, V5 d* T3 n
  512.   }* Y1 ]1 ~8 ]) M
  513. }) v' B; X( b7 s/ A- F, ~

  514. 5 T7 q2 G2 C# O, n, O! A" P( j
  515. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
    1 Z% Y* z$ _# }1 c5 g1 \
  516. {
    6 h2 t% D! y9 g- ?/ [0 g% X
  517.   if(GPIO_Pin ==GPIO_PIN_13)
    + d! r5 g5 Q' D# }8 B
  518.   {
    / B5 }* G+ b5 X3 f4 N' e
  519.         b_KeyNumber++;6 \. }3 C- V5 U* [4 ]; c7 p
  520.         if(b_KeyNumber>=2)0 S: ]! Y7 ]8 X' m$ K6 b( E% w
  521.         {  @- f) c* L% E& h; e
  522.                 b_KeyNumber = 0;
    - i) t. |; H8 Y5 p8 o6 [1 U5 Y0 @
  523.         }
      O2 m0 _& D+ C5 F# A
  524. 4 g% D3 Y) ]  J. v) i6 G
  525.         sprintf((char *)a_DtuInBuffer, "a simple package\r\n");" t- X# B8 B$ A/ e6 N
  526.         b_DtuInBufferRxCnt = strlen((char *)a_DtuInBuffer);2 S! V  L$ i1 m2 X% L1 O: l1 A
  527. , t2 V: H" Y  w' K* w7 P
  528.   }
    " n* s. |( o. k3 G
  529. }
    ' S$ M$ I9 x. @5 h+ O( @! e

  530. ( ?. n4 @+ A( l& j0 S
  531. /* USER CODE END 4 */
    * J6 K- y+ C. R& G' m  b
  532. . i$ H  s/ |+ l% E
  533. /**( J8 x. K3 s: t( @0 A  w
  534.   * @brief  This function is executed in case of error occurrence.
    : K$ L1 A) s6 e1 |; I
  535.   * @retval None
    ! x3 E" ~  O  b% ?  Z
  536.   */
    8 j+ P& _2 c4 K* F. j# H
  537. void Error_Handler(void)5 T) F* `( W/ N  e
  538. {
    ! ?7 ^0 `& q7 g  s$ R8 I" p
  539.   /* USER CODE BEGIN Error_Handler_Debug */
    ' f  q) _+ q7 e4 J5 g
  540.   /* User can add his own implementation to report the HAL error return state */# d8 b. U7 l9 r: F5 M
  541. % y0 O1 e. }7 g& T' T% l/ @" y
  542.   /* USER CODE END Error_Handler_Debug */
    2 U  ]& ]. t+ `/ G7 X
  543. }& [  F; e" b" M# A) E

  544. + \6 F# x1 o: g- [, n9 R
  545. #ifdef  USE_FULL_ASSERT* Q, X$ A  {) c+ N
  546. /**
    1 \( S/ J% T6 s& p) g5 E
  547.   * @brief  Reports the name of the source file and the source line number( M% E2 P2 F0 h" R( v
  548.   *         where the assert_param error has occurred./ I- I4 x1 |- T0 W0 U& R. n
  549.   * @param  file: pointer to the source file name
    $ @' A& G- Y& n3 y7 K
  550.   * @param  line: assert_param error line source number
    $ w" Y! \( d3 O  T
  551.   * @retval None5 U, ~% l9 h  Z' S
  552.   */; ?7 \. s$ V- G% J* S0 E/ f
  553. void assert_failed(uint8_t *file, uint32_t line)
    * S6 y% K0 t, H' j
  554. {
    , o: H. x* A& N
  555.   /* USER CODE BEGIN 6 */) E( Z2 e- b1 Y' n* ?2 E' m" w
  556.   /* User can add his own implementation to report the file name and line number,$ B" v0 \; E7 E$ x( A: f
  557.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    + W- E' z" _5 V7 ?; F
  558.   /* USER CODE END 6 */
    + a  [3 m# C& h# x2 }0 y  \
  559. }
    , q" Y8 h% c6 [3 m/ P2 h3 A
  560. #endif /* USE_FULL_ASSERT */6 g4 O5 ^' b' C; k

  561. 6 P6 k( u( H! @, {) G7 n( H
  562. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码

( r3 b4 x( A8 r+ [* a* n4 试验结果

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

% @4 {' z9 ]2 J# a' D7 J: w

% V* h  D7 ?5 ]2 k$ c
收藏 评论0 发布时间:2021-11-27 09:29

举报

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