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

【经验分享】STM32G070 定时器中断接收时间码

[复制链接]
STMCU小助手 发布时间:2021-11-14 23:04
时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,% Y. a9 O% i5 n+ S" u( s8 z
' W% ?4 i; p6 y  n. E1 G' x
20201127093851207.png

* M* f( F1 {, G6 k( i7 z* L% x
" t& i+ C- n* e) i9 k! Z  |4 g) B! k! M
实现原理,
4 p3 c: t& @' g% p$ v- ~* V4 _4 i7 O  M6 c* K# v3 j$ X
1.  EXTI  Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period# G3 O  I( B1 L3 Z. `, S1 n% l

5 I, w  e$ X" D- d2 \2.  继续用EXTI  Rising/Falling 中断+定时器方式接收时间码0101值, EXTI  Rising/Falling 中断时,修正定时器中断周期为Period/2。
9 Y. v& g: @) t7 W3 `& o6 b4 G& F; Z4 D/ ~
产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period
8 }$ ?1 x5 p6 }* J/ k4 l2 I: _$ c( i6 n# I0 M/ a& m' ?+ R
3.  解析差分曼切斯特编码,查找同步码
: A  U4 I8 F, |
8 c( Z# G8 F' n1 u" [8 T流程图,
9 M! }$ v; n! s3 R9 [6 [8 {+ m& C- @/ J/ U0 |2 o% N8 |
20201127113610958.png

; f: G. A4 @% m2 g, |+ W0 J
9 V: l- X8 \% q; o( A) E
. q  l4 V3 R0 ?/ {关键过程代码,
0 S0 A: b- x, H# a: _; c5 s( n
/ u* E9 [3 G# W# _6 T1. EXIT 中断处理! A7 E: p6 d) F
( V" A) C; p' X8 Z3 k/ V/ K* J2 W4 o
  1. struct LtcInput_s LtcInput = {
    . y  w5 I" v2 L) E  g, n! N# g
  2.     .tim = {0},
    # X4 |0 m" y" c0 V- i# \4 b
  3.     .tim_count = 0,
    9 L8 [6 y' y  D: B& w+ ~
  4.     .period = 0xffff,# y0 E/ y9 b/ J
  5. };2 E0 l2 {, Y* t4 @/ {) |9 v6 x
  6. 8 {" K' L2 I0 {# G! h7 a# |5 I3 U
  7. static uint16_t parse_tim_of_ltc_input_get_period(void)3 Z; p8 s; }4 s8 b! h
  8. {* u& J1 N2 \% R* J+ A7 }
  9.     for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {
    $ z( K+ g7 n3 l  e
  10.         for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {
    8 M8 Q5 u) z# m. g7 w" m% n
  11.             if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
    ( J! ]: B1 k8 B+ q( |9 b
  12. <span style="font-style: italic;">                uint16_t tmp = LtcInput.tim;
    * p  N0 x# G% W" o& C3 i
  13.                 LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];
    ; _6 B1 C. p/ z+ V/ S. X0 \' n
  14.                 LtcInput.tim[j] = tmp;
    4 n" O. }7 s0 g) `" K9 @
  15.             </i><span style="font-style: normal;">}
    - k2 E  I5 n8 S$ \! M/ ^
  16.         }5 T: w4 r6 V0 @# M8 x
  17.     }
    / q- j$ Q+ V8 F& }
  18.     uint16_t period = LtcInput.tim[10];
    # y1 h) ~9 G6 M/ `% O5 i: {! q( n$ O
  19.     return period;
    0 p3 C& A' B* M% ~6 \: D( d
  20. }
    ; o) v" |# F5 u7 y" [% H& ~, T
  21. 0 Z0 n( z* B" U
  22. void ltc_input_timer_restart(int period)# S2 D8 P$ Q, x4 G! a* Q
  23. {4 s9 ~7 R$ G: B) ?
  24. 8 o2 {5 o* L5 a- d) y7 A& F/ \
  25.   htim3.Instance->SR = 0;. _) K% r9 w5 [9 I
  26. htim3.Instance->ARR = period;
    $ ]7 T, l9 I  o  r" O) ?, u
  27. htim3.Instance->CNT = 0;, p: U0 a& A% \; |3 }0 |3 W7 x

  28.   y* i* ^) A" y: m' @3 O2 @
  29. }
    6 f* i& o/ g' O% I9 U
  30. ' L) A/ o1 }; U5 g3 ]" s
  31. void ltc_input_pin_callback(void)- t" ]) |- l1 e6 v# J+ {
  32. {% p9 O/ i* [4 v' n: ?5 J# O
  33.     // HAL_TIM_Base_Stop_IT(&htim3);5 Z0 w8 c( i  V
  34.     if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {; O$ g! i3 @' C, x1 ?9 r
  35.         ltc_input_timer_restart(LtcInput.period/2);
    4 A& `5 }9 v* l: R) s
  36.     } else {5 q  b" b1 V$ q& P: \8 r
  37.         LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;
    , r, A+ c4 J3 g. a! o' E% u2 l! X
  38.         LtcInput.tim_count++;6 Z) C2 p% ^: h4 e" I
  39.         if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {! L) I" L" t. }7 }+ [" `$ D2 L2 E
  40.             LtcInput.period = parse_tim_of_ltc_input_get_period();6 H. L6 t* h+ k6 v" g$ `" N
  41.         }( C1 x8 p1 l' |5 Z. {3 ~, R
  42.         ltc_input_timer_restart(0xffff);" q2 V- @8 t$ i
  43.     }
    5 y5 v- v! f) h+ G5 o
  44. }</span></span>
