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

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

[复制链接]
STMCU小助手 发布时间:2021-11-14 23:04
时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,
( D  p1 w  U3 ^7 I: _3 |9 {% F3 Z" x2 k
20201127093851207.png

* R( k) i% _% b- W. s) A' P# Y9 J8 o/ ]

0 A; N* o7 J. ^0 ?4 Y4 j实现原理,
! B9 K) `5 [# K9 v2 I$ G+ M, X! {6 k  O* V, W) k
1.  EXTI  Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period4 m' L  C: D, T" o( X2 ?& L

- c3 ?/ w$ \) \- G- S2.  继续用EXTI  Rising/Falling 中断+定时器方式接收时间码0101值, EXTI  Rising/Falling 中断时,修正定时器中断周期为Period/2。
2 d4 o, y2 Z2 {! X9 ]
) G: `% U6 I% M; l产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period& q! q# {/ G) ]' U% w0 L, a

& Y- k% ^8 o8 P# v9 v* v/ T3.  解析差分曼切斯特编码,查找同步码
* [$ w$ S/ y; I9 s  U5 C* d
  S/ N3 J" u& L  `  I9 o流程图,
/ L& A% T( J) w/ u  H. _% |
% u  S/ p# `1 f$ m# o! l- L
20201127113610958.png
/ a! }  e, Q6 z8 s+ L* u4 K

