请选择 进入手机版 | 继续访问电脑版

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

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


/ U8 b$ I3 R; o4 a5 P
) p. O. l1 b0 P' w, {2 P: d! ^

3、硬石STM32F1开源的源代码3.1 stm32f107_flash.c
  1. /**9 f1 z+ c- t9 v% R, H, x
  2.   ******************************************************************************" F7 _; [  a) b, F9 u
  3.   * 文件名程: stm_flash.c / N& l  ?# B' E- N+ O- L
  4.   * 作    者: 硬石嵌入式开发团队
    # p# A4 e6 C, q* l& O1 q
  5.   * 版    本: V1.0
    / Q: L# Q3 A5 c! G( }. w
  6.   * 编写日期: 2015-10-04
    7 r' j+ h7 X4 f) b7 ~
  7.   * 功    能: 内部Falsh读写实现
    3 Z6 x" U; O* ~
  8.   ******************************************************************************. v& A9 U2 t3 Z: f% G
  9.   * 说明:1 z2 _; L) ^, b4 \
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
    6 h) Z/ X& I8 p% i# a" f. x$ W
  11.   *
    ( ^* T: Q# n/ p7 k
  12.   * 淘宝:
    - V! J% S+ D% K: f* ^3 ]( K' F! q
  13.   * 论坛:http://www.ing10bbs.com
    # u1 k8 Z" I- z# O6 G: D- a5 j+ r0 l
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
    " X% t# j# o. d2 v2 r$ O& c
  15.   ******************************************************************************
    : m2 w- p% ?$ ^; V, N0 r
  16.   */
    & A9 s+ Z* E- I9 E0 e& I
  17. /* 包含头文件 ----------------------------------------------------------------*/5 Q% o( p+ E2 p/ _9 y' K
  18. #include "stm32f107_flash.h"0 R! o5 Z2 W7 U2 W. @

  19. & _% p$ T9 P0 e7 \% N
  20. /* 私有类型定义 --------------------------------------------------------------*/' |3 @1 ]# \3 x
  21. /* 私有宏定义 ----------------------------------------------------------------*/
    " Y  p* Q* `1 j; M( l0 v
  22. #if STM32_FLASH_SIZE < 2566 H" X3 g; n# {8 {% R* L
  23.   #define STM_SECTOR_SIZE  1024 //字节& t# f, o! O1 q4 s  U0 u3 u0 m
  24. #else , K( p" s  l1 k9 {6 y' _
  25.   #define STM_SECTOR_SIZE         2048
    ( ^3 I& w8 b9 g
  26. #endif
    1 w) o/ M; N) I8 ^
  27. ! f" K5 u" T$ Z, f. k9 K" `

  28. * k0 V- \) F3 O
  29. /* 私有变量 ------------------------------------------------------------------*/- u  ]* S4 U% c. C1 b
  30. #if STM32_FLASH_WREN        //如果使能了写 ' r6 Y" Y' j4 h, U( P/ x: O' E
  31. static uint16_t STMFLASH_BUF [ STM_SECTOR_SIZE / 2 ];//最多是2K字节
    6 e0 {8 D  G$ K' @$ e
  32. static FLASH_EraseInitTypeDef EraseInitStruct;# j/ S- {! `5 ~! E) p0 |% T  q
  33. #endif
    9 i% _8 D& b8 s4 o: Z
  34. * t- R5 |' A8 p9 x  E! o. o
  35. /* 扩展变量 ------------------------------------------------------------------*/
      d7 S! O5 f& @) ]$ S" _9 h" r" ~
  36. /* 私有函数原形 --------------------------------------------------------------*/
    / n" z" G2 [' }
  37. /* 函数体 --------------------------------------------------------------------*/. O) z. O, _* t3 j
  38. /**
    ) |/ f4 G4 s! C( _
  39.   * 函数功能: 读取指定地址的半字(16位数据)
    8 ?2 r- t% \# k0 C" K9 P8 I/ V
  40.   * 输入参数: faddr:读地址(此地址必须为2的倍数!!)
    3 Y# q* j7 g- o
  41.   * 返 回 值: 返回值:对应数据.- u6 c: B) U: ^7 P6 w% {
  42.   * 说    明:无! k) v+ M  _1 _
  43.   */
    * {8 V* R0 N4 k3 E
  44. uint16_t STMFLASH_ReadHalfWord ( uint32_t faddr )+ P  W6 @2 p6 I6 ]  U$ r4 b
  45. {# \/ T4 E: ^, c0 W3 u
  46.         return *(__IO uint16_t*)faddr; + C7 {" u& d, n1 w6 {, S* M
  47. }8 t5 L$ |$ {3 ?+ l
  48. 6 [& j% Q- G8 x  {6 S& Q
  49. #if STM32_FLASH_WREN        //如果使能了写   , H* P8 Z+ c7 ~/ a7 I
  50. /**
    : n# `  G& V7 r8 v% p
  51.   * 函数功能: 不检查的写入
    1 O3 S7 @5 M$ h$ a2 U
  52.   * 输入参数: WriteAddr:起始地址$ T- Q, v$ s2 u' @$ C- R2 S
  53.   *           pBuffer:数据指针
    ! K9 y" F! D  l8 k1 [4 R
  54.   *           NumToWrite:半字(16位)数
    / L5 B. e& J) T& u4 F
  55.   * 返 回 值: 无8 w# O6 _# i( V* X) R: y7 M6 L
  56.   * 说    明:无
    ( g( r9 P& l7 ?& [4 R- r
  57.   */
    ' E) M- ^1 \  p; ~0 I
  58. void STMFLASH_Write_NoCheck ( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite )   ( R. b4 ~1 l7 d. Y- O% m& L
  59. {                                           ' n7 E0 B1 j% [, e7 R
  60.   uint16_t i;1 r1 A7 O- J" T" t. F: O% a
  61.         * F2 e( \& F( |3 _3 C1 V
  62.   for(i=0;i<NumToWrite;i++)
    7 E0 q% w" f( N
  63.   {& @& M5 Y. O& R5 V/ q5 f& `# E
  64.         HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,WriteAddr,pBuffer[i]);
    8 U1 G8 J8 i3 C
  65.         WriteAddr+=2;                                    //地址增加2.
    ' o! C. T+ v. Q& G
  66.   }
    ) |9 z' e2 A- h# E9 U  Z9 Q) w; K& q
  67. }
    5 J. s! j- R- z  C' ]0 `1 w

  68. 1 _1 }( l( n, U5 y/ T2 Y' D
  69. /**# I9 j3 o- a1 B! c. [/ a' B
  70.   * 函数功能: 从指定地址开始写入指定长度的数据' E8 P2 y  k1 ]! p
  71.   * 输入参数: WriteAddr:起始地址(此地址必须为2的倍数!!)
    & o; d) h1 J5 @
  72.   *           pBuffer:数据指针
      A/ m6 ]( |& h% |
  73.   *           NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
    " Q! w" ~6 T4 C- E4 c$ b6 E: j
  74.   * 返 回 值: 无- K- u* u+ P( ?; }( z
  75.   * 说    明:无" O3 R) L# G! M
  76.   */
    - U4 `/ p$ o; j2 F4 @& j. \
  77. void STMFLASH_Write ( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite )       
    * Y$ O( C5 Q! w  R0 s: F
  78. {
    6 D  M0 k% Q. J# \
  79.   uint32_t SECTORError = 0;, a9 d9 v! B& H# r- R% `
  80.   uint16_t secoff;           //扇区内偏移地址(16位字计算)
    $ |8 |' T, d/ x6 b( _- z; |
  81.   uint16_t secremain; //扇区内剩余地址(16位字计算)
    # W9 r* T  |9 W' j( ^
  82.   uint16_t i;
    # s6 ^$ q3 G) J- h' k/ [: ~* a
  83.   uint32_t secpos;           //扇区地址6 G% a, v2 n% N# P$ ?
  84.   uint32_t offaddr;   //去掉0X08000000后的地址  N6 z( S' l, |
  85.         1 y/ K+ L3 V9 j4 y; {9 H
  86.   if(WriteAddr<FLASH_BASE||(WriteAddr>=(FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址7 [" n3 U/ Y2 R- M# W9 G2 N6 }
  87.        
    5 @4 {. ~- `; I$ d% ~
  88.   HAL_FLASH_Unlock();                                                //解锁
    % L: ^" F) D3 z6 c
  89.           E+ t- a% Q; r. B0 I& d
  90.   offaddr=WriteAddr-FLASH_BASE;                //实际偏移地址." k  s# ~# A0 p% Q0 |" p
  91.   secpos=offaddr/STM_SECTOR_SIZE;                        //扇区地址  0~127 for STM32F103RBT62 V" p( p  w5 X* F  I9 E
  92.   secoff=(offaddr%STM_SECTOR_SIZE)/2;                //在扇区内的偏移(2个字节为基本单位.)/ @% e7 h( m8 ~# f
  93.   secremain=STM_SECTOR_SIZE/2-secoff;                //扇区剩余空间大小5 E! L0 X2 C& d. H/ C1 `2 b
  94.   if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
    + V2 k: ~+ v% F# Q2 i- _4 k
  95.        
    8 u# x6 b- w! [/ ]5 e) [9 ^
  96.   while(1)
    & K2 B: _$ l  @$ j9 ]
  97.   {# F: p7 j1 ~( `
  98.         STMFLASH_Read(secpos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容4 P4 q) P( p9 O. [4 P6 @
  99.         for(i=0;i<secremain;i++)//校验数据
    & n) E4 l- ~0 b9 _* ^. w6 o& M. N
  100.         {3 o  Y( @! r# \: |
  101.           if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除
    ' Q* [, v. B! S3 L. S4 w
  102.         }
    & G% w0 S3 d# r
  103.         if(i<secremain)//需要擦除
    8 c, |7 c0 h! P3 |# ~- q, `0 h/ ]
  104.         {
    " c' D8 u, d: }% T& t+ V+ v
  105.           //擦除这个扇区
    % ^% h& v" E" R5 F5 y- S* `$ z
  106.           /* Fill EraseInit structure*/
    ( m, p4 `5 n/ X& O
  107.       EraseInitStruct.TypeErase     = FLASH_TYPEERASE_PAGES;
    7 }( w: A* `0 ]1 ^2 O
  108.       EraseInitStruct.PageAddress   = secpos*STM_SECTOR_SIZE+FLASH_BASE;+ R% H' }3 f) T
  109.       EraseInitStruct.NbPages       = 1;! u3 |6 k) @0 S5 s% f
  110.       HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);
    8 K" k0 l) H2 U( c$ T

  111. 3 P+ w# [) a* G5 c- a) B+ t
  112.       for(i=0;i<secremain;i++)//复制
    3 |7 ]# [3 [, Y, s  q, u
  113.       {% A+ I* O  }5 C
  114.             STMFLASH_BUF[i+secoff]=pBuffer[i];8 K/ j  l8 l0 t' c4 L% r  K
  115.       }4 I+ e$ r/ d9 ~5 s8 U
  116.       STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区
    . r1 q1 t$ n8 f. l& @4 v5 [# P
  117.         }6 P+ ?( I! a9 N, g% V% Y0 ]
  118.     else' o# m  s( y2 l7 o4 f* \% P
  119.     {+ Z  r, A5 d3 s* Z2 j
  120.       STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.                                   
    % U8 \7 H+ u* O
  121.     }
    ( o' L; X5 [9 c: w' n( s! A
  122.     if(NumToWrite==secremain)break;//写入结束了/ I0 S. V' C  _% T$ h
  123.     else//写入未结束
    4 C. d4 w: B& [+ }6 d& o
  124.     {
      X4 K1 M0 g5 P8 C; v
  125.       secpos++;                                //扇区地址增1+ X1 P+ ?* ?; g& f0 x: T8 u
  126.       secoff=0;                                //偏移位置为0
    . X: `1 C) `5 r# {
  127.       pBuffer+=secremain;          //指针偏移  p1 c) [$ H4 t' i
  128.       WriteAddr+=secremain;        //写地址偏移& U3 \5 p2 Y5 F/ t
  129.       NumToWrite-=secremain;        //字节(16位)数递减
    ! _5 i7 H( a- U) t% o# l" h- |
  130.       if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
    " Y6 \; p! z% `$ ^
  131.       else secremain=NumToWrite;//下一个扇区可以写完了5 C2 i6 C' x2 j/ H! j: s
  132.     }
    ; Q3 k6 C, v" {4 @  V% E
  133.   };* B2 T# o7 I9 Z- P. n5 N. v
  134.   HAL_FLASH_Lock();//上锁3 W- X/ t0 h1 O  W7 J( B$ l+ R
  135. }8 a8 W( R- }4 ]4 b% {7 B6 E4 f
  136. 4 O7 j; x  e$ h: O, v
  137. $ I% ^8 s' e) n8 @5 N% f
  138. 9 G9 @+ B/ p+ E$ |8 Z5 t
  139. #endif( K  H/ X  O4 w$ b' @

  140. 1 N1 ~) o8 p4 d" _
  141. /**; k6 U. k8 N0 ~: I8 O
  142.   * 函数功能: 从指定地址开始读出指定长度的数据
    ' ], T5 p6 S! L  B
  143.   * 输入参数: ReadAddr:起始地址
    8 n7 [) C0 W6 }6 K+ b: y
  144.   *           pBuffer:数据指针- |# ]" f$ O- @( y0 b/ g
  145.   *           NumToRead:半字(16位)数
    9 Z' \: [' D1 s$ M7 E
  146.   * 返 回 值: 无
    $ A0 v8 q* t  s. H/ h; ^, C
  147.   * 说    明:无5 T( c3 }6 w- J5 `( c# A6 B7 w% `
  148.   */1 s5 ^' W- ~7 H: J  b* i( U
  149. void STMFLASH_Read ( uint32_t ReadAddr, uint16_t *pBuffer, uint16_t NumToRead )           / w; R2 [6 E* ^9 x% G. O' c7 G' k
  150. {
    3 G6 n/ ]& Q% k* K
  151.   uint16_t i;8 Z8 _6 a# |/ I- B" x
  152. + m6 `: g+ s6 z: u1 c
  153.   for(i=0;i<NumToRead;i++)
    ( F; K. F. m0 |$ P, Q
  154.   {  R$ V  E3 W& c, \
  155.         pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.' t9 l% p; v1 h  R; k& |8 g
  156.         ReadAddr+=2;//偏移2个字节.
      R3 I5 C% j/ L, m; u' w' e3 l- M
  157.   }
    & r  X, y* b+ g4 e! E5 M: w
  158. }. F0 |* x& s3 r" \+ A. S
  159. ; O9 o0 m" v' m, d9 }' ]
  160. /*
    0 m, D, z& n( S- C% Y
  161. * 函数名:Buffercmp
    . `; Q0 e1 d) k, Z5 G
  162. * 描述  :比较两个缓冲区中的数据是否相等
    * J& I6 T" A3 Q: ?0 y% L4 w9 I
  163. * 输入  :-pBuffer1     src缓冲区指针; I6 ~7 p% e' k7 ^- e) w: M
  164. *         -pBuffer2     dst缓冲区指针
    # }9 s, k; [" }  m
  165. *         -BufferLength 缓冲区长度
    " Y# {5 f& e$ W% X* [% q7 l
  166. * 输出  :无
    + d2 J% X9 ~2 I. l
  167. * 返回  :-PASSED pBuffer1 等于   pBuffer29 T- ^1 v, P+ a( x
  168. *         -FAILED pBuffer1 不同于 pBuffer29 k" `) w1 @; C$ {
  169. */4 I4 X, |& R& x% w4 L# }$ s2 O
  170. TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength)
    & L/ o0 J8 u* X8 n
  171. {5 b* M* M- {0 j) R
  172.   while(BufferLength--)6 K, E+ q$ ?, l" A+ w# e  C+ @
  173.   {( X! q1 p" d$ T- U; z
  174.     printf("data:%d - %d \n",*pBuffer1 , *pBuffer2);
      `$ ]$ V8 x7 R, p; f$ n' u# W/ q  l
  175.     if(*pBuffer1 != *pBuffer2)) s8 G* {/ x' \$ u( o" i. T) |
  176.     {
    0 E  z4 x/ ]% b6 `
  177.       return FAILED;: [* X$ S, [2 D- [
  178.     }
    . L/ ^3 S8 z# @6 R

  179. ) K0 i5 D; N/ O
  180.     pBuffer1++;
    2 o4 g% k% L* _9 o
  181.     pBuffer2++;
    7 {' E0 ~( n% r
  182.   }
    % @2 [; F2 |9 c/ k1 p% p' Q8 P
  183.   return PASSED;$ d, m8 A  J& L  K
  184. }
    8 ?2 y' Q- |8 H8 Q9 x& y5 V. G5 f

  185. ! P* V2 p" \0 f# U# v
  186. / c) ]+ e. ^0 P& Y% y; o
  187. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码
3 X/ w. K# s! u' `5 S
3.2 stm32f107_flash.h
1 V! O* u4 D0 w5 {$ M" {) i+ r
  1. #ifndef __STMFLASH_H__  ~7 s4 l8 d3 x; z6 V
  2. #define __STMFLASH_H__3 b' _! ?# V6 J" ?9 L

  3. * y8 V! O  k- E# t6 d7 }" O5 C
  4. /* 包含头文件 ----------------------------------------------------------------*/
    5 h9 |0 C9 T7 q8 m/ w2 f
  5. #include "stm32f1xx_hal.h"
    - B! X8 `+ R; |2 j! s+ `
  6. : h. q; S% N$ ~$ k$ r
  7. /* 类型定义 ------------------------------------------------------------------*/
    * t5 b8 \. Q0 k; y9 E8 l% p# y
  8. /* 宏定义 --------------------------------------------------------------------*/
    ( q, z- q: N4 u1 C4 H8 a
  9. /************************** STM32 内部 FLASH 配置 *****************************/9 k3 ~! @$ U5 N/ t0 H
  10. #define STM32_FLASH_SIZE        256  // 所选STM32的FLASH容量大小(单位为K)& x: T! r+ j1 Z! i
  11. #define STM32_FLASH_WREN        1    // stm32芯片内容FLASH 写入使能(0,禁用;1,使能)- C; q9 H1 a4 R4 T  w6 v$ }; k
  12. ! G/ C; j6 W) C" o, a  d; ~
  13. typedef enum, d; N' u8 O- g6 H3 C5 k! _1 O; Z
  14. {) ^( ~% ]' |  T: I; W1 i
  15.   FAILED = 0,+ `1 w  r. U: j4 W8 P0 ?2 D7 v2 N
  16.   PASSED = !FAILED
    ! @: E* B1 |% i" R% J
  17. }TestStatus;
    $ ~  _3 A# b5 v+ M
  18. ) _0 |  i$ T0 l: p. e  S
  19. #define  FLASH_WriteAddress     0x0803F800            // 写在靠后位置,防止破坏程序
    " Q# s0 g8 ~6 t& S9 ]8 A5 w
  20. #define  FLASH_ReadAddress      FLASH_WriteAddress
    . b/ ~, U) P. Q. `
  21. #define  FLASH_TESTSIZE         512                 //实际是512*2=1024字节
    7 V" ?" x, Z8 I& V

  22. % G. W! ?0 E- b' S

  23. 5 ~1 Q, a: }* ]& U0 T) Q9 M. [* i
  24. /* 扩展变量 ------------------------------------------------------------------*/1 `5 t6 F2 Z6 A" S/ P: k- K; t( ]
  25. /* 函数声明 ------------------------------------------------------------------*/
    + g8 y5 K' J+ d
  26. uint16_t STMFLASH_ReadHalfWord(uint32_t faddr);                  //读出半字! T* t- r3 @6 ]. T2 U, N! ~
  27. 3 [1 M$ S# u, [- `
  28. void STMFLASH_WriteLenByte(uint32_t WriteAddr, uint32_t DataToWrite, uint16_t Len );              //指定地址开始写入指定长度的数据
    5 ~7 Q0 w9 D- |4 F* K8 a
  29. uint32_t STMFLASH_ReadLenByte(uint32_t ReadAddr, uint16_t Len );                                                                    //指定地址开始读取指定长度数据
    $ ?4 o9 q# m; j+ o" B) z
  30. void STMFLASH_Write( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite );                //从指定地址开始写入指定长度的数据
    7 s1 h4 v: Y: A/ _/ b' ~4 x
  31. void STMFLASH_Read( uint32_t ReadAddr, uint16_t * pBuffer, uint16_t NumToRead );           //从指定地址开始读出指定长度的数据
    9 p4 W* n7 O( s$ ~5 V) ]
  32. //static TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength);5 h, O/ `% h5 Q- @. C& \6 B$ X+ h
  33. TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength);
    : ^, H8 x; e; N6 {1 J( F. g: j
  34. 8 m) \) d* M! e/ I7 [; M7 s
  35. #endif /* __STMFLASH_H__ */% V# u$ u2 a8 _# K9 ?

  36. 7 Z9 }' f  N/ a  k8 r0 ]8 [+ d: K
  37. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码
1 z, E7 Y+ |% u
3.3 main.c3 ^# o1 w8 B2 ^. l
  1. /* USER CODE BEGIN Header */: y- W5 ~6 F, B
  2. /**8 z+ q2 P  O2 ?! x. {: G
  3.   ******************************************************************************
    - u# I& ]1 n7 k, _7 l
  4.   * @file           : main.c
    & d( K  k9 |; x. L& e1 w. {
  5.   * @brief          : Main program body) z- }/ G4 x3 y2 {
  6.   ******************************************************************************
      Q3 `4 n/ G( S/ ]' ^2 m' e
  7.   * @attention, p/ K  ]( j8 J2 i6 h
  8.   *  x) S, W$ S8 P0 i( z- J
  9.   * <h2><center>© Copyright (c) 2019 STMicroelectronics.
    5 Z' s' U$ m" }
  10.   * All rights reserved.</center></h2>
    " L, F7 z: ]$ s
  11.   *
    6 h2 v7 }+ o) K+ u: [% t8 e
  12.   * This software component is licensed by ST under BSD 3-Clause license,
      x" o3 N2 j+ R/ E
  13.   * the "License"; You may not use this file except in compliance with the- Y' D( w' b0 N1 |* S
  14.   * License. You may obtain a copy of the License at:0 e5 J$ v$ _8 O, ^- G5 f2 T
  15.   *                        opensource.org/licenses/BSD-3-Clause; B. y/ U: Z. l& ~2 J3 ~
  16.   *
    8 Y/ Z' l  q* a, l' t, i# S
  17.   ******************************************************************************9 A3 {% g# y, B. E
  18.   */
    * H( \2 _, R% S5 b) s
  19. /* USER CODE END Header */
    : Y* B3 ]; m2 A1 I$ W4 c

  20. 4 S, w1 w( v# O5 P) d
  21. /* Includes ------------------------------------------------------------------*/" ]7 T0 S: j0 F* k
  22. #include "main.h"+ ^0 }1 ~6 c$ D9 b6 w  U
  23. #include "can.h": U( {, U4 G9 n1 r
  24. #include "dma.h"! u) J7 e% r$ h5 Z/ A) l. C: D
  25. #include "lwip.h"
    + d* u- P& e+ U+ O0 E( D3 A
  26. #include "usart.h"
    ' H& S1 M1 b# y3 \& D8 u' d: s
  27. #include "gpio.h"7 Z3 S5 f# N2 S9 w
  28. ; [* v* z- m" R; z4 ^6 k
  29. /* Private includes ----------------------------------------------------------*/: Z) l  s4 q) E& s- p, Z  |
  30. /* USER CODE BEGIN Includes */
    + m9 q& T. z) w3 h& }
  31. #include "string.h"
      N. B2 R) M. D) o
  32. #include "tcp_echoclient.h"
    / E4 T! f4 o$ @9 ?

  33. $ a- S$ ^( `. i8 o0 M. c. S7 q$ Z. g
  34. /* USER CODE END Includes */
    : L+ m  n. n" K# ^+ `* W. h
  35.   y/ v1 v  g; i+ M. u6 }
  36. /* Private typedef -----------------------------------------------------------*/
    % l+ n+ G. h. U' J8 o
  37. /* USER CODE BEGIN PTD */
    . j5 Q6 _$ ]) F! o/ R: G; ?* W

  38. * T' B+ i. r5 M, t  j
  39. /* USER CODE END PTD */
    - `, \+ x8 q9 N3 K$ f5 W

  40. 2 N* q- B4 }- z" C' M; z, h
  41. /* Private define ------------------------------------------------------------*/
    " d; P6 C9 ~( Y7 v
  42. /* USER CODE BEGIN PD */0 i" h* l2 K# O' Z# D$ e
  43. #define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))
    ! G% J3 O3 h- V4 ]6 F" z
  44. . T7 ?! z' \! L9 [
  45. /* USER CODE END PD */
    - {& ?: y2 `7 S, H% e: ~& @' x

  46. 2 E& g9 n, @# _6 Z9 q
  47. /* Private macro -------------------------------------------------------------*/$ W! M& R0 M0 P. M
  48. /* USER CODE BEGIN PM */
    5 p) b! D( J! x, _8 D+ a( U
  49. 1 j$ b$ k4 H, c. D6 b. w$ D( f9 w
  50. /* USER CODE END PM *// Z3 B. J7 S$ Y$ p3 s; Q& d1 `0 T
  51. ! d9 o1 X6 B1 j
  52. /* Private variables ---------------------------------------------------------*/. a! A* s4 o9 U& ]
  53. ) _8 Y+ Q% t) ^9 J! I* w
  54. /* USER CODE BEGIN PV */2 c( j, H" r# V! n% M+ p
  55. uint32_t  counter_10ms, counter_50ms, counter_100ms, counter_200ms, counter_500ms, counter_1000ms, counter_2000ms, counter_5000ms, counter_10s;
    7 C* o( _0 z* @8 O  f  b
  56. uint8_t flag_1ms, flag_10ms, flag_50ms, flag_100ms, flag_200ms, flag_500ms, flag_1000ms, flag_2000ms, flag_5000ms, flag_10s;
    $ ~9 }' b) k) Q: n% s: T( `" S9 _
  57. uint8_t b_KeyNumber;
    " ~/ Q6 l- H5 ~- z1 H. q
  58. # J' \/ J$ V4 A. G' w  s' P1 e# K
  59. uint8_t a_DtuInBuffer[100];
    4 B, h' D: M% X" G
  60. uint16_t b_DtuInBufferRxCnt;
    7 D% M6 Y8 V, `, {
  61. & u+ t8 y/ v+ r  @* u
  62. uint8_t a_DtuOutBuffer[100];# i# k4 l* n9 s9 c+ P
  63. uint16_t b_DtuOutBufferRxCnt;5 o. F* @1 k7 G9 f1 d  b0 |: A: z
  64. ( b. P7 z$ Y" ^% z  w8 b$ H
  65. struct netif gnetif;
      v0 E* {2 o$ k. e  n* F; ]  }
  66. extern struct tcp_pcb *echoclient_pcb;6 D4 l: u- a: N7 a
  67. uint32_t status_TCPProc;1 @% s* X5 b2 ]" ?0 }) D8 J
  68. 0 _' E& N  t7 S, n/ [$ S

  69. * x' K5 @  |- P- o) q
  70. uint8_t a_SocketConfig[7];
    & G1 p: L; I8 s7 n
  71. uint8_t a_SocketHeartBeat[60];
    5 y  U# L" t% m( O
  72. uint8_t a_SocketHeartBeatInterval[2];
    . Y% F" ?( v' c9 ?/ G! U
  73. uint8_t a_SocketRegister[60];
    & @; P7 r2 O" H7 q% t7 s
  74. 4 r# J7 g" l4 x2 T% w3 R: c; G
  75. uint8_t a_DtuInOutConfig[2];
    - m3 t  t4 A+ {' s6 c

  76. 1 ^- Y5 |2 }0 N) a. B$ k: d  s
  77. uint8_t b_WifiMode;- B2 \" [/ v& F! ]; A. |. P* Q
  78. uint8_t a_RouterSsid[20];  G* E1 D3 `) \, W; o3 F/ ~
  79. uint8_t a_RouterPswd[20];
    0 M. c; T3 D5 _# Q2 a2 C" F

  80. 7 X/ f- @; Y4 n" z
  81. uint8_t a_Rs485Config[5];
    ; d( O8 P; `( ~- R. }) Y' ]- x
  82. uint8_t a_CanConfig[5];  }* F; Q) K4 w, f
  83. 2 S. |/ j0 \! B- u) L
  84. uint8_t flag_DtuConfigUpdate;  {0 P3 W' k: E3 }5 @* K
  85. uint8_t flag_DtuEthReady = 0;% [' L9 }9 _* l: V9 `9 V

  86. , |* E. ?" J. _3 P2 a
  87. uint32_t b_HeartBeatPackageCnt = 0;
    " p* V1 c- g$ a) K4 B6 w* o+ z

  88. 0 \4 W0 _% w! [! d) x/ N
  89. uint32_t b_232STM32ParamConfigBusyCnt = 0;        //尝试通过串口和STM32交互时候,会让出相应时间,优先处理
    / }( v' J/ ?4 [+ g7 X# E7 q  Y0 k
  90. / _- B& ~" r# }' F2 a- W3 `: C
  91. /* USER CODE END PV */
    ) x. k! X. Y. ^, R' r

  92. 3 M6 Q% G, t# H$ K8 y( r
  93. /* Private function prototypes -----------------------------------------------*/! D6 p) E* k5 o1 Y7 M
  94. void SystemClock_Config(void);
    % M2 S3 k! {9 A- V+ v. O
  95. /* USER CODE BEGIN PFP */% y+ d+ I& t" G& O; X- d  I

  96. ) D9 G. K; e. c' F8 K
  97. /* USER CODE END PFP */- M; D8 G  H7 {2 R. H5 N

  98. 0 s6 w# H/ d6 Z0 W* P& E3 _
  99. /* Private user code ---------------------------------------------------------*/
    0 f" y- y/ }5 H2 G5 C& r
  100. /* USER CODE BEGIN 0 */
    ) D) B) p. h7 E, G# u
  101. void Task_HeartBeatPackSent(void)
      ]3 [8 i' {2 h# Y' B
  102. {& m% t  a! y4 s; T3 w  F8 ]
  103.   uint16_t b_interval;7 s; j0 x( S, X4 N. X7 t1 t
  104. ; l% ?/ H9 F) C& |5 |
  105.   b_interval = (a_SocketHeartBeatInterval[0]<<8) + a_SocketHeartBeatInterval[1];$ O- f) l1 \; h

  106. - M* m+ D3 y( `( }3 r% I" e" N
  107.   b_HeartBeatPackageCnt++;
    & J1 m1 Y1 R/ |2 H. w5 U4 H
  108.   if(b_HeartBeatPackageCnt>=b_interval)5 E, e% M) b$ V' o8 R; y( x
  109.   {2 I- F" Z& [2 y
  110.     b_HeartBeatPackageCnt = 0;
    2 u3 O- b5 z( s  m8 Z

  111. + V) G8 M( n2 u1 U4 A6 W# w, J3 ]

  112. % v4 c1 ]% }; D# O& [8 i8 R
  113.     if(a_DtuInOutConfig[1]==1)! m' t1 h/ I! ?1 y$ y' f
  114.     {; d+ H% B  U  ^! v+ W* N. ?4 ~5 S
  115.       if(flag_8266DTUReady==1)
    ( }6 j7 v7 m1 }3 j
  116.       {
    ( T# z$ S; {& U3 C5 s+ ]
  117.             HAL_UART_Transmit(&huart3, a_SocketHeartBeat, strlen((char*)a_SocketHeartBeat), 100);
    ' I  U/ G/ q. v7 P# s" f) v/ N2 ~
  118.             printf("\r\n");
    + n8 ]3 v- A9 A1 G5 \
  119.             printf("\r\nA heart beat package is sent.\r\n ");
    7 b7 [* T) b& C2 l& f6 z
  120.       }
    3 ^0 S3 {  r" H9 A; z( [
  121.     }1 ?. t' ]" n8 L) y
  122.     else if(a_DtuInOutConfig[1]==2)
    6 L5 ?' Q1 G) T7 @
  123.     {
    3 E3 a8 p/ u$ ~& o
  124.       if(status_TCPProc>=2)0 Y) }: e0 w% q% Y% ~- O
  125.       {9 N: a8 b4 F. a' ], z  t6 A
  126.             tcp_senddata(1);4 m/ _- v5 k6 Q0 z
  127.             printf("\r\n");4 `0 l" m0 T; V4 A/ k4 E$ ^7 U
  128.             printf("\r\nA heart beat package is sent.\r\n ");
    . Q* z5 I6 i* j3 I
  129.       }' G6 T  s6 i+ K3 a( r3 }/ j  f* S
  130.     }
    : i1 x% y& b: v4 H  ]
  131.   }
    , ^3 H* M% _. C* ?) G' W
  132. }
    . e$ ?9 j1 F" Y7 r6 |- G8 x
  133. void cleanDtuInBuffer(void)0 [, s0 d$ y. m8 }1 X, w" `
  134. {
    ; [7 f! S5 @4 v# Y# }2 H. U
  135.   uint32_t i;
    , ?8 \! J$ X# p5 e' G4 h& U
  136.   for(i=0;i<b_DtuInBufferRxCnt;i++)
    0 r9 C  }, v5 v3 a3 j7 |
  137.   {
      \4 I) O" K* e8 I, m; |& l
  138.         a_DtuInBuffer[i] = 0;0 H0 T( r: x2 j# W2 G
  139.   }
    ' ^4 F" x3 k' l! q4 ^( e& [; e
  140.   b_DtuInBufferRxCnt = 0;; E$ S  E- E; d, Y" M: m3 Y: F; S) l
  141. }
    " h4 A" L. p. `6 ~8 o# m) M
  142. void cleanDtuOutBuffer(void)3 {2 E% G! A7 m; k* C$ b- q# b' P
  143. {
    - o6 n% M, `& \) w+ [7 }
  144.   uint32_t i;
    ( g- }. z* B3 G' `# x3 M$ C
  145.   for(i=0;i<b_DtuOutBufferRxCnt;i++)' l! x5 i8 a$ E. C* h8 |* [1 r$ @
  146.   {8 E$ x) w! J/ s- J& w
  147.         a_DtuOutBuffer[i] = 0;% N/ j3 ~2 M- v! s  {
  148.   }  C7 o/ l8 l% H/ H5 F
  149.   b_DtuOutBufferRxCnt = 0;
    ! A' s( X+ _/ g
  150. }
    ; P7 a7 H5 E2 I3 N! F
  151. $ j6 K& C4 N; ~5 F% ?  x
  152. void Task_DirectTransfer(void)
    * D6 w) R; X, }2 f- y
  153. {
    ' K6 l) ?0 V- q, _$ h  H
  154.   uint32_t i, k;
    : x6 ?9 y$ [9 `% w6 [/ R! Q. y
  155.   //把数据输出到以太网或者WIFI
    ' ?- w. L7 H; t3 z: ^2 H
  156.   if(a_DtuInOutConfig[1]==1)
    ' F6 S7 h, g; r$ n# r
  157.   {
    # n) D  Y7 I0 p0 D' `: w" Q
  158.         if(flag_8266DTUReady==1)
    1 M2 w( s: x4 S3 W- a5 Y. \! Q
  159.         {
    , I9 r3 G; F" ^  ^6 ~
  160.           if(b_DtuInBufferRxCnt>0)
      _& H2 c7 J& R8 B
  161.           {; ~! {* h' k; b: d% p
  162.                 printf("\r\n");' A9 D# ?* u7 g* @$ t& K3 o1 |
  163.                 printf("\r\nData sent to Wifi: ");& T4 p1 u7 |% J& E! I; C* t; [, K
  164.                 HAL_UART_Transmit(&huart3, (uint8_t*)a_DtuInBuffer, b_DtuInBufferRxCnt, 100);2 f; j" i! J# W0 s# l; W
  165.                 HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuInBuffer, b_DtuInBufferRxCnt, 100);        //debug
      P" k" ^1 S) T3 a+ y
  166.             cleanDtuInBuffer();& s( S# w5 _$ i0 B) D8 U
  167.           }' J' x$ r8 t$ O; e: h& Q* n
  168.         }; }4 s3 z7 i0 f& X* `5 q! h  j# M
  169.   }
    - d: D! {8 ~7 @( N& H
  170.   else if(a_DtuInOutConfig[1]==2)
      w7 S& v7 }9 s) n
  171.   {
    # Q2 {5 K+ C. W7 y7 r
  172.         if(status_TCPProc>=2), F* m5 t2 U6 i# [2 X+ ?* l
  173.         {( _2 f$ A( p5 f& B0 Z( j0 c
  174.           if(status_TCPProc == 2)
    6 H# Z) d2 i; J2 n9 V/ i% @
  175.           {
      [7 O3 G5 w( P6 t" h0 M( S% L
  176.             tcp_senddata(0);        //专门发送注册包
    + s' U2 J* ]$ P3 F9 H  I3 N( W
  177.           }
    6 u5 Z3 z0 R2 M: F# D+ _, ~# @
  178.           if(b_DtuInBufferRxCnt>0)
    # h6 u3 l0 ]" X( |# I
  179.           {  R7 a- D+ z1 ^4 _
  180.                 if(status_TCPProc <= 3)6 ^( ^; E& R9 {$ o
  181.                 {
    9 p2 ~& X( l+ s' B% ]. ~5 t) R. n
  182.                   tcp_senddata(0);
    0 u) S. D, y' b# ]9 }
  183.                 }) d6 E$ f' a3 d; c# {2 W
  184.                 else! I: R) f/ R# M9 E. o5 U% Z% Y
  185.                 {
    5 f* z* o5 t8 G' L$ z6 n# P  g
  186.                   status_TCPProc = 0;
    1 Q7 D, d2 L7 B, k5 t+ [
  187.                 }9 E/ L8 j: B) z$ l! T
  188.                 cleanDtuInBuffer();  q% N$ Y% l& s6 D, M' e
  189.           }" Z$ e+ L3 z% a" G+ P' |/ y, b
  190.         }/ K9 ]5 M8 L$ ?! B7 H* O
  191.   }3 z' q8 k0 X4 q0 Q* j

  192. + k1 F6 P& [6 q, e

  193. ; j4 Q7 ^7 `; W: j
  194.   //把数据输出到RS232,RS485或者CAN. Q' _8 z) p9 V+ M
  195.   if(a_DtuInOutConfig[0]==1)1 C* i. m- Z* r/ y+ g# x0 e
  196.   {
    2 r' F7 r& B+ ~4 O) w4 y% T
  197.         if(b_DtuOutBufferRxCnt>0)
    : r: u/ d' ~& Q4 Y
  198.         {
    ; }* s! ]4 y' d
  199.           HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);
    ! y0 s* }# I+ F6 s+ v! a
  200.           cleanDtuOutBuffer();
    ! V% v3 |  j/ m: O; e: c% ?; ~% c
  201.         }' }1 o7 o/ A  w- a+ X
  202.   }
    8 ]* E3 U6 l% ~( w, b" R
  203.   else if(a_DtuInOutConfig[0]==2)
    3 H) f2 K7 E0 o* W7 J& O; j
  204.   {3 y* e% \, \* G# L, C/ T
  205.         if(b_DtuOutBufferRxCnt>0)
    * U4 n1 O3 H) T
  206.         {
    / p( `* W, b, Y% e3 J' Y+ t5 E" W
  207.           printf("\r\n");
    2 e; ]7 c' U2 _0 [: ^8 |
  208.           printf("\r\nData sent to RS485: ");7 _, G( M3 q2 J+ n7 v, a  E
  209.           HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);//debug
    ; Y) ?8 N! S: v- t
  210.           RS485_TX_MODE();
    & r) O1 }& F* T* y0 e% T9 C
  211.           HAL_UART_Transmit(&huart5, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);
    1 E* [5 n' M- z# Q. x2 e
  212.           HAL_Delay(1);! K- X. p+ @( _- ^$ |
  213.           RS485_RX_MODE();
    " H: M; `; L( M  [
  214.           cleanDtuOutBuffer();
      m, ^4 b( f# v7 _
  215.         }
    4 h5 r* ~: o: P4 n; @) _  u1 m
  216.   }
    2 v- w. H9 ]( m8 o
  217.   else if(a_DtuInOutConfig[0]==3)7 o. `* E2 H  k; X: d
  218.   {
    3 J% U9 d0 P) h# Y$ `# O* V
  219.         if(b_DtuOutBufferRxCnt>0)  z& ]/ {" |% M. y
  220.         {
    5 N" v; |  R) Y5 M
  221.           k = 0;
    3 N, K/ y0 l$ p! {2 A" @5 i, P
  222.           if(b_DtuOutBufferRxCnt>8)$ j! v/ \9 l+ V$ _: N
  223.           {8 Q/ x4 F' f8 L4 [
  224.                 for(i=0; i<8; i++)& N( d+ E5 D2 U7 ]' E* R3 X
  225.                 {
    8 ]! I; X9 |; G* c) E/ B8 C4 \
  226.                   Can_TxData[i] = a_DtuOutBuffer[i];" ?$ n4 _% ^4 e; s2 o7 ]
  227.                   k += Can_TxData[i];
    0 h, J4 s, S) y" M1 O
  228.                 }
    6 I: h  b5 N6 J- k3 s. e
  229.           }9 K, H. Y4 c  L4 h% I
  230.           else
    3 `) R3 z, v) ^) o$ H
  231.           {4 k# c3 Q( e/ }: ^
  232.                 for(i=0; i<b_DtuOutBufferRxCnt; i++)
    , D! d: i7 c2 A9 J
  233.                 {
    ( I% W- p. h4 I) R) J/ h
  234.                   Can_TxData[i] = a_DtuOutBuffer[i];4 v* Y3 |$ C- y& J
  235.                   k += Can_TxData[i];& l7 l! d0 J9 n
  236.                 }
    ' R7 T+ ^4 t# ?. U$ @
  237.           }+ j! N8 B9 l* n8 p  ?
  238.           if(k>0)3 D4 b2 L; P+ i  B" j$ Y
  239.           {
    8 j8 k' J5 S6 {- Z' l3 p' ]' i3 W
  240.                 if(b_DtuOutBufferRxCnt>8)
    0 C: @( }$ ^/ z/ j% K) v5 G
  241.                 {/ D2 i' _7 \# ^
  242.                   Can_TxMessage(0, Can_TxHeader.StdId, 8, Can_TxData);
    8 z1 D, @; g5 Y
  243.                 }
    0 a. j% D. v& H5 K! A& |7 `/ {
  244.                 else
    3 I6 S5 T+ t' ?) ?/ A3 V
  245.                 {
    * S7 s2 e* p* `7 R9 e) f+ ^1 [
  246.                   Can_TxMessage(0, Can_TxHeader.StdId, b_DtuOutBufferRxCnt, Can_TxData);+ ?. x, O# w0 \  D+ D
  247.                 }' I# a  f7 H- J: M% b$ m( X
  248.                 ArrayLeftShift8bits(a_DtuOutBuffer, &b_DtuOutBufferRxCnt);7 j: K* P6 i4 ^9 T' }
  249.           }
    4 O+ Q4 i6 W: U2 j( V
  250.           else
    0 o1 Z  i6 q% E9 q9 l
  251.           {+ R! @- w/ o" R* U. |
  252.                 b_DtuOutBufferRxCnt = 0;
    4 o/ i$ e7 @6 o  g9 I' t
  253.           }! i0 j2 u( D& ~6 N) `
  254.         }
    ; `( b* A: q' u9 @' T: O8 k, h
  255.   }
    - e) Y8 O; h) t6 i% T2 X
  256. }+ F7 N5 _' D# y1 i/ c& h. O9 g7 o
  257. void Task_DtuRedoConfig(void)
    " ?- q; f$ U) h1 l: D
  258. {
    2 v# |# l' [' M& G+ n% v! i
  259.   if(flag_DtuConfigUpdate==0)' \' v: W/ P/ V2 T1 V# }
  260.           return;
    ! e: W3 W8 ~* z' U
  261. 3 s+ y3 q$ N4 D0 j7 ^
  262.   HAL_Delay(10);' w0 [2 ?' K! Y2 S" w) R* p
  263.   printf("Re-initialize ETH, WIFI module, RS485...  ");6 l7 V% K, _$ X# A
  264.   //ETH:
    1 `% }+ N3 K9 F! ]5 T
  265.   if(status_TCPProc >= 2)
    4 L8 I( P9 x1 @, v' H% o3 `5 l
  266.   {7 v8 ?& C+ q- B) E9 a
  267.           tcp_echoclient_disconnect();
    9 K% N  r. |$ F1 d
  268.           status_TCPProc = 0;
    2 t5 F3 N! I/ @9 D9 p& i
  269.   }
    ( L) \6 z* X! h7 `: X5 A2 B
  270.   //ESP8266:
    " e6 \' r! l) s: M9 x7 v
  271.   if(Status_NodeMCU>=6)* X, S4 O7 x0 ^. ]7 `9 V0 i
  272.   {0 q* q: |" h4 X5 T9 A% D) v
  273.           sprintf((char *)a_8266TxBuffer, "+++");                //esp8266 接收到这个+++会停止透传模式2 I3 z' g  s& k9 N3 F
  274.           HAL_UART_Transmit(&huart3, (uint8_t *)a_8266TxBuffer, strlen((char *)a_8266TxBuffer), 100);8 j% `+ ]; ]$ a6 ]8 Y! Q
  275.           Status_NodeMCU = 0;+ t8 V$ _; ~& @* v; k
  276.           HAL_Delay(100);
    7 d% V- ?/ \) n# b
  277.   }' |; S$ o% S$ o8 E
  278.   //4852 E/ w; n4 m5 p+ o
  279.   //MX_RS485_Reconfigure();
    ( w* |( r; H" v9 p
  280.   printf("Completed.\r\n");* h( |4 z, J9 H, c
  281.   //7 V4 K1 l9 D, V6 }6 d
  282.   flag_DtuConfigUpdate = 0;# ]6 A/ |. Y8 \
  283. * E6 L+ `+ n, u4 `& G& O* U
  284.   HAL_UART_Receive_IT(&huart1, &b_232RxByte, 1);
    + Q: X3 {+ ~4 ?5 D1 n' n+ y
  285. }
    ( s6 z% r' s/ C/ o' a, w3 T
  286. /* USER CODE END 0 */$ v# m; v# n9 ^0 u: r

  287. - t& e/ I8 B7 G1 q4 M
  288. /**% V0 g4 n9 M0 m; f( \2 F% F
  289.   * @brief  The application entry point.8 i- _! |* V% K* @
  290.   * @retval int2 F- F- l. S: b2 K
  291.   */) X" P) E! v: k! n' v! H
  292. int main(void)
    0 J  v* |2 A! w4 y8 p
  293. {: R0 n/ d$ ], J' S8 u& N
  294.   /* USER CODE BEGIN 1 */
    " W9 r- ?7 S) a

  295. 2 B$ G% y& v* m; {% {8 D! k. B
  296.   /* USER CODE END 1 */5 x$ K/ z& v# k( A4 w6 X+ E
  297.   
    - M2 Y% u& Y' E- u4 ~

  298. " E2 J8 J! o  o- Z) D5 l$ ]
  299.   /* MCU Configuration--------------------------------------------------------*/. S+ ^5 @+ H% n- y# K! C! f

  300. " I$ T' u& [! ^2 n5 }% s# E  E
  301.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    9 `6 J8 E5 N) I
  302.   HAL_Init();
    ( a( N! s2 N/ Z+ U1 U' i
  303. 9 \" P" M$ E3 m2 |7 I: x
  304.   /* USER CODE BEGIN Init */
    + B+ G- m3 ]* ?$ ?$ I- r
  305. $ E2 l0 J+ q' x
  306.   /* USER CODE END Init */" u: p/ M7 l9 _2 L

  307. 8 S  k' g1 O! `0 S
  308.   /* Configure the system clock */! O2 |3 @4 [9 m- _! ]
  309.   SystemClock_Config();
    3 S+ I( g2 e3 A' A

  310. 9 f" i! ?* h4 n2 B8 G
  311.   /* USER CODE BEGIN SysInit */  g% ~" r8 q% W* F
  312. 9 |; M3 e3 A" q5 R9 @
  313.   /* USER CODE END SysInit */
    ( I. |( t8 V- y/ R
  314. 8 T* k) C! X+ y* G8 A5 A
  315.   /* Initialize all configured peripherals */* C1 S+ k7 i; A* N& l
  316.   MX_GPIO_Init();
    1 r. `( R+ a" P5 m5 T$ V( m! t  O
  317.   MX_DMA_Init();" ^! f$ u# y4 R/ C' T% |. X# b$ B8 _
  318.   MX_USART1_UART_Init();
    : w/ r4 w, F0 B* j9 ]3 y
  319.   MX_USART3_UART_Init();- b# k& M+ i2 F0 d8 W! r5 q
  320.   MX_CAN1_Init();' x) Y. a) q% ~2 M) r
  321.   MX_UART5_Init();
    3 z) E$ G# v0 V- d
  322.   MX_LWIP_Init();
    : O" A/ S5 c, l' d
  323.   /* USER CODE BEGIN 2 */  T1 t) F. K" b- C; W$ V/ [
  324. * \5 |* B& J$ Q/ g5 s$ @0 y3 B
  325.   RS232Interact_Init();
    ; M4 R1 m- `- a
  326.   printf("Hello. STM32F107_DTU project: DTU. All in one.\n");' m/ u1 l0 L0 z+ G9 Q& W
  327. 0 g% o& t3 k$ c% O, q6 f
  328.   HAL_UART_Receive_IT(&huart1, &b_232RxByte, 1);
    : v) y5 q: C, s" N! c
  329.   HAL_UART_Receive_IT(&huart5, &b_485RxByte, 1);
    + Z: E/ |4 i  R, I/ K- t
  330. # }8 B7 e% Q3 y! o/ `3 X& e3 Y

  331. ' A. W( c$ }: `2 L6 @' W) N
  332.   sprintf((char *)a_8266TxBuffer, "+++");                //esp8266 接收到这个+++会停止透传模式5 L5 y3 a3 [# i; u2 H! @
  333.   HAL_UART_Transmit(&huart3, (uint8_t *)a_8266TxBuffer, strlen((char *)a_8266TxBuffer), 100);6 V/ d% x- l7 e) ]/ ?; i: F
  334.   Status_NodeMCU = 0;( Z" V1 S2 b& K% F6 B
  335. / @; ~) U2 u3 R7 g
  336.   status_TCPProc = 0;
    " g. Z" P& p# A. e% Z% Z0 |
  337. $ m  N3 _8 i7 D" c, ?3 Q! d
  338.   RS485_RX_MODE();; K! s+ L* p( L+ W+ @
  339. ( }( F& D, L: G3 H7 ^
  340.   CAN_Config_User();, `$ r! b5 e+ ^7 S

  341. 7 \* {2 C, m( O1 l  N1 L

  342. " x  W% w& e1 L: w9 c8 ]* Y
  343.   /* USER CODE END 2 */3 R) B* F" F7 c* x; R1 Z4 y

  344. $ r" j/ _+ c$ B- V3 }) M
  345.   /* Infinite loop */
    $ B9 F5 u+ B: w
  346.   /* USER CODE BEGIN WHILE */9 Y  a, c, x, M. U# c  o) y# [" d
  347.   while (1)
    # _2 Y, M7 j% w/ O- n7 p
  348.   {
    : o) @* q/ j3 p; H/ S5 D
  349.         if(a_DtuInOutConfig[1]==2). J; {, O1 k9 M
  350.         {
    9 i# G' \: R: X
  351.           MX_LWIP_Process();
    0 c- u% R- ]# [
  352.         }0 c4 [9 F$ E; d  |9 ]+ Z- f2 `
  353.         if(flag_1ms ==1)
    5 h+ d- Y0 Z) ?( b) _1 v1 @
  354.         {
    , Q$ y/ I; ~7 R
  355.           flag_1ms = 0;( e, x; l+ o  U7 c$ k* q& m
  356.           Task_232PC_Interact();. n, T) C4 C; `/ t) B
  357. * @( N( D1 A) B. Y. u
  358.           if(flag_DtuConfigUpdate ==1), w- p) F1 j; c$ B% f' g6 U
  359.           {3 v7 T, s6 ]1 a4 o' t* \) {
  360.                 Task_DtuRedoConfig();% |! e* F3 Z* f/ w. X$ b: h
  361.           }9 _2 V5 P( b) o, D, I; g0 S- n
  362.           if(b_232STM32ParamConfigBusyCnt>6)0 u+ m' l" N7 W. t1 J, Q
  363.           {
    : L, |# y1 n, l, {7 M0 C/ l
  364.             Task_DirectTransfer();# w& Y. ?4 }( L% L9 |) Y4 a
  365.           }
    ) i) |' Y5 E( [' `' W; ]
  366.         }
    - X( L7 p2 v) ~9 W& F
  367.         if(flag_10ms==1)
    5 R$ J- U! B+ K5 D
  368.         {$ s7 d0 z0 N/ S+ [/ E" z, D6 O+ j
  369.           flag_10ms=0;' P' v1 Q) m% @. l3 Y# i' s

  370. ' N  t! t" n! d; x1 q7 h& J. w
  371.         }& q' s( V# b( f( f# |& l% j+ p4 t
  372.         if(flag_50ms==1)        {                flag_50ms=0;            }
    ! N8 a0 S* n' e2 B8 b" p
  373.         if(flag_100ms==1)
    3 O" I! y# M9 O/ b- r( k
  374.         {  \9 N4 \& A  Q! c2 k5 p
  375.           if(b_232STM32ParamConfigBusyCnt>6)
    - N; }& r) Y" a7 |( L( H1 k
  376.           {
    & q' O7 K/ k3 v" A# n9 j/ G
  377.                 if(a_DtuInOutConfig[1]==1)
    6 ~( `* R7 o% h8 `+ E; s3 R
  378.                 {6 y! l4 E5 g" H- q( h2 B
  379.                   if((flag_ProcNodeMCUActive ==1)&&(status_232PC<12))
    $ E" x+ h* w- C' R2 v1 w2 Y1 {
  380.                   {
    5 V0 o& \, y' H& [8 r
  381.                         Proc_NodeMCU();
    & o7 r. j, d; }' N
  382.                   }
    ' ^; m, w. H! b3 e. |
  383.                 }  t* r; J" G+ p" Z& T
  384.           }" {& P: K) C/ c
  385.           flag_100ms=0;
      k9 ?0 F0 D( m
  386.         }
    0 M, x, \8 W4 {% E% ]7 N% i
  387.         if(flag_200ms==1)        {                flag_200ms=0;            }
    2 A6 ^/ p% T. Y' i9 i8 a
  388.         if(flag_500ms==1)        {                flag_500ms=0;                }" u- _1 Q7 R% U$ N- l8 g- V5 ?7 z; h
  389.         if(flag_1000ms==1)7 y8 z' n. E# s6 k5 Y5 R' r
  390.         {
    5 P3 [+ D! P+ v  |9 w: u9 T8 C
  391.           flag_1000ms=0;9 V$ s5 @( T# ^
  392.           HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);- v* I0 X2 j0 o5 B" u* L- F4 n

  393. 3 w& Z& ?% A6 x' g; Z/ Z& c
  394.           if(b_232STM32ParamConfigBusyCnt>6)
    / X! X2 e3 H% u8 f# R  `% T" M& y
  395.           {
    . o2 v+ @/ G) E6 [9 L1 E
  396.                 if(a_DtuInOutConfig[1]==2)- k# D" d0 r& F# T9 S: K4 {$ B
  397.                 {
    , R$ n+ }1 Q& C6 z7 g4 w) n2 k
  398.                   if(status_TCPProc<=1)3 n' ?! Z- ~- Q' |
  399.                   {
    & i% @9 W2 z! t/ l# P
  400.                         printf("connecting to TCP Server...\r\n");
    ) N* f5 c' o5 x4 x
  401.                         tcp_echoclient_connect();
    % @% P" E. A, }6 u2 S, g/ w% W: V
  402.                   }% k& w/ g1 u3 Y& b
  403.                 }
    0 l) T  l6 Q% X9 p$ }
  404.                 Task_HeartBeatPackSent();
    / V+ M; y7 v' X4 w& g+ @" b
  405.           }
    4 l' f9 ^3 ^- n( @! `5 i' P5 h  Z
  406.           if(flag_ProcNodeMCUActive ==0)1 B* e: g8 d2 G9 D6 P8 @
  407.           {6 b- A3 O5 \" t3 e; g% ^: Y; p
  408.                 flag_ProcNodeMCUActive = 1;5 Y+ _( T( j! O9 M/ v
  409.           }4 G: E; F1 r- ^, j4 f" ]& p
  410.           if(b_232STM32ParamConfigBusyCnt<80)
    " Q8 q6 [0 t3 o+ i; P
  411.           {1 p  X/ C% O1 y- G  o9 C
  412.                 b_232STM32ParamConfigBusyCnt++;4 x2 n3 q# C+ O9 @4 x& _1 I
  413.           }
    ' Q, b& d# I& U5 a# U0 D3 V. Q4 u
  414.         }' ^$ M8 S3 F& o" B, v# }0 ^
  415.         if(flag_2000ms==1)
    3 M, R  m# L* e/ U3 i6 N( i% I
  416.         {- q' }/ S: r' g2 y0 y, X' L8 S
  417.           flag_2000ms=0;
    ! D" c* M# |. v  i3 S: |

  418. % x" d8 G& A9 `. K8 T5 G5 g! T
  419.         }
    : P+ @1 M. ]; i4 p
  420.         if(flag_5000ms==1)
    ; {. i+ @) U" O( k) o. k1 J5 N
  421.         {  E. p/ W/ X) ~1 R8 m0 I
  422.           flag_5000ms=0;
    ; P+ q7 |% @$ J
  423.         }" m' K! e) B( v2 Y' D4 W9 G
  424. * l% I2 P# I4 V  ]
  425.         if(flag_10s==1)
    . g1 y3 j8 a5 K
  426.         {' F6 F9 Q* n, E; X% j( M; ~: ?
  427.           flag_10s=0;& V5 ]( G* D$ R& z
  428.         }( x3 x5 ^0 q1 @5 R
  429.     /* USER CODE END WHILE */: F6 P" G$ F! [! A4 ]: k' y
  430. $ Z! }9 y. K* q% C8 p
  431.     /* USER CODE BEGIN 3 */0 G) D/ Z4 r5 A( n! q
  432.   }. L8 R5 \2 G  t0 Z5 s
  433.   /* USER CODE END 3 */
    . N, Q3 d% \: L6 b
  434. }
    # J  K! k1 V% }) _6 O2 q1 e/ L; Q
  435. & P: z, S, X  q
  436. /**
    9 r4 {' b% k$ N. [. d7 g
  437.   * @brief System Clock Configuration6 E4 V7 K7 |. T; W: ~% ^5 D5 v
  438.   * @retval None% U/ |4 v! q- p" }9 v8 x! w4 A
  439.   */
    ! Q  l/ ~8 h+ X- p- |4 f' I/ g3 V
  440. void SystemClock_Config(void). s4 I8 P9 `' w3 l2 t+ w% z6 V
  441. {
    9 l$ V4 z7 o2 h/ x/ L
  442.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};$ o. {0 a# R" A; R
  443.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    : g, B! N' u  Q& j

  444. 0 J/ U! L0 H( |' T" d
  445.   /** Initializes the CPU, AHB and APB busses clocks
    ' ~( Y# @* i  [
  446.   */
    ( u$ g: c' \: ?
  447.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  X, v, x: B6 q3 j
  448.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;4 F2 d+ f9 H1 d, p) Z+ g9 S  K, U
  449.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;7 U1 [( k- t4 g6 L' S+ E
  450.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    8 ?0 u+ ?" |0 y) H' t' v/ `6 \
  451.   RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
    : y3 @) R0 {4 m& j
  452.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;6 K. d4 ?( x# C( g
  453.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;9 V5 o( N: U, J* x; N' N$ M
  454.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;. q7 k& t( o% c) a2 ^. g, J+ y
  455.   RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
    % H% ]& C* L: Y- r5 d' t
  456.   RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL10;
    . y9 o  l, r* a5 h
  457.   RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV2;
    ; t6 z8 |% a1 W- U5 N
  458.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)1 I% n& l' |1 z' }+ d* v
  459.   {2 h- o% X) T) Y: r: S
  460.     Error_Handler();
    9 Z, m& Y8 B6 p& O% H' B+ W
  461.   }
    5 E+ k$ K" |0 W/ c0 h5 z% X
  462.   /** Initializes the CPU, AHB and APB busses clocks
    4 Z( n5 [: X! \) T& v6 t5 B  C/ Y
  463.   */$ X) `; k2 _( t7 u# s1 r
  464.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
    % k' |' p, D8 Y* `- W% a; ~# T
  465.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;+ U  J4 P/ w& i! b# T$ e; R
  466.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;! w0 Y$ t: V+ \1 h9 T
  467.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    : Z. a" K  [! `: F
  468.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;4 a9 [4 J2 y4 Q, m: D
  469.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;: Z( x/ z8 n" y
  470. ! D  _! L9 @% e, F
  471.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    : [* z& f, N. c0 v
  472.   {
    4 N% _) {5 Q0 k! j; ^
  473.     Error_Handler();
    7 S8 `/ @5 c- U0 A: L4 `* ]0 G6 I
  474.   }" B: k  f2 k) |! s' @/ G
  475.   /** Enables the Clock Security System
    ! Z4 d0 t- I2 H" N, w
  476.   */# H! r' \3 v! _' g+ R( [! Z" w
  477.   HAL_RCC_EnableCSS();
      l# c$ }/ q0 h% o" l
  478.   /** Configure the Systick interrupt time
    ; Y& M: ~3 F+ [3 [) E; p
  479.   */
    & [! p1 B$ I$ m8 D
  480.   __HAL_RCC_PLLI2S_ENABLE();. h$ b( Z( k, J* u2 L6 y
  481. }
      R! ^7 ]$ O( W
  482. . k2 {$ m7 X& x6 v7 ~5 V0 E$ ?; U/ I4 y
  483. /* USER CODE BEGIN 4 */
    % P+ r6 t4 w- d, m2 y" f& Y

  484. ; L: _6 h* [& T# z0 y
  485. /**2 T7 v* \. ^1 j4 W4 w$ L+ d3 |% p
  486. * @brief HAL_SYSTICK_Callback()7 ]" W( g. j" q) B( }8 G
  487. * SW timer triggered every 1ms.3 w* j) a" W% S( T9 l) E9 O
  488. */
    : r- X( Q$ q5 B$ P
  489. void HAL_SYSTICK_Callback(void)  b* h5 ^/ c. P# O: r; e
  490. {" E( b8 |/ J" Y# o( x& U, A
  491.   flag_1ms = 1;/ b1 i- p/ N0 x# @# {
  492.   /*update counters*/5 J0 n/ x, y6 [8 ], P- }
  493.   if(counter_10ms<9)  {    counter_10ms++;  }
    / @3 v5 {6 r! r# b
  494.   else  {    counter_10ms = 0;    flag_10ms = 1;  }
    5 U* i. I# N' W3 q$ E
  495.   if(counter_50ms<49)  {    counter_50ms++;  }
    0 B4 _8 a0 V* \: ]6 D- v* ?7 k( o
  496.   else  {    counter_50ms = 0;    flag_50ms = 1;  }1 _0 N0 S7 H8 h" T

  497. : f! G. n% C, j8 H
  498.   if(counter_100ms<99)  {    counter_100ms++;  }3 i. z* o1 `& q7 v) `
  499.   else  {    counter_100ms = 0;    flag_100ms = 1;
    : p5 e: a4 d) a! Z4 I9 l, l
  500.         if(counter_200ms<1)        {          counter_200ms++;        }
    9 Y) C# K7 i! m# p
  501.         else        {          counter_200ms = 0;          flag_200ms = 1;        }4 i3 X& _( [3 y% k& W: r* q& g
  502.         if(counter_500ms<4)        {          counter_500ms++;        }
    4 U% @; G/ u' X. q' r" T+ Y
  503.         else        {          counter_500ms = 0;          flag_500ms = 1;        }( c! e) ]! L% C, ^& Y  D  t; V
  504.         if(counter_1000ms<9)        {          counter_1000ms++;        }# E5 _7 F2 e$ p; p+ \
  505.         else        {          counter_1000ms = 0;          flag_1000ms = 1;        }
    ; z, h& ?2 g3 n- s5 b2 K
  506.         if(counter_2000ms<19)        {          counter_2000ms++;        }
    1 Z  t. _  w0 B* H. J: o0 F
  507.         else        {          counter_2000ms = 0;          flag_2000ms = 1;        }/ j+ C3 B9 Q# D( l  W0 _2 M
  508.         if(counter_5000ms<49)        {          counter_5000ms++;        }5 [6 g6 a" L2 T6 a7 d; B0 y% w# j, {
  509.         else        {          counter_5000ms = 0;          flag_5000ms = 1;        }
    6 j* V) Y0 ^3 C! G) M
  510.         if(counter_10s<99)        {          counter_10s++;        }! ?. s- |% H" w( d! i
  511.         else        {          counter_10s = 0;          flag_10s = 1;        }
    5 G- x" o. r9 Q  H5 P7 {( ]) t" t
  512.   }
    ) H: i0 m" M8 ]9 k3 m! K  l
  513. }$ g( A. g$ B/ Q$ p
  514. 1 [9 O) |+ h+ m0 f8 [; e4 I  n
  515. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin): G! l/ u% |( L5 Y! ^- D
  516. {: w. `8 @6 o& {" ], r: |' ]  Z" T% S
  517.   if(GPIO_Pin ==GPIO_PIN_13)2 u0 W5 l: ^1 V5 l6 {5 {- y
  518.   {9 z6 _  u0 i) X1 r2 f4 p9 M  k
  519.         b_KeyNumber++;
    5 q. M  Z& P; S- C" \7 q
  520.         if(b_KeyNumber>=2)
    ' u8 p% w2 h5 B7 c) j
  521.         {
    - q; t: a0 I3 z4 E' h
  522.                 b_KeyNumber = 0;( b! n' V6 O" b8 b5 o: X
  523.         }
    ( U" q% k  p4 ~5 g: I, C
  524.   V+ J9 B$ a& `8 S) G
  525.         sprintf((char *)a_DtuInBuffer, "a simple package\r\n");# n/ y, [+ {8 L- g6 C$ U4 J* k
  526.         b_DtuInBufferRxCnt = strlen((char *)a_DtuInBuffer);: R! D; g: P. F! @: H" ^

  527. $ N) ^5 m7 n9 I1 Y2 |
  528.   }
    . z5 {+ z5 R3 e1 o( q/ t0 u' e2 Z& Y9 B
  529. }1 Z1 m$ I8 e* G2 M$ ?

  530. 9 q8 K" b2 F7 l! z- J4 L4 |6 |+ m
  531. /* USER CODE END 4 */
    # O$ ]4 u2 S3 I; ~$ I. }) f
  532.   [6 M+ d! {2 o8 m3 P* v, _/ q
  533. /**. L7 F( F6 |0 r: L
  534.   * @brief  This function is executed in case of error occurrence.
    % {/ J/ E  G7 g0 m( K9 \
  535.   * @retval None
    / ], Y% j  ?; Y) X/ {
  536.   */4 q: w3 ?6 h0 x3 M# s
  537. void Error_Handler(void)% |- u) U% p2 w% K3 s$ x  H( g
  538. {
    1 \3 U8 l8 h% P: B( X1 T3 R! b7 ~
  539.   /* USER CODE BEGIN Error_Handler_Debug */+ p5 Q0 I; Z4 d1 D" }
  540.   /* User can add his own implementation to report the HAL error return state */
    9 n$ Z7 [8 o% B" l
  541. 8 y, `; I9 `! l
  542.   /* USER CODE END Error_Handler_Debug */
    0 O2 `. s; a- {" w! q, E9 P  K
  543. }
    $ k) y- E. B9 {% x& ^

  544. $ }5 ]0 [2 n6 A3 J. d" S; `
  545. #ifdef  USE_FULL_ASSERT+ y, Z% x  r0 @5 e, I
  546. /**: `, \9 d% L  m3 v' _0 H& S4 u) ?+ `
  547.   * @brief  Reports the name of the source file and the source line number
    : i4 @4 q9 p2 ~' p# a
  548.   *         where the assert_param error has occurred.
    " _" u3 F$ `* F
  549.   * @param  file: pointer to the source file name" o0 {! a0 y: X3 N
  550.   * @param  line: assert_param error line source number
    2 x% I8 F& T; S" ^: l/ r8 H
  551.   * @retval None
    4 R5 F1 H8 M. l2 J  ]7 R
  552.   *// J6 g+ E* H6 Y( E
  553. void assert_failed(uint8_t *file, uint32_t line)
    & j2 L" [+ s3 U; Z- E9 I$ {
  554. { 8 n! ~& C( I/ p3 I4 ^$ H
  555.   /* USER CODE BEGIN 6 */
    . e4 U0 ~1 c- i6 Q4 y7 c
  556.   /* User can add his own implementation to report the file name and line number,
    . J! D/ _' j* @' Q: v4 H3 H. `
  557.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */( Y# j; E; |2 u4 C4 G7 U9 n
  558.   /* USER CODE END 6 */7 Z5 {. c6 a) o# C; j6 k) N
  559. }4 W2 |! }! n" i* M6 O( h
  560. #endif /* USE_FULL_ASSERT */+ S- W% D$ @/ d0 a
  561. : ~- I4 R4 j9 U8 I# I8 E
  562. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码

8 ]1 H. `  Y# u4 试验结果

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

  ]5 B: a" c5 c! |. z* ~% k
# I$ w, }" V: T: ~" M5 _# E
收藏 评论0 发布时间:2021-11-27 09:29

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版