复制代码

) \8 `- U, M( z: R' d8 n! D2. 定时器处理
, X% {# ]7 F' Z% r9 d2 K' d' i2 ^
  1. /**: ^* U8 w  y, J0 y9 _
  2.   * @brief This function handles TIM3 global interrupt.
    - }! P3 m: U% @. V6 ~  A" q: Z
  3.   */
    " E) r* X" H, g: q8 |" \8 ^$ L
  4. void TIM3_IRQHandler(void)
    4 }( C8 _2 [1 v6 z$ X  l0 H: q
  5. {& R4 ]% V/ |: W! |% S
  6.   /* USER CODE BEGIN TIM3_IRQn 0 */2 Z- ]+ H& a9 Z* T( d1 ^
  7. 5 ?5 n  F0 F) T2 O& |
  8.   /* USER CODE END TIM3_IRQn 0 */
      L+ U. r* ~8 `
  9.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);4 j1 A- ~  a+ b/ v0 E0 \, \5 s( O3 [
  10.   htim3.Instance->SR = 0;. ^2 T( _* N4 M, N
  11.   htim3.Instance->ARR = LtcInput.period;
    ! l8 s& |3 \! ^2 K* ]
  12.   htim3.Instance->CNT = 0;8 Z) k: P1 ?0 S5 U+ l! w' `
  13.   ltc_input_timer_callback();
    $ W5 I: i1 w5 E0 o/ u/ y* k
  14. , g7 B2 {! j7 S! N8 x: H
  15.   /* USER CODE END TIM3_IRQn 1 */
    ' Z5 I2 ]1 E& u! e* ?! w
  16. }  A- D5 l9 o) c3 I

  17. 8 \8 ]) {5 f6 P
  18. char ltc_input_timer_callback(void)
    2 B; y$ I6 m# O+ h' `; |
  19. {. O3 N. Y1 ]8 j0 Z$ L+ `
  20.     GPIO_PinState status;
    1 A8 z5 D* n) @1 w) \, i2 y: c7 ]
  21.     unsigned char x, y;
    8 B5 m2 x% {/ Y: K- ]4 q% z9 W

  22. 4 Q- X" J7 e0 h& x& w; ]6 o
  23.     status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);
      [6 v6 E3 F! O$ v* J1 p2 c( x
  24.     //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);& f( d, `+ F: t$ r9 i
  25.     //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);3 N' C! t* ]: D7 i1 F* @* K
  26. - G7 G1 ]  k9 P0 C- A
  27.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);
    ( I! _8 g: u/ i% @  p
  28.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);
    8 d' a0 A* M+ G# \3 c9 E" |
  29.     //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));
    : L( f7 E9 w1 \) U, T% U
  30. ! l' b, j% [6 `/ y8 b- h) F
  31.     x = linear_timecode_count /8;) H% u+ W, r8 F
  32.     y = linear_timecode_count %8;# N2 I, T& O7 J. W' I! C

  33. % T0 t6 I7 J8 K. M( Z- i
  34.     //buf[linear_timecode_count] = status;$ T) }: f7 T  T8 B$ g' W% j, T; t
  35.     linear_timecode_raw[x] &= ~(1 << y);  Z  g& k5 d# q: e
  36. , g0 @7 {$ X: V! }. u% B
  37.     if(status != GPIO_PIN_RESET) {
    / `$ e8 \4 p' [% P
  38.         linear_timecode_raw[x] |= (1 << y);. ?5 K4 v3 T% {& A5 O# P5 L& G
  39.     }1 k  D% F5 ?0 \# M& E, y* X0 H( _+ \
  40. : ]; C2 u  x0 t: P0 g" o
  41.     linear_timecode_count ++;
    7 r4 `) v8 s- f& L1 x
  42. # U8 j4 ]4 J& B3 A4 Z
  43.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {, s8 `6 F6 m! V* t- \# n+ z: q
  44.         if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {
      {# r% T1 Q$ H6 C2 y
  45.             linear_timecode_count =0;
    1 z; Z$ @' |' c0 `" \' S
  46.             memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));0 X4 `( q) b% S* b
  47.             linear_timecode_ready = 1;
    6 q2 J9 k9 J) \
  48.         }2 z" ?& j& p5 Y$ F7 q/ e
  49.     } else {
    % G: R& T' S* n1 N. }& s
  50.         if(offset_bits > 0) {
    4 \/ x# Q6 n8 W
  51.             //skip offset_bits! b9 V, U3 i( n) r0 K: _5 ~3 y5 P
  52.             //If offset < linear_timecode_count, adjust the offset to the next frame.
    4 _0 ]; h9 y' D+ H1 g8 K2 G+ ^, W
  53.             //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.0 Y5 I/ ?# u% ~+ w
  54.             if(linear_timecode_count > offset_bits) {
    1 }3 ~0 p' O( V$ z( t9 F) L. v6 S: R
  55.                  offset_bits += 160;
    # _# K+ K3 ]# `9 N* _! @
  56.             } else if(linear_timecode_count == offset_bits) {  @" }* g5 N, v2 e
  57.                 offset_bits = 0;
    7 P: y6 y) q' k* j
  58.                 linear_timecode_count = 0;* ~9 T6 ]! r. r7 C6 d3 g
  59.             }  y+ Q1 ]5 X9 }
  60.         } else {
    7 {: x. A9 h' [' A, P! U
  61.             if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {
    - Y3 A+ Z( M9 g. L
  62.                 linear_timecode_count =0;. ~- I6 B1 F, y6 S) ~
  63.                 memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);% \4 @  Y1 D: C; Y& z( N
  64.                 linear_timecode_ready = 1;" s# |. }2 y+ S* ~' x
  65.             }
    , e- ?7 i" L1 Y
  66.         }
    ! x  X5 k# i& @! M% T3 j+ s) A4 L8 @
  67.     }, b+ h$ {0 X7 l; X/ V- i
  68.     return 0;
    & n8 i  F# s. C8 L
  69. }