8 N% i8 M4 c5 S( O3 V" s# B: a! Q6 K- z6 x8 g8 m1 a2 R6 T
关键过程代码,, r. S& N  S+ z% y* u& C
! n6 }& B9 G4 I8 y& q
1. EXIT 中断处理: {( x8 T- c8 y( o/ j
! g& J  `- p( g& d' }6 C
  1. struct LtcInput_s LtcInput = {* z3 }1 Z1 W3 @# l; S! R3 S
  2.     .tim = {0},5 I* S4 g. A# A9 r
  3.     .tim_count = 0,2 d) M# a) ~$ ?$ u5 p
  4.     .period = 0xffff,; k8 I+ R+ {- a% p2 D
  5. };
    5 C+ H: b) B4 P' E

  6. 5 Q! j1 T+ N! B0 H7 f' c& b
  7. static uint16_t parse_tim_of_ltc_input_get_period(void)# H/ k$ Z% j" \' ~5 P2 i" x
  8. {3 G5 V' ^2 s5 ^  T5 B  U( D8 G, Y
  9.     for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {
    5 Y1 M6 F3 J+ a2 p2 p" w
  10.         for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {
    " c8 ~: j8 g, X  g
  11.             if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
    ) A+ G: ?% i' v9 {8 g
  12. <span style="font-style: italic;">                uint16_t tmp = LtcInput.tim;
    8 _$ s! p1 n% c" ~# V5 o/ f
  13.                 LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];4 B8 L, I" C) n$ p0 u: z
  14.                 LtcInput.tim[j] = tmp;
    ) o9 A- O# G- f! d; f( f' |
  15.             </i><span style="font-style: normal;">}
    2 p: b" Z9 @( ]+ b
  16.         }- b8 w) R* f& y0 p
  17.     }9 ^9 X2 {; `) H8 Y, d! u8 p
  18.     uint16_t period = LtcInput.tim[10];* v. r* h1 p! P2 u) L5 x9 }' h
  19.     return period;5 |9 R/ M; x7 d0 t6 `& y
  20. }
    ; H( i* x) G3 b1 G6 O4 C
  21. - D4 F' F+ m( ^) U/ ]
  22. void ltc_input_timer_restart(int period)
    , ~0 ^$ O3 g2 A9 l; h& G: j
  23. {
    1 P+ C# u8 p- p* |
  24. . ]( N( _% L2 w$ H+ w" g* u
  25.   htim3.Instance->SR = 0;  g+ G5 M$ U( p+ o3 Q) [3 M
  26. htim3.Instance->ARR = period;
    8 y' ~! p  x( [
  27. htim3.Instance->CNT = 0;# `8 j, s8 {  ~1 A% e: j# w0 b

  28. ) ?/ P# U2 n) K9 x, i
  29. }
    9 l# ~; A8 k' Z# _( _

  30. ( X9 N& t( H. X7 N8 ?
  31. void ltc_input_pin_callback(void): t$ i$ p7 F, w8 n. Y
  32. {
    4 i5 ~8 l' m1 ?$ C: N( q
  33.     // HAL_TIM_Base_Stop_IT(&htim3);
    & B, O# w1 f( {1 m6 G; q
  34.     if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {5 Q( ^3 t" w1 f; Y0 i9 S
  35.         ltc_input_timer_restart(LtcInput.period/2);
    ; V4 i1 I1 F8 s5 W- r. z
  36.     } else {8 c" T% C, M8 `6 w) k) }# N
  37.         LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;
    / |0 F) n! U( \  r
  38.         LtcInput.tim_count++;
    ( j+ B3 A, j) M
  39.         if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
    $ Z- \" X# j3 ?0 R- C
  40.             LtcInput.period = parse_tim_of_ltc_input_get_period();
    8 \* t) t. F3 S" Y( O6 Z) w
  41.         }
    6 k: C5 P* T, C$ J
  42.         ltc_input_timer_restart(0xffff);/ D5 `! c9 `0 G! t6 e
  43.     }
    7 r! I& N" h  O: E3 b
  44. }</span></span>
复制代码
. G# P# U! w+ T) \6 z
2. 定时器处理" _7 c) k2 J/ t4 V+ g( J% k
  1. /**
    6 r* S) W  j4 L' m
  2.   * @brief This function handles TIM3 global interrupt.+ a9 b% c" V5 O3 U
  3.   */* X$ I: V5 w4 C
  4. void TIM3_IRQHandler(void)
    " d/ S8 g, @4 X: W3 m$ A
  5. {
    & `* f. S* ]1 |, X: @  v& O/ T
  6.   /* USER CODE BEGIN TIM3_IRQn 0 */+ ]* C- K5 x. ]
  7. ' K5 g; D4 J. `) @7 y  c, D
  8.   /* USER CODE END TIM3_IRQn 0 */
    , p# N; d6 F: e7 I: F) l
  9.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    8 a- ~7 ~$ i2 t( W% A# S- o* V' P# C
  10.   htim3.Instance->SR = 0;
    4 T7 X! Z7 I; m" t
  11.   htim3.Instance->ARR = LtcInput.period;8 \7 b0 \6 G. {4 a" d! `
  12.   htim3.Instance->CNT = 0;
    0 ]  T3 w2 A+ Q# H( x+ B  q
  13.   ltc_input_timer_callback();
    5 K$ x4 l' |0 D0 W7 n
  14. 3 e) E$ ~5 q* |) W7 t, @
  15.   /* USER CODE END TIM3_IRQn 1 */
    % b1 }: O' ~% {5 O; D
  16. }, C) I7 S' A+ A; c( j5 h1 w5 p

  17. ! }9 P- A' T1 m) D- I( n' W! \
  18. char ltc_input_timer_callback(void)
    . b$ X6 x8 v2 u# E, \1 H
  19. {
    : [( z) B& z8 ?
  20.     GPIO_PinState status;
    . ^. }9 @/ }( ?0 \4 R% u
  21.     unsigned char x, y;3 ^; B! F$ _; L- F8 ?! k! V2 o1 [

  22. 0 p3 ?1 O; @7 v& L
  23.     status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);) b5 b- b6 x9 f0 {1 R3 U
  24.     //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);, O6 ^' v* D& n1 h* G( r) M  q
  25.     //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    # Q0 R% X& e1 J( w1 M, i
  26. 6 j/ P2 W# o+ r
  27.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);0 P2 l8 u% ]' ]9 a$ B7 |2 P
  28.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);
    ) Y4 V% e- K4 \
  29.     //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));) L+ O* @" D: k
  30. , C: q  r4 |" N
  31.     x = linear_timecode_count /8;
    & x% Y2 y9 j. T6 X/ z" P9 s6 _
  32.     y = linear_timecode_count %8;, H5 [2 g& R1 {3 A. }
  33. 2 ^5 C' ^  q1 W' p  s5 V) l4 a" x
  34.     //buf[linear_timecode_count] = status;2 A5 J% R  b/ b0 Z/ e4 E2 z
  35.     linear_timecode_raw[x] &= ~(1 << y);8 W+ V% {1 w7 r" g
  36. / Z0 |8 Z, k: T( M% w
  37.     if(status != GPIO_PIN_RESET) {
    0 {8 y( @" M8 x; H! [# o
  38.         linear_timecode_raw[x] |= (1 << y);
    . |1 }: ^  ~/ ~1 V
  39.     }
    # N  u7 C: i0 H/ B: j
  40. : M- _# @) W9 ~; k7 `
  41.     linear_timecode_count ++;
    3 p! U& [4 ^, _7 M  Y# t
  42. $ c; b" Z" d3 \+ ~0 V7 R, b5 U1 U
  43.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    1 C$ {- @* i, w! }: {
  44.         if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {, P1 S% C- b6 e4 w+ ^4 o7 a3 f
  45.             linear_timecode_count =0;
    4 M( i% M* [0 |& N4 H; k* X8 r
  46.             memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));
    & _) G1 y: T% r, ^( G6 |& C# l% S
  47.             linear_timecode_ready = 1;
      E2 i1 \' J$ {5 m
  48.         }
    ( R. ?; {4 v- X
  49.     } else {
    ; w# q& d+ L6 ~* s9 E# `" U
  50.         if(offset_bits > 0) {' s) j5 c6 }! x0 e+ ^
  51.             //skip offset_bits
    * n$ P5 U$ |0 U- y6 m. E9 U
  52.             //If offset < linear_timecode_count, adjust the offset to the next frame., x) s) }( A" M) Q  T" E/ N) w) X
  53.             //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.2 k+ z+ v+ F7 s' V" U- f
  54.             if(linear_timecode_count > offset_bits) {
    + w, h! o- G. [2 G& `" R! }
  55.                  offset_bits += 160;
    * h: n8 {/ [! K' P0 r" n# a
  56.             } else if(linear_timecode_count == offset_bits) {
    . g( ~- D' [: C7 `& W- S, A
  57.                 offset_bits = 0;/ Z- v: A9 S8 }2 w
  58.                 linear_timecode_count = 0;6 y9 x4 r) M/ T3 Z1 X
  59.             }
    % c" N1 }8 g2 M: ?' q/ V! n8 T
  60.         } else {  p9 U) ?- E! z/ S+ F- l
  61.             if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {. Q9 b5 E4 N9 h( q% j  g" P
  62.                 linear_timecode_count =0;
    + Q6 E% o: ^0 T/ J( L: A8 m" m
  63.                 memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);
    - [  X$ \! b$ o9 A- a% m
  64.                 linear_timecode_ready = 1;: |( I. Q- P4 p8 j) s
  65.             }
    8 A4 a1 {/ J, Z, `) B  X
  66.         }
    1 c  _! w& @, w0 l4 w( w4 d8 e" k  e
  67.     }
    : z: P5 i4 R, A& D
  68.     return 0;2 n' {# u: D  F# e2 E
  69. }
复制代码

( m: n$ V: ?* w: N7 _: B0 c3.  差分曼切斯特码解码
9 \$ G* T! S9 k  T. ?1 y

  1. - `2 ?  U& G, r5 A5 t% C! j% |
  2. unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
    ( }% n$ C- V3 f  V/ ~! |2 v
  3. unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
    , p: ?2 e: G) y: z

  4. / J9 t+ \5 f1 Q: P" |  |) e/ ?
  5. static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)% i4 D; n. c5 _6 o+ Q
  6. {' e( o. r7 ~: H
  7.     unsigned char i;
      P' N- b' V+ v- e* K. ^
  8.     unsigned char tmp;5 w6 _* q  k# H4 `7 f
  9. ! U( ^; l4 G+ J6 `6 O& G
  10.     if((nbits < 1) || (nbits > 7)) {
    2 @2 b0 _% Z& D, C: K: [, z
  11.         return;
    6 p% U! W  S3 V/ a7 O
  12.     }
    7 M  U" {, ?, [2 b+ Q+ i- m! v1 H
  13. 1 n  y/ f2 S# I1 G* G  h
  14.     for(i=0; i<nbytes - 1; i++) {; ^5 i: W5 j7 d) \( T
  15.         tmp = raw[i+1] & r_mask[nbits];5 L4 Y, ?7 b% B9 U8 N( u' I& @! _  u$ @
  16.         tmp <<= (8-nbits);! ~4 q( ~- L3 z, f4 y% L
  17.         raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;  ~6 e% o8 i  k6 G
  18.         raw</span><span style="font-style: normal;"> += tmp;
    : B1 m- E! ^. p' ^7 F, i4 ^& G
  19.     }' Q0 u& p  ?7 N- F# J, H
  20.     raw</span><span style="font-style: normal;"> >>= nbits;; R$ n0 u" R5 a% ]9 `
  21. }
    5 i$ z0 i5 W, z/ V+ g6 s  C4 o
  22. 3 k! y+ Y% {8 r" L! H9 X
  23. static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    / d$ X9 a  l1 V2 R6 y7 R
  24. {
    # G9 F! D+ S3 T$ M! W
  25.     unsigned char i;
    3 @  i2 A$ J7 h# V4 [4 @* R, O4 P
  26.     unsigned char tmp;2 p' U# O2 P+ a/ y5 b+ S* b  w

  27. 4 p+ ]# Q6 W7 x1 D
  28.     if((nbits < 1) || (nbits > 7)) {2 T9 }! s5 e0 z: @  t
  29.         return;
    3 A2 ^4 e3 U$ C% l; V
  30.     }
    - Y$ |2 l; |" K. _" t, Q

  31. 8 l( o& P8 J3 y0 m  i
  32.     for(i=0; i<nbytes - 1; i++) {
    : |6 U- D7 k  t7 }1 w9 {
  33.         //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;  p5 ?1 ?1 a/ k7 u0 C, M! x
  34.         tmp = raw[nbytes - i - 2] & l_mask[nbits];  g, q& T! d/ L' m5 S
  35.         raw[nbytes - i -1] <<= nbits;9 ~* Y) \9 j3 U7 B
  36.         tmp >>= (8-nbits);, A9 Z  y! K9 S) |
  37.         raw[nbytes - i -1] += tmp;
    8 `0 S. ^6 V' N9 p8 g+ @& r" C# u
  38.     }" i0 ~$ v$ |% R4 H
  39.     raw[0] <<= nbits;" i( m2 @7 }: z7 |6 P
  40. }
    , s# Y& L# N; R+ I
  41. 9 g. e" j4 k, v* `2 S( y; z
  42. static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)! o- [- j! \" S7 t! W" g' [7 N
  43. {
    - s* u" V0 V2 s3 }. G6 N1 H
  44.     unsigned char x, y;
    " |8 P, f7 p, a3 \
  45. & e% U5 @  G2 C2 ^; H0 r3 Q
  46.     x = nbits / 8;
    ' I' ~$ V0 K5 q) P+ {7 x- H5 v
  47.     y = nbits % 8;
    : ], |4 \; g6 r. N+ d
  48. $ ?6 K! C" w* s
  49.     if(x > 0) {2 z! R, H& e3 ?& C1 G( F3 q
  50.         for (int i = 0; i < nbytes ; i++) {, H9 l+ d% V& k
  51.             raw</span><span style="font-style: normal;"> = raw[x+i];/ [* V+ G2 M/ c3 }# Q  [& J
  52.         }
    ! `& C3 N' _" H! S  i" j; @& }
  53.     }2 W  Y, R- ~4 P  a
  54.     move_right_linear_timecode_raw_7bits(raw, nbytes, y);
    0 h. L0 O6 t. |; `# R4 _
  55. }7 H$ a! C' Q2 K9 [& l
  56. ) q# \. w' W/ Y! \
  57. # E, D$ O5 d  W& F+ B
  58. static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)5 a8 x" r1 k( y1 [
  59. {6 j% t# K9 d4 @) v
  60.     unsigned char x, y;6 h. c9 ~! b- c3 C) Y) I9 P

  61. . w! k1 v8 s+ _. I: I
  62.     x = nbits / 8;
    4 j/ \/ Y8 p" F' |; ^5 h
  63.     y = nbits % 8;
    / a* r8 t, f0 G( b4 d0 L
  64. 6 y. m' q) a  a
  65.     if(x > 0) {7 F. X! J7 _, w. X
  66.         for (int i = 0; i < nbytes ; i++) {) O. Q* g: [0 i: p
  67.             raw[nbytes-i-1] = raw[nbytes-i-1-x];
    # e" O3 ~4 y6 ^( I8 a. C! [' }3 \
  68.         }4 q* ^$ B6 T/ R) X9 r& P1 j3 x
  69.     }  p2 F) k' ?: F- L3 t
  70.     move_left_linear_timecode_raw_7bits(raw, nbytes, y);3 o8 ]6 p( y6 v. Z- [, x% O, s
  71. }
    / s3 d4 t" @% ^4 J. ~

  72. 1 p# h4 j4 }8 G1 n1 b0 A: ]* q
  73. unsigned char get_bit_linear_timecode_raw(unsigned char index)
    ) E" D: p# K8 W0 z) a' a% N
  74. {6 D  D$ C6 b9 g4 m* ?4 Q
  75.     unsigned char x = index/8;
    & d$ m  i4 s  O6 b
  76.     unsigned char y = index%8;. R9 Q3 ?5 u# N
  77. 9 g  K- n: ^8 u* R  n1 G
  78.     if(linear_timecode_raw[x] & (1 <<y))- o4 @0 ^+ `' n1 d  N
  79.         return 1;
    " x0 R% `$ \1 ?
  80.     else
    ' Z) O; D2 ~" M: o4 y
  81.         return 0;6 ^: L: a/ p9 S8 y
  82. }
      w: u! [* W+ \/ Q' Y% p; e( k; P
  83. 4 a1 |: L  G0 c  x7 R: u8 `
  84. static void parse_differential_manchester_code(unsigned char *src,  unsigned char *dst, unsigned char dst_size)- `5 S1 I0 R3 z/ M+ ~1 ^: @
  85. {4 u, `0 l& c7 v* B/ p) n
  86.     unsigned char i, j;
    # l1 l; f9 X# W$ S- u2 e- R
  87.     unsigned short tmp, tmp2;6 W6 ~3 ?8 s0 H  B8 k$ e1 D4 O

  88. / ?3 R% @- T4 K, f4 O7 o: `
  89.     for(i=0; i<dst_size; i++) {
    0 j) V, e8 Y' X1 o6 E

  90. 4 i8 F4 [( w1 V
  91.         tmp = (src[i*2 +1] << 8) + src[i*2];1 @5 |/ ~( u9 |% B( D$ a
  92.         dst</span><span style="font-style: normal;"> = 0;
    / K) _4 @; c/ ^0 w( n
  93.         for(j=0; j<8; j++) {
      r, D4 |/ w1 D6 W, ]+ s
  94.             tmp2 = tmp & (3 << j*2);
    & r, K" Z9 ]& N, D5 o
  95.             tmp2 >>= j*2;
    ' M! ^( c' @3 t# `; t
  96.             if((0 != tmp2) && (3 != tmp2)) {8 u2 ^9 b, j. i' F8 z3 e9 u/ l# R
  97.                 dst</span><span style="font-style: normal;"> |= (1<<j);& v# v/ B) n9 i4 V! A+ e# v8 h
  98.             }) @7 X; T( C9 [$ x1 j8 |
  99.         }7 L6 g- C6 y4 S) }
  100.     }$ e5 Q6 w* |% l) T9 C. g: }
  101. }* a1 B& Q; m' y7 J5 |% K; @

  102.   E4 O: P3 u/ j
  103. static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)2 c9 V& E4 l1 Q3 @" b+ g0 ]
  104. {: _) I8 w7 M/ a8 C/ _
  105.     const unsigned short sync_code = 0xFCBF;8 E( F4 T0 w. q; I
  106.     unsigned char i;
      m; V8 i6 `  ?
  107.     unsigned short tmp;
    ) F' i- D4 @+ Q; ]2 Y" U
  108.     char ret=-1;
    $ L/ z. T( i  c8 G

  109. # p  l2 Y  B$ `" Z7 E0 o9 y7 f8 D
  110.     for (i=0; i<len-8; i++) {
    : s6 N" s- K. j; _$ O
  111.         tmp = (src[i+8] << 8) + src[i+9];
    2 z+ B7 }( [% n) M; @/ f
  112.         if (tmp == sync_code) {8 Q+ S: j8 F* e: Q
  113.             ret =0;
    8 Y* w3 Y4 J/ S8 z
  114.             *valid_len = len - i;  M- F: I) }& H# L# E! \' J
  115.             memcpy(dst, &src</span><span style="font-style: normal;">, 10);   //10Bytes equals 80bits
    % b& H2 l+ v0 L* |0 s4 }
  116.             break;
    / n! J9 Q; @% e2 b. Q! S0 }% ?
  117.         }
    3 {* `8 U% ^5 ^7 ^7 L
  118.     }
    ! [! k3 {& `/ o0 _8 {
  119. - H" D. R- `) q! J) R( X
  120.     return ret;, I- {9 ~9 x9 Q6 Z
  121. 6 t! E  S& z# M7 x: v
  122. }
    ; S) x2 |% |1 a6 ?* j. M( t$ J

  123. % ~2 M, t3 f4 s! \. L: f
  124. unsigned char ltc_dst_code[40][10]= {0};  u3 e  s  {9 k: d, q
  125. unsigned char ltc_dst_code_count = 0;
    - I! g& b* ^, c* O& [3 o1 M
  126. unsigned char ltc_code_valid_len=0;
    : K* Q& p+ M' k6 F3 S0 G9 ]
  127. unsigned char ltc_code[20] = {0};; X/ s- I7 d$ B
  128. unsigned char raw_ready[60] = {0};
    4 k: k. [8 F) I3 M# s5 c- w
  129. unsigned short offset_bits = 0;
    & N% W0 a) H; R5 l/ p% X
  130. unsigned short ltc_remain_bits = 0;
    1 d" |5 i+ k" h6 D. K
  131. unsigned char sec_ltc_code[20] = {0};/ j. f. Z! t& Z& u' e
  132. unsigned char ltc_dst_code_cur[10]= {0};! A, A. V4 i5 d8 e2 m/ O& A0 G
  133. unsigned char new_frame =0;
    * Y( F+ Y7 ]( L1 R6 w

  134. 4 s: s' b/ k+ j

  135. / l3 _$ e' x6 S. D& ~- L! N3 ^# I% q
  136. void parse_linear_timecode_raw()& |& w4 O. T4 f
  137. {6 k3 |  {2 w" a% C6 h% ]$ _/ `
  138.     unsigned char tmp;
    ' J5 v2 f$ V$ g4 z# C) Z5 ~) g* N
  139.     unsigned char raw_mv_right_bits = 0;5 H$ Q# o) V" E; r' d% e; m
  140. ' S% q' c' \3 u
  141.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    % n; `8 M( ^5 I+ S/ j4 p. O
  142.         isjam = 0;6 J2 [9 @9 F& }& S( r% r6 e
  143.         memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));3 h" U+ k6 F2 B. |5 ]3 n" E  m
  144.         tmp = raw_ready[0] & 0x03;
    , a; m7 N: o: l4 H
  145.         while((0 != tmp) && (3 != tmp)) {# [# {1 y+ Q# w
  146.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);: E: `$ _+ `7 G. P* e  z# j; W( s
  147.             raw_mv_right_bits ++;% _, T0 F' ~! f$ d
  148.             tmp = raw_ready[0] & 0x03;
    ! L6 C3 |- _( l7 Y- T) T) o
  149.         }
    3 T5 X5 E# C6 E! r/ x( @* i, O7 ~

  150. $ E/ x) b9 @8 D( S! z
  151.         for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {2 ]& Y$ x2 P6 F$ j2 G8 z
  152.             memset(ltc_code, 0 , sizeof(ltc_code));
    7 g/ E. a, K8 R; l$ l! F
  153.             parse_differential_manchester_code(raw_ready,  ltc_code, sizeof(ltc_code));1 P  [# F: [6 w; K. y. l
  154.             //0xFCBF;
    5 j4 M8 P' W+ }0 x, I
  155.             if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {
    + f- u* @9 Z$ u: B
  156.                 linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;/ N) v  ~1 x" K
  157.                 offset_bits = raw_mv_right_bits;
    7 U8 h& r( C: J+ f& g  j7 a1 E
  158.                 break;, M+ P1 \9 h: ]( Z+ p! M
  159.             }  `2 \+ i2 e9 e6 ]
  160.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);6 x7 C+ Y5 T: J: v$ A1 f* _$ v
  161.             raw_mv_right_bits ++;. V* j# w, D8 E2 e" K/ v! z0 K& u
  162.         }0 c: y' Z( C8 X9 {

  163. 3 Q8 r$ \/ s" z4 H6 x* F0 a
  164.         if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    7 _, {% X' l, U# Q: m# b/ Y3 f  |. K
  165.             LtcInput.tim_count = 0;     //reflesh tim2 period9 s! y% H/ {, f; `2 B
  166.         }
    . _8 f5 d% b& P# _. H  u3 F  _* {. ^

  167. 4 @1 M2 h7 ]1 R( P% ]6 K
  168.     } else {9 Z8 W# B: F) F
  169.         isjam = 1;
    7 D  P4 H$ X1 W- U$ A7 A
  170.         memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));; G) B2 @; d, F8 \
  171.         parse_differential_manchester_code(ltc_code,  ltc_dst_code_cur, sizeof(ltc_dst_code_cur));* w& Z9 V1 g: F/ N* {
  172.         if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {8 G, I) L9 D8 r: P, w# G
  173.             linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;1 {; R# F( \9 s' [+ J/ W
  174.             LtcInput.tim_count = 0;     //reflesh tim2 period* X4 g6 H( G; K) z# J% D3 }
  175.         } else {
    . R2 G2 w" W# v7 q
  176.             new_frame =1;" a9 w( R8 f/ \$ [1 W
  177.         }2 w0 D1 W- J1 U: O& e" D4 E) s' L
  178.     }
    6 Q" o& B7 ^* ]" r/ b& P3 W
  179. }
    * w0 i) l4 g; S5 W: i' j6 b
  180. </span></span>
