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

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

. H0 U, H# w& E6 E6 B8 m

' g' ^7 F! Q1 d7 d

3、硬石STM32F1开源的源代码3.1 stm32f107_flash.c
  1. /**
    5 B" `0 O( f& u: F1 L/ q
  2.   ******************************************************************************' Z. `: ]+ E: N" r, {4 \: W1 W/ N
  3.   * 文件名程: stm_flash.c # `0 Q4 s4 ]  s0 u
  4.   * 作    者: 硬石嵌入式开发团队
    2 m2 o6 T6 w, J+ N
  5.   * 版    本: V1.0" x' A6 A, J, f/ S  V
  6.   * 编写日期: 2015-10-04
    ; x  _- [6 }# \  J+ w9 L. y% u
  7.   * 功    能: 内部Falsh读写实现
    3 j% _) @4 o4 k2 k5 K
  8.   ******************************************************************************
    / X. t3 e$ G( E0 O* L
  9.   * 说明:
    ! o& i) ]3 g, C; P) b
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
    : `; Q0 B& A7 e) s
  11.   *
    , V0 I& N; I6 W
  12.   * 淘宝:
    " _% Y7 T3 J+ d7 K/ B
  13.   * 论坛:http://www.ing10bbs.com
    1 K9 a* [5 U. M  S  f
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
    , n7 |  Q4 I# i5 p/ ]+ N$ }% l; {
  15.   ******************************************************************************
    & m# {# B3 f% w* f  p9 s
  16.   */* n/ ^* K) J# s" K' \
  17. /* 包含头文件 ----------------------------------------------------------------*/0 Q$ Q* P* A8 x: C! R
  18. #include "stm32f107_flash.h"1 s( y$ b' F5 q, B5 z" ^: K
  19. & R4 R7 j0 P: X% v
  20. /* 私有类型定义 --------------------------------------------------------------*/
    ; N1 A6 _( C9 A5 D8 `; G: ~: Q! p
  21. /* 私有宏定义 ----------------------------------------------------------------*/3 Q5 X! ]) Q( b) l  k
  22. #if STM32_FLASH_SIZE < 256) Z  L! I  y+ C
  23.   #define STM_SECTOR_SIZE  1024 //字节
    7 k) J, b6 z# M' x$ ~3 A
  24. #else
    " L1 m* z5 F' m4 w2 u3 j) n0 b
  25.   #define STM_SECTOR_SIZE         2048$ q! l# ?( `- E: `3 Y4 x4 h+ ?: q
  26. #endif
    , |4 v$ {# F2 ^8 r2 ]7 `& _

  27. % Q- M# A; }0 u% b# R# p" H  y
  28. 1 {# I4 k! Z- `% c
  29. /* 私有变量 ------------------------------------------------------------------*/, g1 O, [2 m5 ?6 A: Y( J; U
  30. #if STM32_FLASH_WREN        //如果使能了写 # D. k+ L: ^; i+ f, M0 n+ Z
  31. static uint16_t STMFLASH_BUF [ STM_SECTOR_SIZE / 2 ];//最多是2K字节
    & |5 a% @7 r, I
  32. static FLASH_EraseInitTypeDef EraseInitStruct;
    0 {3 ^1 V- o6 ?$ q; C/ i, q- t
  33. #endif6 D2 I; x# g  A* v: R6 u% m
  34. . ^. C9 x: g/ L6 y
  35. /* 扩展变量 ------------------------------------------------------------------*/
    $ ^# e: w7 ^: q7 S5 k9 L
  36. /* 私有函数原形 --------------------------------------------------------------*/
    6 S5 t( \. n* ~* v% @! W, g8 i/ L
  37. /* 函数体 --------------------------------------------------------------------*/6 b/ u' W7 _# D- k2 w4 f
  38. /**, ^7 v8 ~! @$ `; Y2 C4 |
  39.   * 函数功能: 读取指定地址的半字(16位数据)
    ' J2 w6 t6 j7 ^
  40.   * 输入参数: faddr:读地址(此地址必须为2的倍数!!)
    3 n" M! \$ e2 r6 D. w; b4 ?
  41.   * 返 回 值: 返回值:对应数据.# E- S) I: q* P* `' S
  42.   * 说    明:无
    $ n# O% j, P  t5 z/ ~! @
  43.   */" ~9 ^, d4 e; E: Z+ {
  44. uint16_t STMFLASH_ReadHalfWord ( uint32_t faddr )" i6 E4 C  I- G
  45. {* N* X# o$ X' E* g; P
  46.         return *(__IO uint16_t*)faddr; . r+ j7 y* |/ D: Z' V
  47. }
    * E* v! [/ J! B! M2 X# P

  48. ; |, {: r4 \$ I7 ~
  49. #if STM32_FLASH_WREN        //如果使能了写   6 d2 r* ]; [  F4 z4 w4 u8 R: n
  50. /**: I0 B" z4 v2 A( r3 \: F
  51.   * 函数功能: 不检查的写入
    - ^1 W1 Z+ y4 a2 h, S
  52.   * 输入参数: WriteAddr:起始地址' N/ m& g7 a4 u+ [7 b; h
  53.   *           pBuffer:数据指针
    5 I8 C. G! N9 f/ t3 x' e6 i' D
  54.   *           NumToWrite:半字(16位)数7 H/ E  w3 z9 ~/ x9 j6 O, a0 y2 R- M
  55.   * 返 回 值: 无
    6 a! E: r8 m4 V( t
  56.   * 说    明:无
    $ f" U( z. `/ b
  57.   */
    $ C2 i$ |, V0 _7 F. M% l
  58. void STMFLASH_Write_NoCheck ( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite )   3 ^' C* Y8 W: A7 x  q2 I
  59. {                                           2 s  D: v& g4 V' C
  60.   uint16_t i;5 }" P) a0 u! |! _
  61.         & T, c4 c- N- V8 s( b
  62.   for(i=0;i<NumToWrite;i++)
    5 t% E6 `+ [$ ?! N
  63.   {9 c+ }3 n/ K& d. j
  64.         HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,WriteAddr,pBuffer[i]);
    5 Y7 P* E/ V3 l3 \) X  x0 R
  65.         WriteAddr+=2;                                    //地址增加2.
    # n( R9 {) C' M2 b& l8 |" a
  66.   }
    4 Y; J0 ]. q+ [* G6 W
  67. } + d+ C7 H7 N8 D' H% H

  68. ) F  T. T4 v- L  ~* M% M  E
  69. /**/ N: N8 {# N0 Z+ l9 G- t2 T% t5 }: A
  70.   * 函数功能: 从指定地址开始写入指定长度的数据& B* F1 Z1 t( z8 M0 A% P1 V
  71.   * 输入参数: WriteAddr:起始地址(此地址必须为2的倍数!!)/ X# @" i9 R4 g7 I, W7 n& l
  72.   *           pBuffer:数据指针( B8 X8 G8 U+ z* T3 h
  73.   *           NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
    ) f  l' r4 H/ y8 Q, B" v; R0 w9 r% T
  74.   * 返 回 值: 无0 `+ C1 M! W9 W( H$ |, i; W
  75.   * 说    明:无
    # T. i6 u, R0 O+ _! {3 a& C5 }
  76.   */$ e0 L3 {# k* u% E  }, S
  77. void STMFLASH_Write ( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite )        ; _+ s+ p  Z* V. A
  78. {4 \" o9 X2 U7 T7 i: \, r* V( ?0 I7 G
  79.   uint32_t SECTORError = 0;
    2 G: v, z" H" H- v
  80.   uint16_t secoff;           //扇区内偏移地址(16位字计算)
    # C* h- l* ?5 G7 c; J1 p
  81.   uint16_t secremain; //扇区内剩余地址(16位字计算)" ~+ x( o; ?% l3 C7 c
  82.   uint16_t i;: ^: }6 U; w" s5 P; x( S
  83.   uint32_t secpos;           //扇区地址6 `6 J- H9 T& i6 m) T
  84.   uint32_t offaddr;   //去掉0X08000000后的地址4 R1 y3 [6 ?( X3 T& K  ~
  85.         2 ]' W. I: ?, L7 _/ t6 Q
  86.   if(WriteAddr<FLASH_BASE||(WriteAddr>=(FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
    . b* R. N4 U7 l
  87.        
    2 |+ O, }- Q9 q# r) O
  88.   HAL_FLASH_Unlock();                                                //解锁
    & n' h9 i  K! R- i* L( I- W
  89.        
    8 K( \/ }8 }- T; A) N
  90.   offaddr=WriteAddr-FLASH_BASE;                //实际偏移地址.
    . s) _, y( p% @3 O) d6 R" x
  91.   secpos=offaddr/STM_SECTOR_SIZE;                        //扇区地址  0~127 for STM32F103RBT6
    6 t, k9 J" P# D  ^
  92.   secoff=(offaddr%STM_SECTOR_SIZE)/2;                //在扇区内的偏移(2个字节为基本单位.), C5 m" b7 M6 F6 I9 j
  93.   secremain=STM_SECTOR_SIZE/2-secoff;                //扇区剩余空间大小; V- o. _: V! e
  94.   if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围6 @* _4 A% w; r, K6 i
  95.        
    9 C# }8 Y& N* `6 V- N7 f8 `
  96.   while(1)
    * A- z, W# j4 S: b! m; S; u- X/ A
  97.   {7 H1 o' n! W! x5 _5 B
  98.         STMFLASH_Read(secpos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容' w2 U1 s. `* m. l0 P
  99.         for(i=0;i<secremain;i++)//校验数据
    ; M/ A7 F& q0 z+ C
  100.         {/ o; N. N7 l/ H. h
  101.           if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除# U" L. ?5 M" b3 K* p7 w7 b: T
  102.         }
    : ?6 A( `2 }& W7 |# S4 N. N
  103.         if(i<secremain)//需要擦除
    - {) l  d/ p# E1 o1 B7 a
  104.         {
    ( W+ S0 x: ]2 s
  105.           //擦除这个扇区
    1 U* y' d( S$ T$ @2 H
  106.           /* Fill EraseInit structure*/% c+ Q& ~9 {* n6 j3 Y: N
  107.       EraseInitStruct.TypeErase     = FLASH_TYPEERASE_PAGES;
    7 t3 |4 c3 v' H- g5 s0 U+ {
  108.       EraseInitStruct.PageAddress   = secpos*STM_SECTOR_SIZE+FLASH_BASE;
    " {9 D7 b* S" G2 r  `
  109.       EraseInitStruct.NbPages       = 1;0 X1 R  {* @+ _7 ^5 r" E9 K5 H" F
  110.       HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);9 D# i: J, u0 R& X7 g
  111. % R0 D% w# |1 F. N) n
  112.       for(i=0;i<secremain;i++)//复制' z' `! Y2 n8 c- K2 o! [, ^& x
  113.       {5 X! |. W0 E1 v  T
  114.             STMFLASH_BUF[i+secoff]=pBuffer[i];5 \3 _; [9 x; u/ G* A
  115.       }
    3 v& ]: O5 J# X  o% y
  116.       STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区& K# d2 G. c1 q  _! C) I
  117.         }
    + x! P/ E1 z7 |* d5 J; e5 x' f$ C
  118.     else
    $ Q& @! T7 G, T. }+ R+ y. E$ o. H
  119.     {
      d  r0 p* Q2 |: K
  120.       STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.                                   
    : I1 i! V* F8 v/ g/ r+ `( ?
  121.     }
      M/ P$ p4 g5 Y1 S5 s5 U" L
  122.     if(NumToWrite==secremain)break;//写入结束了
    # H& k" d$ c; @
  123.     else//写入未结束
    ; f7 }- o9 a4 g! S$ x! q, q7 G
  124.     {, g6 K- \7 k% l2 s, p
  125.       secpos++;                                //扇区地址增1# }( ]3 T( q' {" Y0 W* O, y
  126.       secoff=0;                                //偏移位置为0
    % i0 ?8 |4 n! _2 {6 L; {
  127.       pBuffer+=secremain;          //指针偏移
    . a! o, `1 Q$ g+ v
  128.       WriteAddr+=secremain;        //写地址偏移4 Q% s; C2 G$ k5 Y
  129.       NumToWrite-=secremain;        //字节(16位)数递减
    & w9 j0 \+ Q' P6 o1 w! V9 ^2 L, B
  130.       if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
    . ~( R% V" z$ t
  131.       else secremain=NumToWrite;//下一个扇区可以写完了8 \4 B/ L- I6 c. u( ]6 A
  132.     }
    , v: y% U7 B" h0 z5 @
  133.   };1 ~$ R: c- N* c
  134.   HAL_FLASH_Lock();//上锁% W# h/ j! r0 h- u: S' P& D3 s
  135. }5 B- m. ^; J. }; h- s

  136. 7 a, D$ J4 Z0 ?. L5 O
  137. 1 J+ P/ G1 H) N, Y- [

  138. , U, r1 z; t8 i3 Q
  139. #endif
    . M, Y+ ]! Q4 b( x3 a- v  Z  o

  140. 9 ]/ P* \$ Y# D! D
  141. /**
    4 c4 X: ?+ A0 H: D  \
  142.   * 函数功能: 从指定地址开始读出指定长度的数据$ h& c4 q' u% }4 `
  143.   * 输入参数: ReadAddr:起始地址' O1 N& Q  n( l" J. K3 c
  144.   *           pBuffer:数据指针
    : a! u8 J/ E: \4 u# q
  145.   *           NumToRead:半字(16位)数, Y3 y% Y6 M! v1 Z% V8 v
  146.   * 返 回 值: 无9 D3 }: U2 I) _
  147.   * 说    明:无
      J* ~' T! }1 |3 s! j! \
  148.   */) j& E* ^0 i4 m) t7 X
  149. void STMFLASH_Read ( uint32_t ReadAddr, uint16_t *pBuffer, uint16_t NumToRead )          
    - |( z8 G8 P% U1 u. N; \, m
  150. {
    0 J$ @0 ^$ i5 D' h( M$ n$ M
  151.   uint16_t i;
    8 M* S' z2 d9 \) S6 w' r) r" K

  152. * F$ B& N  @( ]0 o" W! v
  153.   for(i=0;i<NumToRead;i++)
    + _3 x: {; N# u! Z. b; p
  154.   {: d2 T9 y4 L+ J4 v9 j9 K. H, }
  155.         pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
    # g2 E# ?" Y0 x, h( K5 ~
  156.         ReadAddr+=2;//偏移2个字节.
    + x; E4 C3 N9 Q0 x; D2 G; ~2 _
  157.   }* q1 ^# v6 H  o- Q# ?  K5 l
  158. }' E" T8 k, D2 W# B4 ]8 I
  159. 8 V5 Y* y% |9 X; e& {4 s6 x
  160. /*
    # e5 K( H, I$ m7 t2 U/ F
  161. * 函数名:Buffercmp
      ^) Z) ^, U# t% a; p
  162. * 描述  :比较两个缓冲区中的数据是否相等
    & D. Q% N1 W7 s6 }% z3 V
  163. * 输入  :-pBuffer1     src缓冲区指针
    ; v7 w6 D4 f/ \6 D. W) B
  164. *         -pBuffer2     dst缓冲区指针
    / P1 @' k" [2 K: O& R
  165. *         -BufferLength 缓冲区长度
    1 s+ f1 K6 a& ~: v2 \
  166. * 输出  :无
    $ p; b! ]% T& ~$ r9 Z9 y3 k
  167. * 返回  :-PASSED pBuffer1 等于   pBuffer2" g- P; b  N+ d! ~
  168. *         -FAILED pBuffer1 不同于 pBuffer2
    . o& f9 ~& W) g- c, m( [$ q6 X- r  @
  169. */
    + ]9 J3 b% Q7 o0 e$ U
  170. TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength)
    0 X  f$ q# U, E; C. W
  171. {
    , o& s9 q4 }& c
  172.   while(BufferLength--)
    * H2 c5 q: T2 _- E6 ~. t( K
  173.   {
    ! U, J9 Z" I- O9 j( [; ?
  174.     printf("data:%d - %d \n",*pBuffer1 , *pBuffer2);. F+ D9 x: z2 w$ {5 i8 Y) a' V3 V
  175.     if(*pBuffer1 != *pBuffer2)! l; e) I! c$ S+ M9 `1 ~, L
  176.     {- k7 J6 {! G  u4 d7 i, [1 S8 v: l
  177.       return FAILED;$ r( u; m7 u/ g0 d& B
  178.     }0 x) ^% D& T+ q7 g3 S
  179. " O1 l; Q! Z/ W) Z% g
  180.     pBuffer1++;
    + H. G5 A( y6 L1 k/ Y2 ^2 P
  181.     pBuffer2++;9 T8 L8 y8 u( a6 o
  182.   }
    . u  |5 a4 `4 p7 i
  183.   return PASSED;
    : m# a+ O$ e# w+ R- e
  184. }
    9 \2 ]& Z& m' i9 z" Z6 x$ ]
  185. : |+ C. V; ^* O% h
  186. ' D7 F$ q5 J: e
  187. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码
& m& z! x- j) U/ n$ L, j6 c. a5 n% P
3.2 stm32f107_flash.h
( Q) N' l: \5 m' A
  1. #ifndef __STMFLASH_H__' F- f. @/ C2 I/ U6 v3 H/ x
  2. #define __STMFLASH_H__, A( u; x% \# A. [6 O

  3. 6 Y& `! t! D) y# f: g( Y
  4. /* 包含头文件 ----------------------------------------------------------------*/- g6 C: b2 q, l* U/ Z" x$ X
  5. #include "stm32f1xx_hal.h"
    ' F. b2 Q) ^4 S$ Q8 {
  6. $ }9 _; O0 Q( m
  7. /* 类型定义 ------------------------------------------------------------------*/
    ; F* ~# |# f; y$ r/ p2 p
  8. /* 宏定义 --------------------------------------------------------------------*/
    6 F! ]' P6 [0 D* s' {2 |
  9. /************************** STM32 内部 FLASH 配置 *****************************/
    ) C9 m* b/ r$ D& r" u4 X- y
  10. #define STM32_FLASH_SIZE        256  // 所选STM32的FLASH容量大小(单位为K). x1 l7 k5 l) s
  11. #define STM32_FLASH_WREN        1    // stm32芯片内容FLASH 写入使能(0,禁用;1,使能). v1 y! X5 X" E

  12.   d- E8 C7 W" |
  13. typedef enum
    / s5 ]& S/ R* |
  14. {
    2 _, \; j: M. q% z# x, {
  15.   FAILED = 0,3 ]7 ^6 Q7 l$ M" k
  16.   PASSED = !FAILED! i  [( c2 y, N- k) Q& N
  17. }TestStatus;
    5 x# H; }( y" w$ i+ q

  18. - u, Q4 x* ^1 ~' u0 |! B9 Q
  19. #define  FLASH_WriteAddress     0x0803F800            // 写在靠后位置,防止破坏程序
    0 Z. c1 X" `. k% q. i9 a9 h
  20. #define  FLASH_ReadAddress      FLASH_WriteAddress+ o( A2 c# T, P3 D- Z. @
  21. #define  FLASH_TESTSIZE         512                 //实际是512*2=1024字节% P# ^" S) |% r+ J

  22. 1 c* g( H4 w+ C3 a* m$ Z

  23. 6 R/ ^5 r8 l! U% Q% W4 ^( C. D$ G
  24. /* 扩展变量 ------------------------------------------------------------------*/( q& j( K6 x. y9 f; u- [
  25. /* 函数声明 ------------------------------------------------------------------*/  ~/ \7 Y' _) U4 M! b$ t8 m
  26. uint16_t STMFLASH_ReadHalfWord(uint32_t faddr);                  //读出半字% m  U) E* E6 r- p5 E# j* d

  27. 1 k3 @: R( J7 Y: r, C5 |
  28. void STMFLASH_WriteLenByte(uint32_t WriteAddr, uint32_t DataToWrite, uint16_t Len );              //指定地址开始写入指定长度的数据
    2 I$ [: _9 J  S6 x
  29. uint32_t STMFLASH_ReadLenByte(uint32_t ReadAddr, uint16_t Len );                                                                    //指定地址开始读取指定长度数据7 w! z1 P; I. F/ W* L! M# I
  30. void STMFLASH_Write( uint32_t WriteAddr, uint16_t * pBuffer, uint16_t NumToWrite );                //从指定地址开始写入指定长度的数据. }* N2 _- o, v2 h9 B- Y1 D* O  o
  31. void STMFLASH_Read( uint32_t ReadAddr, uint16_t * pBuffer, uint16_t NumToRead );           //从指定地址开始读出指定长度的数据5 k2 T7 ]: f* k( t, c$ C
  32. //static TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength);
    ! a0 r3 A( q0 l
  33. TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength);; t% q+ ^0 D+ s! z; e
  34. 9 A, [* @7 w. i% {
  35. #endif /* __STMFLASH_H__ */: N' O+ g9 \9 s# D! P& I  n/ Q
  36. % Q: @) A4 i& P( Z# `
  37. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码
$ }2 K, k. v6 C0 h4 b2 L5 H1 k
3.3 main.c
! k/ }+ _" R9 I" ]. q  v
  1. /* USER CODE BEGIN Header */
    # }3 k$ m0 ?$ J: w
  2. /**
    9 `$ t5 T' f% f  @* L- j% ~
  3.   ******************************************************************************3 d/ ?. J1 M2 h' m$ Z
  4.   * @file           : main.c6 e* q) M) T# L2 L# q
  5.   * @brief          : Main program body
    . @8 L& |  D, D0 r$ x
  6.   ******************************************************************************6 H7 P8 j* z$ d; c7 T
  7.   * @attention( p/ U- l, U' f; Y, K, |4 L/ L
  8.   *8 o9 e( Z) M- L* z; O
  9.   * <h2><center>© Copyright (c) 2019 STMicroelectronics.# }" U. y, T& r) s0 H; `7 X
  10.   * All rights reserved.</center></h2>
    3 x4 F( A1 Q1 s7 b
  11.   *
    + I, G+ p& B  ]) ]) Z  O9 e% K1 C
  12.   * This software component is licensed by ST under BSD 3-Clause license,- S0 i$ T0 _) ?8 C6 r7 [! A" p
  13.   * the "License"; You may not use this file except in compliance with the
    5 x% _; r" u: k( l9 B
  14.   * License. You may obtain a copy of the License at:
    ( N) a2 `$ q% W+ z0 I2 Y
  15.   *                        opensource.org/licenses/BSD-3-Clause
    - A* [7 h6 @- l% Z0 t. P1 V
  16.   *
    6 Z. @* m' h. F8 B
  17.   ******************************************************************************
    + F: r" r% z6 h0 c6 T
  18.   */
    ! o5 R( {- k  `: q( B; {
  19. /* USER CODE END Header */
    " Q# F2 f! g% A6 K$ x" x8 G2 t
  20. ' k7 Q0 B7 h3 k3 `$ G& G5 i
  21. /* Includes ------------------------------------------------------------------*/# Y6 A: k/ l5 v
  22. #include "main.h"2 O7 Q/ @* L3 h/ l! _4 G/ z0 w7 ]
  23. #include "can.h"
    4 P. w/ W: e% d" H$ M/ V; A+ H$ t) Z
  24. #include "dma.h"
    . ]2 i) I! t7 F; @+ k
  25. #include "lwip.h". |( W3 }! g2 O- z. |0 }
  26. #include "usart.h"' U. b# a. l" `
  27. #include "gpio.h"  \/ e5 K/ P- p6 q0 Z
  28. 7 ?* b) I* d$ _& j  u  \( ^
  29. /* Private includes ----------------------------------------------------------*/
    : ^, y4 I; X" S  n, X
  30. /* USER CODE BEGIN Includes */( K! E: w* k6 S0 l" N: }9 K2 k3 b' a
  31. #include "string.h"
    & u* \: d& s- X3 H2 V" f8 _( C1 S
  32. #include "tcp_echoclient.h"0 R9 k. L4 |" J  l( q. o

  33. 8 j3 V. N. [) s( e) B1 A) N' L% j
  34. /* USER CODE END Includes */
    0 _. T" v5 ~. M5 i" p- D

  35. % n5 w9 v5 I! E5 i+ Q' p) H
  36. /* Private typedef -----------------------------------------------------------*/4 L. ~6 ]( B" N/ I' x3 m
  37. /* USER CODE BEGIN PTD */) `+ O7 z8 V$ v# ]
  38. 5 J0 u3 M8 B3 \
  39. /* USER CODE END PTD */
    2 b/ |; W  y2 G. V8 ?

  40. * d) ~/ U) m& a! p2 a4 A  d9 ?1 g
  41. /* Private define ------------------------------------------------------------*/
    ' K9 P1 j$ f1 M
  42. /* USER CODE BEGIN PD */. s8 f( e' R$ A; D0 {
  43. #define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))- Y2 b* \/ R( W: d  F2 a( f

  44. 6 F- ?" Y1 ^# u) g$ P, r, j
  45. /* USER CODE END PD */
    ' S& D% Z1 {8 _' j* [' L
  46. $ s+ X' Y" D$ I
  47. /* Private macro -------------------------------------------------------------*// A, ~- T% l( {0 x) p& G0 _
  48. /* USER CODE BEGIN PM */1 V7 A' s/ c! T8 s

  49. ' p; }: G# o8 y: {8 o4 Q: z
  50. /* USER CODE END PM */' W6 T7 O: c2 R. o. B; O+ z' s- R
  51. % w; A8 j2 Y9 v& e- V9 B& |3 C
  52. /* Private variables ---------------------------------------------------------*/
    ! a0 ]- u  r" z

  53. 6 U2 H' S! ~5 y! E" p6 A
  54. /* USER CODE BEGIN PV */
    - L- F  `4 f& I* ?& F
  55. uint32_t  counter_10ms, counter_50ms, counter_100ms, counter_200ms, counter_500ms, counter_1000ms, counter_2000ms, counter_5000ms, counter_10s;
    5 I1 q% H/ o4 d1 t2 r' r% i
  56. uint8_t flag_1ms, flag_10ms, flag_50ms, flag_100ms, flag_200ms, flag_500ms, flag_1000ms, flag_2000ms, flag_5000ms, flag_10s;
    / w% k2 S' T% C3 H* Z) U) g0 y
  57. uint8_t b_KeyNumber;
    ; O' ]; ~& U. y8 _7 v
  58. " H0 d/ @9 r6 m9 J
  59. uint8_t a_DtuInBuffer[100];' U$ u) B3 N; ]5 T) O( y
  60. uint16_t b_DtuInBufferRxCnt;
    6 ]  I  `/ w1 j* a# ?+ u
  61. - U& A& v9 V. S3 J
  62. uint8_t a_DtuOutBuffer[100];, ~7 }6 j+ W# O& n# Z5 c( C
  63. uint16_t b_DtuOutBufferRxCnt;
      r; F! m! E. |" `

  64. ; O) b4 c5 u" U3 O% [
  65. struct netif gnetif;6 Q; x5 Q4 u. O# j. i4 \  W
  66. extern struct tcp_pcb *echoclient_pcb;5 q1 y. @+ o0 K; |' d  z' U, }( P
  67. uint32_t status_TCPProc;! v' C6 Q6 u$ ^- v- R

  68. ) ?4 `& o! o7 x5 {
  69. " {$ V" J# [1 s4 c) ]8 R& x, y
  70. uint8_t a_SocketConfig[7];
    6 `7 a: k2 M" N8 T4 d2 o
  71. uint8_t a_SocketHeartBeat[60];$ {, z6 w, x$ L" s% e6 _
  72. uint8_t a_SocketHeartBeatInterval[2];
      h% L- q2 I9 V( q
  73. uint8_t a_SocketRegister[60];
    " f- L5 z' h9 R# t) H, b+ L
  74. / E& K* ^  _  H; R5 @7 _$ Z
  75. uint8_t a_DtuInOutConfig[2];2 q$ |+ Z" z* i% b9 F1 A5 F

  76. - a# W$ x0 _4 }! F
  77. uint8_t b_WifiMode;$ T- ?& o. N6 q
  78. uint8_t a_RouterSsid[20];; [% }) t" c( D3 P5 }; U
  79. uint8_t a_RouterPswd[20];8 I) T( @$ o( H/ K0 `# o7 t: @1 _0 S

  80. 8 w% b* L' ?1 p* W& I7 h8 @7 M' k
  81. uint8_t a_Rs485Config[5];2 j" s% W' F8 X  B) U2 B
  82. uint8_t a_CanConfig[5];# R$ o+ t0 d3 U; z9 K
  83.   |" |$ M& H5 H" {" N# U  w
  84. uint8_t flag_DtuConfigUpdate;
    ' o& s$ n/ W- Z) ]
  85. uint8_t flag_DtuEthReady = 0;' `; h' m- K. `  V
  86. ) V. f, `) g8 m6 U
  87. uint32_t b_HeartBeatPackageCnt = 0;9 u8 G( {9 P$ S; D+ M

  88. " P' e; c5 l  ~8 \( d% J
  89. uint32_t b_232STM32ParamConfigBusyCnt = 0;        //尝试通过串口和STM32交互时候,会让出相应时间,优先处理8 g+ U( j1 n3 Q  U' T. ]4 @
  90. 9 y! Q+ n  w# t1 \
  91. /* USER CODE END PV */
    - F3 N% N, g* B( W  u$ S( }

  92. & ?9 L/ ~  |# n" O
  93. /* Private function prototypes -----------------------------------------------*/
    ! V2 o' |: M4 T9 F7 h6 Z
  94. void SystemClock_Config(void);- A  f0 u! q& p& i* `0 I/ i
  95. /* USER CODE BEGIN PFP */& w7 n' o; V2 Q4 a2 r4 h
  96. 7 i9 k; G+ _- I' m
  97. /* USER CODE END PFP */4 J4 q, ^* L( S* u5 G
  98. 8 ?3 ~6 _: E% ]! T9 ]( L6 |
  99. /* Private user code ---------------------------------------------------------*/9 u* }) F8 ^3 Q; Y  s) _: n
  100. /* USER CODE BEGIN 0 */
    6 ~# L1 {4 t9 |) [3 y* ^6 n- ^: t5 _4 b
  101. void Task_HeartBeatPackSent(void)
    / o6 L6 _3 ^3 B$ }
  102. {
    . X) T9 t' `5 @( d
  103.   uint16_t b_interval;
    + t+ E# x2 u# g% b- q- r

  104.   F, l" J! k. E* u
  105.   b_interval = (a_SocketHeartBeatInterval[0]<<8) + a_SocketHeartBeatInterval[1];
    # P: L7 b' ~* L" ^7 P/ o# J. P
  106. 6 V5 A5 j: _$ s4 E
  107.   b_HeartBeatPackageCnt++;
    - J3 g# t$ W( e
  108.   if(b_HeartBeatPackageCnt>=b_interval)
    1 ^6 r0 P/ c, X5 ?) z
  109.   {/ b) r, h5 v) j% I6 F* x
  110.     b_HeartBeatPackageCnt = 0;7 _& O6 o/ B9 ?: b3 Q

  111.   r6 D8 O% r3 a6 p
  112. 3 R( ?$ ^" P9 l
  113.     if(a_DtuInOutConfig[1]==1)
    - Y5 j- i" I, r9 V# T  D+ o! A
  114.     {
    ( Z! Q8 P- Z4 ?6 }9 b/ y1 \" h3 s
  115.       if(flag_8266DTUReady==1)" d$ x: A# w! D' u
  116.       {
    & l% v/ _  P) \/ A+ H7 g. V  b; X1 x* e
  117.             HAL_UART_Transmit(&huart3, a_SocketHeartBeat, strlen((char*)a_SocketHeartBeat), 100);0 \6 c) G; |9 w
  118.             printf("\r\n");
    ' N2 k) `$ n6 s" M
  119.             printf("\r\nA heart beat package is sent.\r\n ");
    ; ?, h) [1 h( T% H" @" K; l* ~2 w4 i
  120.       }
    3 e1 n2 l5 M) q% k8 k* d
  121.     }# e: L8 ^3 J" p8 l& N
  122.     else if(a_DtuInOutConfig[1]==2): v. \" _+ ]5 D& E* B9 ~( ?$ L& D2 G
  123.     {9 X6 D% |& s) O6 M! I9 X. M
  124.       if(status_TCPProc>=2)5 C: j8 h& t" x. q, W9 Y. X8 E6 ^) E
  125.       {
    & R: i- {! d3 F4 Q/ }. C7 |
  126.             tcp_senddata(1);9 N) h' e1 ]3 [$ Z
  127.             printf("\r\n");& g" p! j' g5 M' h: I, h, u9 V
  128.             printf("\r\nA heart beat package is sent.\r\n ");1 v  s& q2 E. e: o
  129.       }
      I, K: g" r( b# R: s: b6 G: r
  130.     }/ x: Z/ C6 J0 Y
  131.   }, j: A  H. ^% }1 ^4 o
  132. }, |1 n' T; t7 L; S( I; d
  133. void cleanDtuInBuffer(void)
    * @- k  S; |- @% K. l2 o
  134. {
    0 V) p: s7 u$ E5 W* g  M' p+ R
  135.   uint32_t i;
    1 d. z) }! }& b
  136.   for(i=0;i<b_DtuInBufferRxCnt;i++)
    4 I" T& B9 P7 M8 Z* y* W1 d
  137.   {
    4 P2 K$ t, `6 ^$ U- W+ ~
  138.         a_DtuInBuffer[i] = 0;6 F, e7 A3 b& C# _  i
  139.   }+ |% \7 m: x/ h, \) h2 x
  140.   b_DtuInBufferRxCnt = 0;
    3 g- n* G; p6 Q- y& _/ y5 Y( N# c/ @
  141. }, l" ]# r. C2 m
  142. void cleanDtuOutBuffer(void)% i( r1 W* d' w8 @! y
  143. {
    5 H* @' X( X5 v: T' \0 b- |
  144.   uint32_t i;9 Z0 m2 m- D& m- f6 C' Y! [
  145.   for(i=0;i<b_DtuOutBufferRxCnt;i++)
    0 J5 Q% b" K2 y- R2 V: L3 N
  146.   {
    9 F, h5 o9 q  i; s  A
  147.         a_DtuOutBuffer[i] = 0;$ A  g/ N4 J, s6 }0 @2 k  n3 H
  148.   }
    ) B9 s: q7 H9 q: u$ {9 W
  149.   b_DtuOutBufferRxCnt = 0;" S4 o8 M9 W9 d, W; j9 [
  150. }
    # A' p5 e) L# G& {

  151. : b; x3 X* H% [8 R
  152. void Task_DirectTransfer(void)
    * g9 _" x; U# L9 h; J4 S, @; n
  153. {
    " j0 @7 K# m- ]7 n- G6 X5 @
  154.   uint32_t i, k;- D" @8 {; b$ b* Q+ S, x4 v  t
  155.   //把数据输出到以太网或者WIFI
    ! D. `# \3 h3 L
  156.   if(a_DtuInOutConfig[1]==1)+ C/ u& p: a1 g9 q
  157.   {+ x  D# A" W+ v7 t2 y. f9 Y: Y  W
  158.         if(flag_8266DTUReady==1)' |- U4 G: {0 E. ~  J$ s: r; R
  159.         {
    # H* O+ [! R) O, i& W8 ]" f. _
  160.           if(b_DtuInBufferRxCnt>0)7 K( Q4 G9 Q6 o+ U- x
  161.           {
    # {8 C( Q2 ~% y. ~& V  x- S
  162.                 printf("\r\n");- o; m) U$ \& G# A% o
  163.                 printf("\r\nData sent to Wifi: ");
    5 o" t! I3 H; u
  164.                 HAL_UART_Transmit(&huart3, (uint8_t*)a_DtuInBuffer, b_DtuInBufferRxCnt, 100);
    ; w; q7 p/ g7 C; V2 U7 L4 l* r$ `
  165.                 HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuInBuffer, b_DtuInBufferRxCnt, 100);        //debug4 w6 ]' S$ [6 R- I
  166.             cleanDtuInBuffer();
    $ A6 e7 ?; x! h; G, O
  167.           }( g2 A6 ~: U0 C
  168.         }5 q) g4 X4 V7 G. i* k% {6 f
  169.   }
    9 a" n" y. o; p' i$ K+ N
  170.   else if(a_DtuInOutConfig[1]==2)! [, Q% i; G& ?
  171.   {
    ! x7 ~8 f: e3 r2 b' `
  172.         if(status_TCPProc>=2)+ T& S4 I. a; R. k, O; U$ l% `6 p) c
  173.         {
    ' X$ `. g+ {5 g1 j' f8 e! y
  174.           if(status_TCPProc == 2)
    3 ]& s6 S9 |! S. W* ~4 Z5 a3 K
  175.           {( @" ]  K$ @& A/ }: }
  176.             tcp_senddata(0);        //专门发送注册包" U8 F- H6 k7 {- c% H" N, h
  177.           }
    ' s$ C* }4 w1 o! _3 b
  178.           if(b_DtuInBufferRxCnt>0)
    1 x# }5 V" ^; l0 m1 C1 b0 a& b
  179.           {+ P( n" a* Z) U. D- ^
  180.                 if(status_TCPProc <= 3)
    6 }) R: E8 A% Y+ g# u. W
  181.                 {) T3 X- ~, F5 |$ Y: g
  182.                   tcp_senddata(0);
    & }9 [% E. @8 n9 X
  183.                 }
    * [/ g8 o. l. R. p2 M1 j+ Z5 g
  184.                 else$ ]2 a3 m2 l5 H( g
  185.                 {; u# y1 B- f# ~" d6 i/ b8 G5 L
  186.                   status_TCPProc = 0;
    & I7 E, h; |7 A: q0 U. W
  187.                 }: p6 D% {; {# c2 q2 e" s' _
  188.                 cleanDtuInBuffer();) e% y- n( C  u& j. `% {0 Q; p
  189.           }
    , a2 ?0 ?, T8 E' m  z
  190.         }" z- m/ P) w7 M7 P9 C8 [/ _$ i) Z6 T
  191.   }3 l- M2 g4 [; G* m/ W; a; b- P

  192. ' P) M. F! M$ e0 R8 C9 s5 O& p

  193. 4 v7 l( n% _! r  c6 I3 R
  194.   //把数据输出到RS232,RS485或者CAN
    # p4 `# d, ~3 z8 i
  195.   if(a_DtuInOutConfig[0]==1)
    9 w, Q# e1 Z' v8 A- O+ [% D( U
  196.   {
    8 i9 q! Y: k: l6 e3 U
  197.         if(b_DtuOutBufferRxCnt>0)
    3 g. a- N2 r  e. I9 ?5 Q# {' p* r0 K
  198.         {
    ' E6 L5 L+ l  ^6 m, ]
  199.           HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);+ S% o- \, N7 P( H2 b/ O
  200.           cleanDtuOutBuffer();
    " L+ H/ l2 V2 U+ v% m  |8 H, B6 x
  201.         }
    7 n  [: @; V* c: g
  202.   }4 a5 T; H$ D6 Z$ k' a" d
  203.   else if(a_DtuInOutConfig[0]==2)
    - h. ~# N; m* J' U
  204.   {
    / i+ M# [2 X, |% ^
  205.         if(b_DtuOutBufferRxCnt>0)
    - z- N" J( G& O# p/ ^8 `- w$ B: q
  206.         {4 _: k) }: M& |! X) f: Q7 Y0 I* C: T
  207.           printf("\r\n");
    ; l1 `- A5 j" t( w8 a* z0 q- ]* J$ C
  208.           printf("\r\nData sent to RS485: ");
    * `2 b" T, ~& Z) I! G; R
  209.           HAL_UART_Transmit(&huart1, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);//debug# ~; y: }8 I0 ^. U( R3 C
  210.           RS485_TX_MODE();$ `3 }* G6 f$ S- ^
  211.           HAL_UART_Transmit(&huart5, (uint8_t*)a_DtuOutBuffer, b_DtuOutBufferRxCnt, 100);
    ( [! c% o: C' ?3 o  z4 X
  212.           HAL_Delay(1);* M0 C3 H. w- A/ X
  213.           RS485_RX_MODE();5 P4 A+ a8 H1 x# Y& O4 G
  214.           cleanDtuOutBuffer();. Q" G4 ?6 J1 w9 c# D1 n
  215.         }
    9 Q8 x# |5 i! V3 H& G) ^! U
  216.   }/ d, U8 N+ O% j0 T" m& [
  217.   else if(a_DtuInOutConfig[0]==3)
    7 G  g1 t( `, x2 q8 V' \0 Y3 n
  218.   {& s7 n* z# D6 V" B5 }: k4 D! o& ?
  219.         if(b_DtuOutBufferRxCnt>0)! g( ^( _: A0 j/ |1 I  p
  220.         {
    # K7 M. {# D2 O7 ^; A0 z1 v9 P
  221.           k = 0;
    & s, Q, }3 _, _5 {- x
  222.           if(b_DtuOutBufferRxCnt>8)
    2 L  y. D5 _- a" Y
  223.           {
    & P+ ?! K9 K6 E3 F- \
  224.                 for(i=0; i<8; i++)
    " u* h# v7 V8 g% F
  225.                 {7 c& S" D" F" Q1 V: A' ]* P
  226.                   Can_TxData[i] = a_DtuOutBuffer[i];
    ( O7 _0 D' X, f" G- x1 Y; j
  227.                   k += Can_TxData[i];
    % I' I- u1 `1 E
  228.                 }3 m) v) l' S0 w3 U% h# V* T# s, r/ o
  229.           }
    7 G, P* ?6 y8 v9 g9 g
  230.           else, t0 E- b! ^" ]% b
  231.           {
    ; O+ V: m" o: q# x; r7 m
  232.                 for(i=0; i<b_DtuOutBufferRxCnt; i++)
    - ?8 d, A9 Q! [3 J6 M
  233.                 {
    . u+ T( l: G' T& p- F; `" }
  234.                   Can_TxData[i] = a_DtuOutBuffer[i];
    - k. ~0 T. W6 R8 c, v
  235.                   k += Can_TxData[i];) Y7 G9 b5 R+ C: }2 @7 t
  236.                 }
    & R0 S8 O5 ^" C# z: D2 h5 L+ N2 M
  237.           }+ y* x8 S. s: N
  238.           if(k>0)! R) `7 a2 t7 f8 i7 W! f! D8 c3 v
  239.           {
    ' L7 a' y2 E  A7 k3 e: o0 M9 e
  240.                 if(b_DtuOutBufferRxCnt>8)
    2 z% w1 g6 F* l. S) P/ N4 Y
  241.                 {
    8 Y- L) Q/ \1 V5 O
  242.                   Can_TxMessage(0, Can_TxHeader.StdId, 8, Can_TxData);
    ( r: Y/ d" o% f
  243.                 }0 Q" Q# y) J1 n
  244.                 else
    0 _5 N, X/ J5 o4 A+ l6 j8 _
  245.                 {* ]# S7 }! @9 `- `" v- u; P1 k& H
  246.                   Can_TxMessage(0, Can_TxHeader.StdId, b_DtuOutBufferRxCnt, Can_TxData);; _: R+ }9 y8 ?  I
  247.                 }
    # W5 |; p+ Y9 Z
  248.                 ArrayLeftShift8bits(a_DtuOutBuffer, &b_DtuOutBufferRxCnt);7 J0 r. |* s( D. W% m6 g
  249.           }& Z" i) k1 I7 i0 f9 z4 k& S8 D
  250.           else0 }" x2 B) L4 k' F, {. [
  251.           {7 Z& Q2 o; f: u! D3 j2 Z) ^
  252.                 b_DtuOutBufferRxCnt = 0;
    + Y: \3 v* Q6 m! {! @
  253.           }
    / H4 V$ P( v9 q( }$ }
  254.         }
    ! g$ f0 `& w  X! q1 S5 e( d
  255.   }" g( U7 t  d9 p/ _/ J) u, e: h+ X
  256. }6 X" A: c3 A% u1 l" s" v8 G4 h3 W
  257. void Task_DtuRedoConfig(void)
    0 c" `; e9 l1 ]1 w% R! o" f
  258. {
    - T: ?7 i$ j  e9 N1 M6 h
  259.   if(flag_DtuConfigUpdate==0)
    . ^' ]# [/ w" @+ o- S$ J* Y
  260.           return;
    4 c6 j+ ^* ]. g, x! R! H2 _

  261. 4 o0 }" U6 U! Y
  262.   HAL_Delay(10);
    # A# S4 l6 B- N& I
  263.   printf("Re-initialize ETH, WIFI module, RS485...  ");
    - s; W. q' B$ J& y1 W$ M
  264.   //ETH:! d9 |/ ]3 D& n6 U
  265.   if(status_TCPProc >= 2)1 u! o- E* P6 u. o9 ~  p, Z
  266.   {- m2 Z; P0 e# ?6 D! f
  267.           tcp_echoclient_disconnect();
    7 t7 X" Z8 ]* ]: H% K# g
  268.           status_TCPProc = 0;9 S" ^4 }$ c4 r9 d  D
  269.   }
    ' F* p/ m* i8 i, X
  270.   //ESP8266:
    " M0 x1 c) v; ]+ H/ }. `4 y8 K
  271.   if(Status_NodeMCU>=6)+ k' m3 R/ z! w( B
  272.   {, ~% o; a: L0 w3 s7 t
  273.           sprintf((char *)a_8266TxBuffer, "+++");                //esp8266 接收到这个+++会停止透传模式
    7 g5 E$ _' z1 Z: ?. G/ o3 {
  274.           HAL_UART_Transmit(&huart3, (uint8_t *)a_8266TxBuffer, strlen((char *)a_8266TxBuffer), 100);
    . J2 f( _2 t$ {5 C
  275.           Status_NodeMCU = 0;' x( v$ e1 `$ ~4 [  b1 u
  276.           HAL_Delay(100);
    % \$ W1 v" C( x' |
  277.   }* b3 L' ^: Z) c4 N- P
  278.   //485
    5 w( L$ K+ n2 P  [. J: m& w: @* ?
  279.   //MX_RS485_Reconfigure();
    3 ~  _+ ]) O$ z
  280.   printf("Completed.\r\n");
    & f8 T: D7 s* R3 F6 z
  281.   //3 c1 f+ s9 u' ]. t4 t
  282.   flag_DtuConfigUpdate = 0;  D  X" @: F2 A) i. Q

  283. 3 c* w  [) o2 y; i4 ^
  284.   HAL_UART_Receive_IT(&huart1, &b_232RxByte, 1);/ P, N9 D/ |& t* Q2 R
  285. }
    7 l3 y1 G) K; T
  286. /* USER CODE END 0 */: x; ~9 K) N7 r+ L. y6 K! |
  287.   f! J+ f& Q. U: F) \
  288. /**' }, J/ F. D+ g) k
  289.   * @brief  The application entry point.0 g# C! W7 J+ J. n/ g- m
  290.   * @retval int
    " F' [% n+ _( X
  291.   */8 K4 [0 m3 `1 M; C( A+ Q  x3 _* Y  A
  292. int main(void)9 ?2 K3 s* N7 ]/ M' O( `. k3 T
  293. {
    - F; M$ r& a$ ^0 a2 Q. h+ J
  294.   /* USER CODE BEGIN 1 */9 |4 F. g' i- W$ C' A3 _

  295. * J4 Q% l4 v7 D' n
  296.   /* USER CODE END 1 */
    : C. n- ^( O) s0 I1 a3 G2 I8 S, g
  297.   8 ?$ y( m: x9 u! w' [% F+ r

  298. - J1 v6 ]6 W* S8 f4 R% A
  299.   /* MCU Configuration--------------------------------------------------------*/! U8 I0 _, w+ B( v2 C8 L7 m

  300. 1 r/ T! V; B( D5 q. p
  301.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */% g0 t# M8 F7 s$ Y# T
  302.   HAL_Init();% y6 M# q( D' ^) X& f

  303. 6 _- O, l" B. L( o
  304.   /* USER CODE BEGIN Init */. i5 I1 A. o( i0 @9 u

  305. 7 {* m8 ^/ |& \+ Y5 U, a: X
  306.   /* USER CODE END Init */$ T  o0 O8 n7 c! \9 Y: D6 s
  307. 7 e0 k; {1 S, N
  308.   /* Configure the system clock */
    1 C; E# R/ U3 K6 r4 @1 d& P' `, T
  309.   SystemClock_Config();
    ( ]7 J1 j/ W' M. e# {

  310. + Y7 ^; O2 b1 m! ?+ B
  311.   /* USER CODE BEGIN SysInit */, R# O' t! I- ]2 Y
  312. . U# f0 r. r0 }. A, e; I* E
  313.   /* USER CODE END SysInit */, d& Z4 ^8 V+ ~1 f  `

  314. 3 J  t: s4 }2 w+ ~- Q: j+ V5 P
  315.   /* Initialize all configured peripherals */8 C0 S- H9 X& |! y/ o2 T" z
  316.   MX_GPIO_Init();& C/ U. e. S- s6 {! q" `6 d
  317.   MX_DMA_Init();
    , {0 L4 C) N( ^; _6 d: ]9 }
  318.   MX_USART1_UART_Init();
    . C; q* }7 L, T- l
  319.   MX_USART3_UART_Init();; d. e  J- F7 q3 u( v) M
  320.   MX_CAN1_Init();
    6 i9 }# `/ x# D/ j. H( p* M
  321.   MX_UART5_Init();( H; ?1 N- g4 a8 I# j3 b6 @" e
  322.   MX_LWIP_Init();
      @8 v1 T8 r5 K( l
  323.   /* USER CODE BEGIN 2 */
      V7 V* Q9 ]! g5 S& H& }0 S0 V

  324. 2 u' _2 E& R2 @
  325.   RS232Interact_Init();
    1 Y$ {$ ]( |( Z
  326.   printf("Hello. STM32F107_DTU project: DTU. All in one.\n");0 V9 ]2 h. S, S2 h) F5 r
  327. 8 p/ o( b/ l: \1 w8 d0 w$ u
  328.   HAL_UART_Receive_IT(&huart1, &b_232RxByte, 1);
    2 u- P; a1 z* o7 J+ e1 h
  329.   HAL_UART_Receive_IT(&huart5, &b_485RxByte, 1);
    % Q& o9 c1 F( Z0 S2 e/ V5 n
  330. + P0 }+ t  j0 M) l' a, [

  331. % N+ n/ Y5 O5 @8 K- `2 `' k" \
  332.   sprintf((char *)a_8266TxBuffer, "+++");                //esp8266 接收到这个+++会停止透传模式
    - F7 x  v2 {. H, X* v; H
  333.   HAL_UART_Transmit(&huart3, (uint8_t *)a_8266TxBuffer, strlen((char *)a_8266TxBuffer), 100);6 [1 s- p5 f: K
  334.   Status_NodeMCU = 0;
      ~7 N/ r0 m# r. Y, O" U

  335. 8 Q5 j- x" o; u, @% G: N5 J1 l
  336.   status_TCPProc = 0;
    ) h9 C# D8 y. o$ V# Z0 _
  337. 0 N$ _& E! d* ^1 o+ W* S
  338.   RS485_RX_MODE();
    % }6 c4 M* `( q( F6 u$ _* A! E

  339. ' }* W  r2 \$ K$ [
  340.   CAN_Config_User();
    9 b) p7 o  J) z! r

  341. ( X& u, o' t. @$ V- O' J" V

  342. 5 G& [  R4 `/ h2 w/ d* A
  343.   /* USER CODE END 2 */$ w' ~( L/ h! L
  344. % q0 ~4 B5 V/ [' u- l# N  l
  345.   /* Infinite loop */2 y- I2 X( F$ ~7 |4 O8 s# h
  346.   /* USER CODE BEGIN WHILE */
    , \, a2 [- K* l$ @  y8 `
  347.   while (1)0 o' k! g0 @: h! {$ t  U- a
  348.   {
    0 V! ?" _1 o' a& E
  349.         if(a_DtuInOutConfig[1]==2)
    3 ?. M3 X6 z9 i2 z. _3 G) Z0 @1 V4 }
  350.         {
    * M* v& r% m) i5 A( o! o- e# k
  351.           MX_LWIP_Process();, I4 e4 |% w& f; K
  352.         }
    % M& e/ \, T+ s2 \9 x$ Q6 k: S
  353.         if(flag_1ms ==1)
    " Q$ _7 V2 ]! {) p; F4 n5 w% \1 B4 ]
  354.         {# E1 r8 h. c6 ^, V* H/ i5 m8 _
  355.           flag_1ms = 0;6 N2 i: v- P/ w- N
  356.           Task_232PC_Interact();( B' S! b3 c& W# L0 I: }
  357. 2 q/ b3 [& y7 J% u- @. O. f
  358.           if(flag_DtuConfigUpdate ==1)
    " n; `6 {2 X. n  u! L; x8 U
  359.           {
    . h8 m6 e9 u0 J" T* t- A
  360.                 Task_DtuRedoConfig();8 X- T# e  m. {- {" w( l, G
  361.           }# M9 R# g: `1 |9 n) g0 @
  362.           if(b_232STM32ParamConfigBusyCnt>6), \7 o( ~% A/ ]7 ]0 w" k4 w
  363.           {$ H: a/ O( u8 C1 g! A' k4 C  `5 Z
  364.             Task_DirectTransfer();
    * D! h# X2 \( D) X# ^% R9 i9 n
  365.           }
    , g7 h& F! l& M' o6 z, z
  366.         }
    & S  {$ R5 ^5 b7 x) c0 v' w% A
  367.         if(flag_10ms==1)
      L9 [) G0 M% x6 e
  368.         {
    # Z% B8 q) d9 N% a6 f8 r3 \( d
  369.           flag_10ms=0;- f0 a5 t0 o/ C3 {4 S3 y

  370. - J4 X' ^8 t2 C
  371.         }: u) M) K( l+ o# B) v
  372.         if(flag_50ms==1)        {                flag_50ms=0;            }' a6 e8 O. Y* o  M9 B9 ?
  373.         if(flag_100ms==1)
    9 G, w4 R: L! }
  374.         {
    * E2 e5 A, e9 n5 g: A
  375.           if(b_232STM32ParamConfigBusyCnt>6)
    0 ^) M8 G1 `% }* b4 V
  376.           {
    % E3 `" I1 T6 X- x2 P# M
  377.                 if(a_DtuInOutConfig[1]==1)
    % B/ \2 b* y% ^8 e7 @  U% V& W; d
  378.                 {5 V, S7 a7 s( \6 e/ W2 f0 g8 R
  379.                   if((flag_ProcNodeMCUActive ==1)&&(status_232PC<12))
    9 z" t+ y+ T8 I
  380.                   {* W3 \3 ?0 U/ Z. N
  381.                         Proc_NodeMCU();+ a: f' _8 J! Y6 Z( D- V) l
  382.                   }
    ; x1 ~0 @  y: D/ O% d/ o
  383.                 }; K. h5 W( }+ v$ C/ P
  384.           }; k& _3 B4 P% e6 @+ E+ e2 v6 ^& Y4 L
  385.           flag_100ms=0;/ c, M' S& c+ p3 ~
  386.         }
    1 ]( o( O% T$ I) Y+ ^1 t$ I
  387.         if(flag_200ms==1)        {                flag_200ms=0;            }
    + @- U* g6 b5 o# P6 w
  388.         if(flag_500ms==1)        {                flag_500ms=0;                }0 K* [5 e5 u/ {. ]: V- b$ J# n
  389.         if(flag_1000ms==1)
    " \( [* n9 ~7 u9 I5 n* p. Z
  390.         {/ U$ Y) a4 A1 F8 I! c% b  P
  391.           flag_1000ms=0;
    % r. v: C& p% N2 M! X
  392.           HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
    4 b. S# o: |3 e( ~$ g  f& i
  393.   B9 y$ u/ R  }. E0 p) b
  394.           if(b_232STM32ParamConfigBusyCnt>6)
    . P2 k; K2 z. \+ J" ~6 n8 N; T
  395.           {
    ; u5 Z/ k4 R  u' B
  396.                 if(a_DtuInOutConfig[1]==2)
    # l  ~& J9 d. u) X% H6 D
  397.                 {
    ( _) \; E7 m; G' ^- {
  398.                   if(status_TCPProc<=1)- z. @1 t( W* q  N# B( _
  399.                   {
    7 Z. u* Y) {. ?' y6 D. H
  400.                         printf("connecting to TCP Server...\r\n");
    0 p! _; G! X6 o) D/ x. N! a
  401.                         tcp_echoclient_connect();
    # O# m2 P& }7 ~4 Q
  402.                   }
    % K7 j- E, ?/ J. ?% x1 F' R4 z' R* J
  403.                 }1 h6 q( H# [$ h& ~! E5 }
  404.                 Task_HeartBeatPackSent();
    ; Q- e+ r& ?5 S  v
  405.           }
    ( X% ]: X& Z" B+ u( u
  406.           if(flag_ProcNodeMCUActive ==0)
    # j5 }& n* ]& a/ b% x
  407.           {1 s% c, q: W& {* O7 |4 I, L+ S
  408.                 flag_ProcNodeMCUActive = 1;
    . e5 F4 `( U0 q5 W3 ^% o; R- e: ~
  409.           }, Y4 P7 p, U" J1 V
  410.           if(b_232STM32ParamConfigBusyCnt<80)6 J  g/ }: @; ^4 k! I# Y% [
  411.           {3 z3 o* T' D0 J" C1 Y
  412.                 b_232STM32ParamConfigBusyCnt++;
    9 E% P7 f& w6 C3 ?: ^
  413.           }
    3 N" k# X! n* d. R, G" N
  414.         }
    , i3 z: M0 c9 k: [
  415.         if(flag_2000ms==1)
    0 l7 z: u- C# C9 J7 s
  416.         {0 ]7 o- k) A. m  a: p- W6 Q
  417.           flag_2000ms=0;! C* R9 k4 |. Y  |' v  T0 l
  418. . ^5 d, ?% @1 @# N
  419.         }  }& R8 j8 ?+ R- @% k+ [" Y
  420.         if(flag_5000ms==1)
    7 l+ o3 U+ }+ F$ `; X
  421.         {7 z8 n, l3 C* G
  422.           flag_5000ms=0;% [* W' S  q- c( W: a: k7 ^% i
  423.         }
    " T2 \$ V6 `. A9 N/ W

  424. 6 P; S! R5 {0 F' F) \. P
  425.         if(flag_10s==1)$ |* }" S1 Q- K+ B
  426.         {2 b, ~7 i. A" H& t& O) s! ?. g
  427.           flag_10s=0;. `( s3 ^$ i9 T5 ^9 \. K8 V
  428.         }3 U: F/ C* G2 n- c- C
  429.     /* USER CODE END WHILE */
    ' V# ^4 U  C0 v& R

  430. 2 h) D( f4 h4 A) L. M
  431.     /* USER CODE BEGIN 3 */
    1 L! s3 S- ~6 k, |; w# t
  432.   }% E' _+ Q7 t5 }  Z  m8 L5 M% [
  433.   /* USER CODE END 3 */  \( h& p  Z* k; x9 Z
  434. }
    ' @# C% c+ a/ L% m9 P
  435. ( G0 m$ Y  J% c, m
  436. /**
    ' R. k- N) U, E/ H8 d/ i/ C) D
  437.   * @brief System Clock Configuration4 ^6 Q# |/ N& E, ~4 A% T
  438.   * @retval None" E, ]8 `1 m; E, d1 C: C; [4 i
  439.   */$ |( K9 w2 O# W& u
  440. void SystemClock_Config(void)
    5 t; u& ], v2 ^3 n8 N" y
  441. {( {, j- j2 R" v' Z1 Z
  442.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};4 ]1 y/ T/ h$ ?6 G' ~
  443.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};1 A; \  B7 `$ ]3 g! {' d
  444. . i+ Z1 A/ a  p  X0 b( F
  445.   /** Initializes the CPU, AHB and APB busses clocks 5 ]1 Z9 Y' ?1 ^7 B
  446.   */8 f7 `" T6 N7 q4 w1 ?
  447.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    , w$ h3 T* ~% ^8 s: L$ d
  448.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    1 L& W0 g2 a' i. f. H; v& n) V
  449.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;' ?, g7 C& }: b3 W3 Z- U8 r
  450.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;0 a9 E1 c5 d, H1 N! n
  451.   RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;: u  p8 P8 b. x5 g
  452.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;8 M5 h- y9 ~8 v$ J/ w  J8 ~+ k
  453.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    ( W7 j! A, C- g3 }
  454.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    ' J3 k3 I+ K+ M6 w2 J* ]* [
  455.   RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;2 D# E1 O7 n: n
  456.   RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL10;
    * \9 z- y, s- }. |% p( |; G
  457.   RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV2;& O  E1 @0 W: V* L' U
  458.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)4 c# a3 [# n( E) {
  459.   {, o' p6 v: R" U3 l; b
  460.     Error_Handler();
    4 H+ y" b7 R: [0 D0 K) B  v7 C
  461.   }
    ! o0 F7 e* c2 j: G4 _& w
  462.   /** Initializes the CPU, AHB and APB busses clocks 5 e4 g; g' c" E
  463.   */& @3 D: b5 B$ I- U( V4 g
  464.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK6 `. y4 L% i, S: T. d; i5 ~) B& ^$ K
  465.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    - ~$ w% H9 D: [. k
  466.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    # r; W; e* ^; C8 F
  467.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    ' L! G) m+ h& y* o6 h/ t4 D
  468.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;& |9 G/ u+ T4 V  N6 U
  469.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    & V" S+ C6 t# u' v. V' @1 G

  470. 3 W6 r* r# S2 H# s4 U
  471.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    3 r. {8 m, a0 A6 C- c" D: f" s: P: s
  472.   {
    : a; m) b0 A, I
  473.     Error_Handler();
    & w: L, ^! x5 o+ [$ Q
  474.   }7 C+ D% X% v5 W8 [1 d. Q' f' a
  475.   /** Enables the Clock Security System
    ! C9 ~  u7 c0 n
  476.   */8 {- v/ Z: I4 y+ F4 [4 d) ?
  477.   HAL_RCC_EnableCSS();
    ! y# U' V+ i+ i! ~- a2 t
  478.   /** Configure the Systick interrupt time
    ; c5 F4 l1 E: U
  479.   */
    * u" B; c' y  Z2 N
  480.   __HAL_RCC_PLLI2S_ENABLE();$ |$ A% L$ z- I: ]* ]
  481. }1 K# ]: v( P, b! \+ j8 m7 X. e

  482. ' y; K  f( D) T6 _0 [
  483. /* USER CODE BEGIN 4 */
    3 w: ^' r* [+ A8 \$ D
  484. + g4 T1 P( L  Z; }1 d- d
  485. /**( x; U  l) K2 o! F7 d! h/ T6 y
  486. * @brief HAL_SYSTICK_Callback()
    0 L4 A; q( v! R, u* d/ X, ~- }
  487. * SW timer triggered every 1ms.+ Q) ~. j9 U, {' Q' p$ h
  488. */# c# O1 g3 u# Z" ?' F
  489. void HAL_SYSTICK_Callback(void)
    8 F5 o* w4 i* G+ A6 D: H
  490. {
    3 V/ }+ l- A, J6 ?/ O
  491.   flag_1ms = 1;# O. c/ t" a6 s( W' N) ?
  492.   /*update counters*/
    , _. d4 Z6 m) [0 h. }
  493.   if(counter_10ms<9)  {    counter_10ms++;  }, l7 M( Z5 x6 ^4 N1 K9 O
  494.   else  {    counter_10ms = 0;    flag_10ms = 1;  }% x5 m5 Q2 m) I
  495.   if(counter_50ms<49)  {    counter_50ms++;  }
    ' v2 \2 @4 ]; s: Z
  496.   else  {    counter_50ms = 0;    flag_50ms = 1;  }
    ! O# m! L5 f) U4 G% u2 O0 ]4 ?* }: d

  497. , d0 _4 x4 o6 r( E, X. f
  498.   if(counter_100ms<99)  {    counter_100ms++;  }0 I% I! o/ D  V$ M
  499.   else  {    counter_100ms = 0;    flag_100ms = 1;
    + y/ m  I) _: T0 N* L
  500.         if(counter_200ms<1)        {          counter_200ms++;        }5 C1 s! G) G5 B. O  U9 y& Y) [1 q
  501.         else        {          counter_200ms = 0;          flag_200ms = 1;        }+ O( [6 N8 T; a7 r' n2 s5 a
  502.         if(counter_500ms<4)        {          counter_500ms++;        }% \4 c& O) A$ x9 Q4 w) [
  503.         else        {          counter_500ms = 0;          flag_500ms = 1;        }
    / o/ X$ b8 @; A9 E6 }5 O9 H9 S
  504.         if(counter_1000ms<9)        {          counter_1000ms++;        }8 u9 h& }6 z; G
  505.         else        {          counter_1000ms = 0;          flag_1000ms = 1;        }! g) @. Y3 c- C- e2 ^4 I
  506.         if(counter_2000ms<19)        {          counter_2000ms++;        }
    $ W# O: T# \) X: N! f1 @7 G
  507.         else        {          counter_2000ms = 0;          flag_2000ms = 1;        }" N' ^; Y9 O0 B/ Z
  508.         if(counter_5000ms<49)        {          counter_5000ms++;        }
    - g$ P2 V% U% x9 C- y$ h1 g: t
  509.         else        {          counter_5000ms = 0;          flag_5000ms = 1;        }
    ; Y7 ~. x8 A5 N7 x! U3 q& A
  510.         if(counter_10s<99)        {          counter_10s++;        }
    7 W0 [7 B* Q3 `! y/ `6 j( j. J
  511.         else        {          counter_10s = 0;          flag_10s = 1;        }% I# D8 F+ ~1 M. _
  512.   }" h- P2 r" \2 R  R( Y3 Y
  513. }
    6 W7 j+ n( Q( u4 p7 j

  514. / V" j- Q5 H8 x; t4 G) b& K
  515. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)0 X5 j) H# t) X) |( l
  516. {, p( s" l3 \4 ~$ y( s% Y- ?5 {
  517.   if(GPIO_Pin ==GPIO_PIN_13)5 J. L0 z4 x/ }, d4 p, w+ x' ^- [
  518.   {
    : Z" w* m4 i" ?5 {
  519.         b_KeyNumber++;
    * P0 F3 B) r* o) m
  520.         if(b_KeyNumber>=2)4 W5 G$ P9 j+ k! N: l0 z
  521.         {; `- q2 V$ S- f% Y) y
  522.                 b_KeyNumber = 0;- E. E; q7 [: V9 O9 g
  523.         }$ k1 M& i9 A. M7 h3 r2 @

  524. 8 q$ \% ?& @  P6 u1 Z
  525.         sprintf((char *)a_DtuInBuffer, "a simple package\r\n");% I7 }4 I/ M" r) r- ?+ w. c" h5 D6 e& I
  526.         b_DtuInBufferRxCnt = strlen((char *)a_DtuInBuffer);
    3 F. k6 u& G+ p, Y6 z& F

  527. . s$ }- [0 R# a7 p, G% b
  528.   }
    / T, t  z5 Q' ?  J- L) L
  529. }
    : s+ n- M7 B' _

  530. / I, Z3 d% A( j( S4 V7 `2 T
  531. /* USER CODE END 4 */
    . L: R1 t) Z: x$ ~1 ~

  532. 0 H4 k3 ^3 Y& o; _
  533. /**
    / `' n" h' s3 j# W1 B8 T% Z
  534.   * @brief  This function is executed in case of error occurrence.
    % |" X' R& ^' ^
  535.   * @retval None- B0 ^6 c' j0 L' i
  536.   */
    1 I- a, k8 F- D& g+ K  u
  537. void Error_Handler(void)
    ; `. E, I, A% Z9 R$ y/ y: `( ^7 [* j
  538. {2 [3 O) n( A( e0 |2 U6 ~* E
  539.   /* USER CODE BEGIN Error_Handler_Debug */
    * b6 v) ^( n- ^
  540.   /* User can add his own implementation to report the HAL error return state */
    + R* \6 V- P! h$ R0 M

  541. 4 ?, G+ R" P% v- p, y7 }
  542.   /* USER CODE END Error_Handler_Debug */
    , S2 ]; `2 P% B5 D& ~  }( o
  543. }
    1 M# i7 L: r6 x9 N$ I5 v

  544. ; T, K# i' T* f, O0 e* b8 I
  545. #ifdef  USE_FULL_ASSERT
    & R8 l+ H8 M4 o0 Z- h7 g+ E
  546. /**! E2 y$ {# `1 x0 Q  ]) Q: W
  547.   * @brief  Reports the name of the source file and the source line number  P+ o" E2 C+ d/ D3 V
  548.   *         where the assert_param error has occurred.3 b- s; I  d0 j* }, ?
  549.   * @param  file: pointer to the source file name
    6 \# [! y9 i: a% ?" w9 b6 Y- v
  550.   * @param  line: assert_param error line source number# b8 J% F9 U1 d4 \+ g
  551.   * @retval None4 W6 D6 D& I" _) g$ Q* X  {$ q  @$ |
  552.   */
    : U6 a2 a4 t$ ~/ R0 v3 R# A
  553. void assert_failed(uint8_t *file, uint32_t line)
    2 [+ Y; Z0 _' o4 S, F
  554. { + S. o* l" V8 U/ Z+ _
  555.   /* USER CODE BEGIN 6 */0 @) @, {9 x# h: g( e6 {
  556.   /* User can add his own implementation to report the file name and line number,& @% _; U% B1 H- \1 |
  557.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */) U- z$ R0 a, L" u8 U
  558.   /* USER CODE END 6 */
    . i7 R2 |- B, ~4 U4 m( ]
  559. }
    + u$ a* ]8 l7 E/ K- H( C8 W
  560. #endif /* USE_FULL_ASSERT */' P  c) X" H9 S' U2 j" s# @
  561. 7 G# K" Q6 _) l3 J9 m
  562. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码

" U" P4 j" x; T4 i2 q4 试验结果

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


7 Q& Z& O5 b3 \, t, D. ~% E7 o3 L; g: m) {% z4 [" h- d
收藏 评论0 发布时间:2021-11-27 09:29

举报

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