复制代码

) v2 R, d" l7 Z5 A8 n: i3.  差分曼切斯特码解码
; e9 o5 k1 N$ s. n$ L
  1. 3 i; C/ y" A; A
  2. unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
    ' V0 }- [  @$ _+ k$ x( F0 J, m, K0 D
  3. unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
    # w7 B% E) t' b1 r
  4. - N$ ~6 J3 i$ [
  5. static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    0 a# X3 L' @; k/ J) X/ D
  6. {
    4 b+ r3 \) C; n
  7.     unsigned char i;
    0 S+ d( i" [! Z. _
  8.     unsigned char tmp;
    7 q4 |1 @6 y2 d* f9 s0 b' u5 ?$ [; z
  9. ; q3 y* L4 z+ f/ `- o6 \7 I
  10.     if((nbits < 1) || (nbits > 7)) {% I, r/ ^5 p1 R4 c% |
  11.         return;
    . O# ~7 I" _0 p6 L
  12.     }
    ; m8 N. [3 e& N# Z9 `$ f
  13. ( @* k( ]+ J# C1 p; O8 z1 o
  14.     for(i=0; i<nbytes - 1; i++) {* H* E) s* K( v
  15.         tmp = raw[i+1] & r_mask[nbits];% b8 p+ S5 ~0 X
  16.         tmp <<= (8-nbits);  ~$ D4 o' Q; e
  17.         raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;5 J' I1 I" A" ~: S3 o3 _2 B
  18.         raw</span><span style="font-style: normal;"> += tmp;! X2 X; t+ u5 D9 o1 \$ x  `$ u
  19.     }/ A' e; u! K# L. B: L' q
  20.     raw</span><span style="font-style: normal;"> >>= nbits;/ {& A; q$ P7 C, }* ~
  21. }
    ' t8 Q. F. Q4 P3 F

  22. ( Y, e" L) {: T
  23. static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    : j. w$ H1 W; T
  24. {
    . B9 O" L: M0 w/ z, N# }
  25.     unsigned char i;
    : |0 S# y. j1 `4 X
  26.     unsigned char tmp;
    & \5 z6 x! Z# B  f
  27. / ]$ u# d) k, [% b
  28.     if((nbits < 1) || (nbits > 7)) {6 `5 m. ^7 m+ M9 a4 o6 e
  29.         return;
    9 k1 k/ W* g9 ]5 F8 B. e4 O( C* F
  30.     }( i7 `: `4 C$ h+ }$ W1 k) D; x

  31. $ @- I) z7 m3 |7 S
  32.     for(i=0; i<nbytes - 1; i++) {2 M; Z5 t0 y: L/ Z6 {* ~7 V5 K( r2 F
  33.         //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;
    . k: `, e# k$ [( \$ H1 @
  34.         tmp = raw[nbytes - i - 2] & l_mask[nbits];1 U3 c& I. s1 ]" L$ K
  35.         raw[nbytes - i -1] <<= nbits;4 K2 v3 d* Q; j) Z* X+ j
  36.         tmp >>= (8-nbits);! l. ^3 a) o6 p' A! P2 q
  37.         raw[nbytes - i -1] += tmp;. {( a3 B" M* b' E1 K) ^
  38.     }9 [+ H0 Z) H0 f, A* E" r% R
  39.     raw[0] <<= nbits;
    . @# i% ~! R# k5 z
  40. }
    8 l8 X# s  [$ T9 i0 {
  41. 8 ^8 z& p: ^9 n: K6 J2 P; P# f
  42. static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)& H. {# L2 S2 V, z, E! v
  43. {5 o8 |9 n: v, w" Z
  44.     unsigned char x, y;
    " u8 m; {- c0 p& ?/ m

  45.   w0 C" {; J/ O! h. S$ C- K- a
  46.     x = nbits / 8;7 P# t: H  b, B, T3 B6 J9 Y
  47.     y = nbits % 8;
    5 i  e; T" i6 i0 {+ {

  48. 2 n5 C( \4 Z  g3 p
  49.     if(x > 0) {
    " X9 s- ^% X' o) Y  N
  50.         for (int i = 0; i < nbytes ; i++) {
    7 c& G+ `/ @& ~8 q3 r# I; g
  51.             raw</span><span style="font-style: normal;"> = raw[x+i];
    ! K; i' L) Z5 n6 z% n
  52.         }
    6 U  T; O: {8 T/ z2 V6 r& M( _
  53.     }
    + e+ @( K+ X1 d
  54.     move_right_linear_timecode_raw_7bits(raw, nbytes, y);5 ~+ R' J/ `) {/ y+ b" W
  55. }
    8 {$ j3 Y1 I) d1 J

  56. 5 f4 Z! d1 v1 ^5 I7 Z2 g( e) g  N
  57. ! M) q7 X, Q$ _7 Y5 N' Y8 {- f
  58. static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)+ C, n0 w" z0 j/ ~: p  ^! R. E
  59. {
    6 h+ ^' ~  v0 c3 \
  60.     unsigned char x, y;
      ]- l4 L8 t! D; E: d7 J/ I

  61. " e5 I; C% r6 s2 L9 q2 M
  62.     x = nbits / 8;
    ' l8 @: W! f6 S& D( W. O8 A# x' c% A
  63.     y = nbits % 8;
    # y6 v$ {& K1 ]; h5 x

  64. & i2 i( ^6 N7 ^; Z; n8 n; `5 Z' d
  65.     if(x > 0) {
    5 e3 ]: V" G: `1 J: }7 d2 R. h
  66.         for (int i = 0; i < nbytes ; i++) {
    * p- u# \/ H! |% L$ o6 E1 y
  67.             raw[nbytes-i-1] = raw[nbytes-i-1-x];9 o! ^1 S: u6 Y! F# s, d
  68.         }
    * n7 b' W& ^4 C3 v1 g& P, d
  69.     }
    5 E9 P/ |/ E& S
  70.     move_left_linear_timecode_raw_7bits(raw, nbytes, y);0 _) g9 U, D) z5 K5 ^
  71. }( r! e8 D# b! @* y  I

  72. ; R* [0 @* K. [# V( L
  73. unsigned char get_bit_linear_timecode_raw(unsigned char index)
    7 Z+ ]% q* _% N$ j
  74. {( Y/ M2 Z! |1 Y- ^
  75.     unsigned char x = index/8;
    " x$ u+ [; j  ]6 j8 H0 W3 A+ L
  76.     unsigned char y = index%8;+ X) ^1 s, ?( d/ S, G, r( z9 ~

  77. + e! c3 }+ |  U) e* g
  78.     if(linear_timecode_raw[x] & (1 <<y))
    " X% r3 Q5 }9 E
  79.         return 1;
    * t3 S; W% C7 O5 o" r% X5 m
  80.     else8 [. s& N4 g! R) ^' [+ `; I% t) N: I% u5 W
  81.         return 0;5 v2 F9 K9 ]  m, Y
  82. }
    - F2 b& H. b- q. U' X) C4 X! G
  83. : _) e  ]% f* ~
  84. static void parse_differential_manchester_code(unsigned char *src,  unsigned char *dst, unsigned char dst_size)
    ! e7 C9 M  Y8 u/ U: x2 G/ o
  85. {: W+ ]/ H+ F' n
  86.     unsigned char i, j;* `2 f* v: a& V9 F
  87.     unsigned short tmp, tmp2;. k5 s. O& u* Z6 m9 Z& r+ _

  88. . n% A  Y" a& b  {- H  X. y/ U7 Z
  89.     for(i=0; i<dst_size; i++) {
    ' t! O2 y  z$ [& s- I

  90. # s1 [+ V- Q7 s+ l( |8 I( f
  91.         tmp = (src[i*2 +1] << 8) + src[i*2];0 ]) M' q% {; J; U
  92.         dst</span><span style="font-style: normal;"> = 0;
    * ~( P  |2 s+ r" c; F* x; r5 ]
  93.         for(j=0; j<8; j++) {
    6 x7 j' b, B1 S
  94.             tmp2 = tmp & (3 << j*2);! G) Q/ _" U5 G! M+ ?4 h; d' K: b
  95.             tmp2 >>= j*2;- c) p, Z  E4 O
  96.             if((0 != tmp2) && (3 != tmp2)) {/ J5 f. L1 I# Y, J: x5 ^
  97.                 dst</span><span style="font-style: normal;"> |= (1<<j);6 p- x' m$ y4 w  |; I( g; S
  98.             }$ h: u0 u" P4 I8 }
  99.         }% Y2 i7 a8 v1 x& Y
  100.     }7 d" L  ~+ ?$ b; Q
  101. }, v) w" q2 A( V- N# {0 d4 R4 i: l

  102. 2 X  t. l# D$ w) I2 D3 p; ?
  103. static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len). T, Q+ {; g" |: o  U* C
  104. {
    0 A; ^: g- X5 j6 n
  105.     const unsigned short sync_code = 0xFCBF;
    - v, [+ s$ G9 y* w6 R6 x/ d
  106.     unsigned char i;
    , ~( O8 K8 E1 h0 F; Y, T' G
  107.     unsigned short tmp;
    ( L7 F  r  j1 R9 Y0 s% U# X7 I
  108.     char ret=-1;
    & f+ X. [( n6 e2 C9 R

  109. ' q4 p& j, T% ~6 e$ C. y, `
  110.     for (i=0; i<len-8; i++) {1 p- O" q5 P, R  u" W9 |
  111.         tmp = (src[i+8] << 8) + src[i+9];
    ) D) C# m6 k+ a+ [+ p
  112.         if (tmp == sync_code) {
    0 D; t2 Q. E# c  r5 Y  ]5 v
  113.             ret =0;
      p  `8 N! T* i/ M
  114.             *valid_len = len - i;+ Y* F0 {- c+ B$ s6 |
  115.             memcpy(dst, &src</span><span style="font-style: normal;">, 10);   //10Bytes equals 80bits
    % b$ z+ Q2 R/ K$ C' @
  116.             break;
    , K) c$ T; N& d8 e
  117.         }6 |  c  C- F3 o- O" e- w0 m6 ^
  118.     }
    ; i0 N, V6 f* P7 {5 c. g) Y3 _

  119. ; l  g" X9 R; n6 ~; W
  120.     return ret;, X& G* h3 C* i) C: }6 K; {! e
  121. - g* `1 G% |9 @" ~$ \
  122. }
    ( x7 m5 n" V& W8 `

  123. 3 }+ S; F1 U' t1 i) t" Q" e! j
  124. unsigned char ltc_dst_code[40][10]= {0};
    4 ^% d. c8 ]) U
  125. unsigned char ltc_dst_code_count = 0;& p) Y" S+ F7 Q: x8 k( Q: T+ y
  126. unsigned char ltc_code_valid_len=0;0 T5 o8 d( I6 a' _5 x
  127. unsigned char ltc_code[20] = {0};# @/ }2 m4 ~* o) g3 [) j; m$ n' w
  128. unsigned char raw_ready[60] = {0};
      o- A8 U4 u9 e; B: p4 J0 Z
  129. unsigned short offset_bits = 0;+ n4 x/ o% x$ E5 ~& M  i8 n5 B+ J
  130. unsigned short ltc_remain_bits = 0;
    / U: g' }( }0 c: F0 e; @
  131. unsigned char sec_ltc_code[20] = {0};/ B& Q! A  Z4 c& z8 W
  132. unsigned char ltc_dst_code_cur[10]= {0};
    : i: v4 H1 e+ u( U8 y% c$ s. U
  133. unsigned char new_frame =0;" k  R2 _" C" m! b

  134. ' h5 d7 t' F$ ^2 c8 G4 E
  135. 6 L0 y' {- H8 s! ~
  136. void parse_linear_timecode_raw()
    - g4 p, w9 R5 M4 A. @  y
  137. {
    4 d3 Z( {* y) a4 U' [
  138.     unsigned char tmp;- o0 p. ~- q. E1 A7 Z" S
  139.     unsigned char raw_mv_right_bits = 0;
    6 B9 W3 R. N0 y! m! m

  140. / L( ]3 z0 F1 B
  141.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    6 q+ t- _, v" g0 `. ?6 M7 _
  142.         isjam = 0;2 M0 N, x8 [1 M
  143.         memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));
    , |3 _! r/ l" ]$ _/ \
  144.         tmp = raw_ready[0] & 0x03;+ W( ?+ [% k8 a1 x) h, y# k/ M4 p  h
  145.         while((0 != tmp) && (3 != tmp)) {& c* s, f: ]/ Y0 u! I7 t# Z
  146.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);+ k! w; R5 ^- ]5 Y$ o4 C6 F
  147.             raw_mv_right_bits ++;. u$ W2 A% ~0 j4 K
  148.             tmp = raw_ready[0] & 0x03;
    / p# y  A2 E+ G2 S; e" m
  149.         }
    + H4 e) @' ~/ A8 z) {/ o

  150. 7 L! h9 s/ L' t) O" b9 ]+ c% a4 m& J
  151.         for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {: C* R8 ?9 {) J/ `
  152.             memset(ltc_code, 0 , sizeof(ltc_code));
      Z; P5 R  b( w1 _6 |6 e2 |- W1 R$ Q
  153.             parse_differential_manchester_code(raw_ready,  ltc_code, sizeof(ltc_code));
    # c/ t7 D& j% ^! r) U, c
  154.             //0xFCBF;
    9 r; N6 d, h+ N, g- E6 X
  155.             if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {+ A/ V, k8 {3 p1 ~6 {& X$ n7 ~
  156.                 linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;
    / L, r7 f4 }9 x# }" {  w/ B$ P
  157.                 offset_bits = raw_mv_right_bits;* W! ]/ H( Z- W  {
  158.                 break;& w" \3 t! a5 ?/ T$ n3 f; X7 j( a
  159.             }
    + ], p+ h( e$ D+ R
  160.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
    0 V. L9 T+ r, M8 [4 z. ]
  161.             raw_mv_right_bits ++;6 w- z: M) I9 g1 j8 s
  162.         }; d3 A/ s$ G% _. \8 |1 Z( g4 J

  163. . E" k1 V) s# K, |; k. c
  164.         if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    7 \0 u* B! c( G. s- K2 [3 R
  165.             LtcInput.tim_count = 0;     //reflesh tim2 period
    / V- |9 n" \, z9 d1 S3 g
  166.         }6 O: s# ^9 c7 g! h) l, H+ w

  167. : g5 v( ~) K' h; O! \9 k7 {
  168.     } else {7 K4 Q; {  I2 T" V4 N
  169.         isjam = 1;
    . p0 A4 W2 A$ z
  170.         memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));
    6 f* O& h* ?4 |# W  T4 Q
  171.         parse_differential_manchester_code(ltc_code,  ltc_dst_code_cur, sizeof(ltc_dst_code_cur));
      I+ t' ?$ K( m2 R' ]2 l, M" v
  172.         if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {; ?7 C7 z- u6 a
  173.             linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;" F$ |! o- v0 H* s! @
  174.             LtcInput.tim_count = 0;     //reflesh tim2 period
    : w1 p/ E' d9 A% U
  175.         } else {
    3 i6 ]  d+ _7 c) {+ U) K$ K
  176.             new_frame =1;/ N% R5 @. {& [4 h/ f$ m
  177.         }
    0 _/ z( W$ M) j( m2 n
  178.     }
    4 O& u& y! H/ `4 [/ ]
  179. }
    , n/ g& J- C3 b1 f4 r( b
  180. </span></span>
复制代码
, f; o" j, p) v0 C1 O; `0 ]: q% A
7 q0 y5 I' \0 i
总结以及调试过程中发现的问题。
: V- P) w1 I/ D9 O# z0 \3 S" a
, H7 z( W( p) ?! L1 U; c1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us. u% M0 {% G$ Y" S2 k  _1 M9 D
7 A) L4 Y7 J% a: Z7 ~
20201127114629167.png

  |$ ~9 m6 f$ M  G; ]. E) r+ f9 i" o: k( h( s+ s& K/ t