复制代码
* a, @7 J& b5 f

$ f' \: {8 E7 }( a, J8 b! P总结以及调试过程中发现的问题。
! X. u/ N! U% g6 ]% a& ]9 C
) G) K$ q7 l# Q6 D2 a4 t8 u% l  Y1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us
0 P# @. `$ Z  u& i, Y' `
3 R, ^3 t1 x# R- o# T
20201127114629167.png

* [( E& C5 c, d0 ]. S) h. P2 b4 f+ ~8 X! k
2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
0 @9 y- V6 O2 U6 V  h8 _! X2 C  _9 q; ]4 O- I+ Q* \6 }9 i
异常1, 中断回调,里面调用HAL_TIM_xxx ,  导致反复进入定时器中断,
4 ]: o& r/ s) E0 _6 h+ E! l- H; `6 u5 h% O6 Y
20201127115308255.png

& P7 l* o1 |0 A. @4 ?
8 h$ H5 D9 B" p: x+ t6 x; T异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行# X2 i" y- _: I# C0 f

" s0 j3 m# U' Y- Z$ b  t
20201127115925296.png

. y# d" ^5 H& j0 x9 }& ~0 ]0 u% x/ _: D+ ~8 ^7 O8 K  b
解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形7 f+ K- ^4 I3 A% v* I4 S
  1. void TIM3_IRQHandler(void)
    6 {- I4 t! V4 `; L5 O7 l6 Y0 G
  2. {
    5 e, @+ c; i5 s; F0 i2 T. ~5 x+ ~& P- \2 N
  3.   /* USER CODE BEGIN TIM3_IRQn 0 */2 P0 o# v$ d5 ^$ P
  4. % [0 {' J& T& l# u! p0 }, g
  5.   /* USER CODE END TIM3_IRQn 0 */; C, m2 n& s3 W5 P
  6.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);4 @6 H; p# t3 \  p  C7 {
  7.   htim3.Instance->SR = 0;7 F7 g- e8 L1 C& |
  8.   htim3.Instance->ARR = LtcInput.period;
    3 x4 t5 p% w# ]: K
  9.   htim3.Instance->CNT = 0;
    " F9 C: S3 J+ w+ S
  10.   ltc_input_timer_callback();
    * S% o8 J1 C- h2 V  I9 j/ X
  11. 4 Z7 v) h! H9 R* o* k# }( p( @' Y
  12.   /* USER CODE END TIM3_IRQn 1 */- Z' I8 e6 m% W  k; v0 ?. t0 [
  13. }
复制代码

! a, ?4 A% S3 |, x* A) `, `$ Y# ^/ ^
20201127120550172.png
$ s& @( {3 \. b$ e! z
; _$ y5 _; Q3 g! F9 [6 K7 Q. i7 _
赞 收藏 评论0 发布时间:2021-11-14 23:04

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版