2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
4 [5 @( K! Z# U6 j+ V% n% X- O1 O2 g, ]( b% Q8 V
异常1, 中断回调,里面调用HAL_TIM_xxx ,  导致反复进入定时器中断," [/ Y) \9 g1 r. H9 x- \

+ @5 d( J. Q7 P) a4 A4 k: R! m5 H
20201127115308255.png
% M. {2 X- H/ O9 {, ?4 _" v5 X
" f$ L, D/ v4 R( `
异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行
' S% T2 V! ?( `
; G) x1 u( G( z- e  X$ Q. O
20201127115925296.png
5 W; H$ _" @: l/ i: U- S

. S* Y/ o# O8 R4 [解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形
( ^" N2 Y, T% m! G6 S5 `( G0 s
  1. void TIM3_IRQHandler(void)
    ' O! F: c9 P. p3 _
  2. {6 `% D+ X( [' o0 e7 d3 h1 r' u- _+ a( ?
  3.   /* USER CODE BEGIN TIM3_IRQn 0 */
    ( `& u! P5 V1 Z8 d, k
  4. - ]6 {% I" T5 r) ]9 v+ ~
  5.   /* USER CODE END TIM3_IRQn 0 */% B! Q/ p- ]. ]% ~: n7 G# i
  6.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    2 S1 z. g3 O# a. g7 h- z
  7.   htim3.Instance->SR = 0;
    4 y- Z( p8 O% B5 k6 B, V0 [' B
  8.   htim3.Instance->ARR = LtcInput.period;
    ' ^+ Q0 p: g1 r' m2 H- g7 W
  9.   htim3.Instance->CNT = 0;. F8 v8 Z" c7 a0 e; J) J+ k9 N/ j
  10.   ltc_input_timer_callback();
      f! t8 P9 R' _9 ~8 X3 C+ v

  11. 6 z* ?) W, o7 [3 @# _4 b- W
  12.   /* USER CODE END TIM3_IRQn 1 */5 C4 A- x6 O0 ?
  13. }
复制代码
- a0 Z& Y( k4 s9 H4 S
: W7 x/ f; E# E8 D
20201127120550172.png

: i6 E" D3 p) \2 @1 b) T7 k
" X* ?$ S+ x% _* W& E$ R
收藏 评论0 发布时间:2021-11-14 23:04

举报

0个回答

所属标签

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