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

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

[复制链接]
STMCU小助手 发布时间:2021-11-14 23:04
时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,: S  N8 |# Z+ W- y6 n
# ]. j3 h/ t5 z8 d
20201127093851207.png

8 o3 ^" I; L5 U; p
+ B5 r, o! _3 i4 v- _
8 b: ]' b6 K" c6 }" P& x) f实现原理,+ L! F8 E" }  T* A

3 S/ r) ]0 z8 z1.  EXTI  Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period
% n+ ^' ^9 y/ S
# ^4 I8 h- O1 u2.  继续用EXTI  Rising/Falling 中断+定时器方式接收时间码0101值, EXTI  Rising/Falling 中断时,修正定时器中断周期为Period/2。
) u. F! e3 C' b' }2 ~7 }8 G4 X% S6 L0 V8 h1 i! `1 p! u
产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period
4 j) {/ e% S) `8 a# z+ c8 L6 Z0 A
3.  解析差分曼切斯特编码,查找同步码% f& N; K6 ?5 ]. p" ?( F) h$ h2 S/ Z9 j0 [
/ v& r) \0 p" `; V
流程图,: n8 g* O# Q0 f9 s& E! p
# {! \6 N- a( o, m. M1 |- c$ q
20201127113610958.png
/ u' q9 D2 Z  J6 G( U5 P2 b
7 O0 `6 A0 h) p5 o4 X: ]6 P
# ~! j; r& d/ M( e0 E$ c
关键过程代码,
8 C2 l3 }+ U2 s/ D: A0 z, x6 h  h& _5 @
1. EXIT 中断处理1 D) M# m6 \7 X$ q) F" Q+ @/ u) \3 i
/ z* S. q5 J: p; v. a0 P! i1 q
  1. struct LtcInput_s LtcInput = {
    2 H' g  y. u- `, x
  2.     .tim = {0},
    # G' N# Y/ c9 h& K0 j
  3.     .tim_count = 0,4 R8 n0 v8 P( u; Z3 q
  4.     .period = 0xffff,* y1 x1 z. U: n8 c2 h, G0 g
  5. };. F! q1 h" w* W

  6. 4 q: n: U2 F: ]- w2 g8 A, o
  7. static uint16_t parse_tim_of_ltc_input_get_period(void)
    * r8 }. S* ~7 i
  8. {
    6 r; c9 ~) ]$ ?9 ?  F5 ]: k0 s
  9.     for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {
    9 f5 Q" V( p( s! h: R. B5 }
  10.         for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {
    4 O% \" _  p2 t. _( ^
  11.             if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
    4 M5 h0 u/ G# _+ A
  12. <span style="font-style: italic;">                uint16_t tmp = LtcInput.tim;3 {* P* w* Z/ y( _2 p& R" R' t
  13.                 LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];, u3 P% x# V$ n1 h' @. D* p% C. Z
  14.                 LtcInput.tim[j] = tmp;: A5 T: H) L# s3 C4 b
  15.             </i><span style="font-style: normal;">}6 q5 y9 u8 c3 O% [- [2 L
  16.         }
    . r2 `+ Q5 P" u8 |: m! g) o
  17.     }
    # `7 ]6 y7 L$ Y3 w1 a
  18.     uint16_t period = LtcInput.tim[10];9 b% N# @6 h2 m7 V4 d
  19.     return period;
    4 W% y% Y2 k1 F
  20. }3 ~( y* N% ~; Z' G
  21. ) a# r0 [& A( _6 ?! X& l
  22. void ltc_input_timer_restart(int period)& I" e* u6 s1 g" O: s: C
  23. {
    6 H7 E  s9 Q5 v

  24. 0 b$ t' [* u) _7 h9 Z0 |
  25.   htim3.Instance->SR = 0;
    9 W) C, ~* k. I' T# K$ L1 O" Q
  26. htim3.Instance->ARR = period;
    ! f  |+ A5 l; B
  27. htim3.Instance->CNT = 0;
      v1 H! f" i; x  w

  28. % q- S& v2 {: q" i0 z5 {9 x
  29. }
    6 h& k( m$ Z3 K

  30. ! _* K( Q/ ?8 D9 e
  31. void ltc_input_pin_callback(void)* E! I" w) _2 e  `4 L
  32. {
    . u) {+ Q) ]9 }% T
  33.     // HAL_TIM_Base_Stop_IT(&htim3);
    & M; Z+ ~  x  U+ g/ K/ ^3 M
  34.     if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
    - |8 e1 ?- r  j/ w) r
  35.         ltc_input_timer_restart(LtcInput.period/2);
    # W/ n7 `* P7 y* o
  36.     } else {) s. f- O$ ?+ ]% C5 P7 B- Y8 v
  37.         LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;
    9 N$ e8 `/ m9 }( f7 J
  38.         LtcInput.tim_count++;1 Z  X5 R+ B+ v7 ~
  39.         if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {3 ^4 {& M8 r5 Z2 G/ E* M
  40.             LtcInput.period = parse_tim_of_ltc_input_get_period();- ?5 x8 |6 I* g* E& @
  41.         }
    2 _. q2 j$ T2 k, x# w" `& r/ `
  42.         ltc_input_timer_restart(0xffff);  g) i7 ]$ W3 j  u; h& U
  43.     }: a5 l' U7 n( g. T( E0 Q- L
  44. }</span></span>
复制代码
# c/ V. t- i) P' j# H0 L
2. 定时器处理
) z+ |( C  Z" f. d
  1. /**1 p. Z! h6 B4 |2 F1 R4 [
  2.   * @brief This function handles TIM3 global interrupt.1 L" t* |' H$ h5 ^. \' C* \
  3.   */& `/ S  p  R5 r+ H
  4. void TIM3_IRQHandler(void): _4 @5 _- h5 V* Q
  5. {
    ; H7 f5 T4 q  @& g# B3 ^$ r, V
  6.   /* USER CODE BEGIN TIM3_IRQn 0 */' `: ]' B  e+ S

  7. ' i1 \7 q0 |0 i0 E
  8.   /* USER CODE END TIM3_IRQn 0 */
    6 u( o# _' g/ Y6 c5 [/ G
  9.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);" [- e8 D: H' H) s1 O! F+ Q! Y
  10.   htim3.Instance->SR = 0;0 A/ y. S1 Z  Y2 P! h2 ?3 A$ J* N
  11.   htim3.Instance->ARR = LtcInput.period;
    - U7 d) ~! T  f" r
  12.   htim3.Instance->CNT = 0;6 _7 [! o/ u' _9 J  i( V6 e
  13.   ltc_input_timer_callback();9 a1 V( b' o/ D! G5 t) W

  14. ) b8 ~1 y' U& y- N' O! n
  15.   /* USER CODE END TIM3_IRQn 1 */
    - R" v* V7 d" Y
  16. }
    3 w8 t1 x* n8 _4 y; D
  17. % G) o4 J) E& N+ X: m0 v' z
  18. char ltc_input_timer_callback(void)
      r# }1 w1 r& X2 j' G
  19. {
    $ U4 Y7 |* g; n# a5 c% i
  20.     GPIO_PinState status;0 U+ }4 z( s- g* q% P
  21.     unsigned char x, y;
    . K' c( h! _. w; W  t/ h; |
  22. ! Y9 D/ F2 y6 f
  23.     status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);" Z; H1 I8 D. ~1 U
  24.     //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);+ r6 ?5 x, k% d5 f# z: w1 k
  25.     //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    & }4 y' Y: v0 ]: ~4 p  {
  26. 3 v* P9 [' S; w. w0 d" X6 i
  27.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);
      d- J6 N8 M0 A* N4 z4 ?2 i+ n& ?* T
  28.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);
    - ]" N5 B; [1 \' t
  29.     //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));; ^# K/ p- \# O+ f

  30. " K! X$ ]' o* J- G" h
  31.     x = linear_timecode_count /8;5 g, V: v7 g3 A# _& P
  32.     y = linear_timecode_count %8;
    5 a' I6 k9 R3 |# a  K; q/ S
  33. & I! B" a) N1 G% V) P1 Z# A
  34.     //buf[linear_timecode_count] = status;
    , p4 r, Y' ~0 Y5 z7 e1 ?" G% }
  35.     linear_timecode_raw[x] &= ~(1 << y);
    1 d7 T  m- L& v
  36. + X6 O2 h/ K$ m& T
  37.     if(status != GPIO_PIN_RESET) {, n. i( Z5 L/ Q0 u+ b6 b. Z' |  z
  38.         linear_timecode_raw[x] |= (1 << y);
      W8 ?# ?3 n# j7 g9 _1 L
  39.     }
    8 c+ e1 U2 N4 M8 u8 a

  40. 9 d* {6 J8 [) G
  41.     linear_timecode_count ++;
    ( I7 W9 x7 |8 r1 R8 V, g
  42. / R+ p+ Y' t2 k" U, V. C- K4 ?7 u5 u3 |
  43.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {$ m! q7 R1 c/ M6 z1 E$ Z
  44.         if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {
    : z6 K: K( a6 s' v& E7 }1 `- j2 h
  45.             linear_timecode_count =0;) f3 c- U7 O* N" d( {  {6 D3 G
  46.             memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));6 S9 _6 u. \, q2 g! ^$ L
  47.             linear_timecode_ready = 1;
    ) y4 i, h& `2 p, l, o
  48.         }# m  X/ o, x' H3 T$ k
  49.     } else {
    5 B% R4 U' {: Z9 u0 _' y# w
  50.         if(offset_bits > 0) {1 _5 t' @* s& y
  51.             //skip offset_bits
    $ l- P% u/ E& `1 [$ ]9 u
  52.             //If offset < linear_timecode_count, adjust the offset to the next frame.
    5 U! d1 }8 Y$ m$ K
  53.             //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.6 c: V* T* ^2 K3 v, W' z9 v; [
  54.             if(linear_timecode_count > offset_bits) {5 q  v7 y- `3 U9 ?5 R* l
  55.                  offset_bits += 160;
    # H' q9 l3 _& o$ a0 a
  56.             } else if(linear_timecode_count == offset_bits) {6 S9 T6 y! Q. Y( b( J8 ~
  57.                 offset_bits = 0;) b% [$ @& [7 |- `
  58.                 linear_timecode_count = 0;- j! R0 O1 ^2 `
  59.             }
    " ^8 j+ e9 o% l! F
  60.         } else {
    ! x" r! ~7 S/ P8 y& \. A+ R5 I) M
  61.             if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {
    ; d. M7 `! q- _5 ]( V+ _4 k: B4 p
  62.                 linear_timecode_count =0;
    2 [! N1 ~5 L0 q7 o0 C! j' {
  63.                 memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);0 v8 F$ I" `5 }$ ?- m+ i1 N
  64.                 linear_timecode_ready = 1;9 j+ U( p! l( D9 o* _7 z8 u
  65.             }1 n3 F/ M, ]8 H: M  q8 ?
  66.         }$ v0 A, G7 |6 P
  67.     }: q% z* o" A% ~/ Q7 i& S4 d
  68.     return 0;
    & d0 p5 ~& L) p  M
  69. }
复制代码

4 Q7 \# s5 n9 b' p6 h; g3.  差分曼切斯特码解码
1 f8 B" g' y; G. `1 ]; k0 }

  1. ' K* X- [( P. {$ {$ {
  2. unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
    - U) }  H. _- M' X* Y
  3. unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };' o3 y1 {; F- U, o- v! e
  4. * m+ M0 e$ @; t& |5 i! J
  5. static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    % |4 q6 q# J# j' {" C
  6. {
    ( B% u! v: b# }4 N& `
  7.     unsigned char i;
    + F9 S. _1 _( o) a7 v
  8.     unsigned char tmp;4 z7 W$ v% Z8 ]2 H7 U4 a" x
  9. - k9 A* S  `/ o' E: w" p
  10.     if((nbits < 1) || (nbits > 7)) {
    7 l  N2 g$ F8 J, w
  11.         return;
    0 o- a1 ]5 h: g1 E! [, i6 v( Q) ~
  12.     }
    ) t( _& j& h: a" {# g# ^+ o
  13. 0 _; m2 b- }: M$ S! R* F0 B, B
  14.     for(i=0; i<nbytes - 1; i++) {/ h7 Y% Q  F5 d: V! X( i# b
  15.         tmp = raw[i+1] & r_mask[nbits];
    7 w+ u! l; ]% ]' _* R+ L
  16.         tmp <<= (8-nbits);
    . D- L( q- n4 u/ I+ Z* m
  17.         raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;
    . O$ Q0 ~6 ~" G' [/ Y
  18.         raw</span><span style="font-style: normal;"> += tmp;
    2 Q4 Q1 ]0 n6 b, G- J. \1 i1 n  A
  19.     }
    ' R% H$ d' Z' @0 n& g. M  z, Q
  20.     raw</span><span style="font-style: normal;"> >>= nbits;
    $ e( Q, h! D9 u1 p& W/ K4 ~9 O* z
  21. }- q1 D3 `& Q/ W5 P" l, l

  22. / n4 p/ a/ U. Y3 J
  23. static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    ! t& m; w) y$ `6 k! V" \  [
  24. {
    + x4 K: B: g. N$ r6 Y5 K
  25.     unsigned char i;% g5 E- C  T! K' s+ o
  26.     unsigned char tmp;
    4 Z- o* P9 q  b3 s$ ?3 B* X6 W
  27. - F3 y$ D/ N2 C
  28.     if((nbits < 1) || (nbits > 7)) {5 y9 L! k5 Z' A  k8 \0 d7 m
  29.         return;
    : t4 a# i/ @9 J: J
  30.     }' k( \# v, J5 h& m7 d% l6 |! U
  31. ) {; ]2 B- h+ R, }  E3 ?
  32.     for(i=0; i<nbytes - 1; i++) {) \9 E' d' T  L) k7 p6 @: q
  33.         //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;( t, j9 a7 Y/ Q5 p# ]" o6 e) {  e
  34.         tmp = raw[nbytes - i - 2] & l_mask[nbits];6 }7 n6 N) I4 \, I$ r" f" }
  35.         raw[nbytes - i -1] <<= nbits;
    , R; Z8 p5 X! {1 K4 w
  36.         tmp >>= (8-nbits);9 m" |$ E0 J9 @: {
  37.         raw[nbytes - i -1] += tmp;1 }% S4 k$ F3 ?9 T$ Q! ?
  38.     }
    ; d: \1 H# Y+ b- K+ L! g
  39.     raw[0] <<= nbits;
    / C( K5 U2 U$ n9 Z( `9 K
  40. }; @/ O9 R# J  R- D) s+ O& v! f
  41. 5 f# ~9 x* ~6 w4 L+ b* R
  42. static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)5 g+ J. x1 R$ ]4 ^
  43. {2 P/ H; O8 ]. x  X  w7 b& F: F( y
  44.     unsigned char x, y;6 P/ ^! x0 p' f( r7 R
  45. / l* y" f3 g7 l7 T$ d
  46.     x = nbits / 8;
    & q) k) Y9 m8 W& ?: G( K% I
  47.     y = nbits % 8;2 C- ?+ A& |7 `7 D0 W

  48. , f" n5 _+ r% d$ L: N
  49.     if(x > 0) {
    : V. E2 q& L2 o; m/ [
  50.         for (int i = 0; i < nbytes ; i++) {
    , I) |. h; B0 K
  51.             raw</span><span style="font-style: normal;"> = raw[x+i];' ^4 p* R1 L% F/ J+ h+ V7 L
  52.         }
    $ ?7 @4 L# N# w/ w9 k9 {
  53.     }
    , @0 F0 D. L- L. q8 X4 O
  54.     move_right_linear_timecode_raw_7bits(raw, nbytes, y);
    ' b7 k% k  b' C( P- h
  55. }
    * @2 g6 ~3 D  ]# r2 {, G
  56. 4 G5 z" p7 M. q4 f
  57. 8 L$ c3 f' M8 t
  58. static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)
    $ `$ F5 D" e- ?
  59. {
    " C( L* o( y9 S' ?$ ^& P) O
  60.     unsigned char x, y;- t2 Q3 k) s- _, u& ]6 b4 W
  61. 8 ~( P# ~$ _9 K% y5 m
  62.     x = nbits / 8;
    ) v9 k6 p" e/ A6 e
  63.     y = nbits % 8;
    7 E! F$ B9 L& R# }7 H- d
  64. $ G: A. u& U. \& _$ z
  65.     if(x > 0) {1 @0 J* O! V5 \3 M
  66.         for (int i = 0; i < nbytes ; i++) {
    - ~. Z4 \4 u% ?/ B" H/ d, R8 M1 {
  67.             raw[nbytes-i-1] = raw[nbytes-i-1-x];
    ' A# X% v, e  h/ N- c
  68.         }4 L3 E  L/ `6 l9 l
  69.     }% I! n8 `- e0 O" t4 ~$ m
  70.     move_left_linear_timecode_raw_7bits(raw, nbytes, y);1 s/ o5 d# r0 w: }/ b! v( ^4 ]
  71. }+ }  M" r6 V# [  t

  72. 0 }5 I$ Z% ?$ F
  73. unsigned char get_bit_linear_timecode_raw(unsigned char index)
    / K( I4 @8 v7 R
  74. {- g( G9 {) @. O- @. s$ z9 N% u, z
  75.     unsigned char x = index/8;2 T- Z+ g! ^% O1 [# ]" u
  76.     unsigned char y = index%8;
    0 Z% v" Q0 W3 H( k0 X& j& W" }

  77. ! h. c% ^: ~/ v  ]# m
  78.     if(linear_timecode_raw[x] & (1 <<y))
    ' o3 C! N# ^  s% P6 T$ T& S3 z
  79.         return 1;
    : _. Q& S: h+ l% h! I+ ?
  80.     else
    & @% M6 P; T1 v* n! ^, s: @
  81.         return 0;
    5 L+ r9 i5 n& m- k' R, O3 H
  82. }* ^6 J$ u# J3 W9 l

  83. - m5 d- W/ [) u' I2 g
  84. static void parse_differential_manchester_code(unsigned char *src,  unsigned char *dst, unsigned char dst_size): u3 y7 H5 s5 D- v, q
  85. {3 b: G7 S2 g: W5 a9 v3 P+ U
  86.     unsigned char i, j;
    - R2 I' G0 U: a: d
  87.     unsigned short tmp, tmp2;) Y) h% M. B9 a
  88. ( F8 l3 g5 X8 J+ J, C/ B! z9 s" h
  89.     for(i=0; i<dst_size; i++) {
    7 y. G/ }" \# K0 K
  90. 3 A) r0 h4 \' _1 O! ?6 x
  91.         tmp = (src[i*2 +1] << 8) + src[i*2];/ z5 U, ^6 p' S5 {' h* z% @
  92.         dst</span><span style="font-style: normal;"> = 0;- S. [; {& t9 }& c) c' p' G; S( l: O( D
  93.         for(j=0; j<8; j++) {4 h+ ]5 ~: W) y
  94.             tmp2 = tmp & (3 << j*2);
    0 }+ M' Y* u% w$ C7 e* I8 Y1 s; J
  95.             tmp2 >>= j*2;
    * }' d" V- N1 _! X0 A: }7 @
  96.             if((0 != tmp2) && (3 != tmp2)) {
    3 n0 s5 `% D8 \# u
  97.                 dst</span><span style="font-style: normal;"> |= (1<<j);
    . Z& H2 K' J! z2 s# e, }- Q% {
  98.             }
    1 g! ]8 A5 k% G
  99.         }
    - ?, i: K" W* ?
  100.     }& O! Q. L, h3 v
  101. }9 }: Z2 n% A$ w+ Z: A& @9 `
  102. 6 f! d# r6 L8 i
  103. static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)4 N4 B' p$ N  e4 b2 f- T8 K# ]
  104. {0 p9 v, b, V( E/ v3 j
  105.     const unsigned short sync_code = 0xFCBF;) \  c1 ?0 Z5 d; {0 R2 _. l5 D
  106.     unsigned char i;
      X+ r( z9 c2 T, W
  107.     unsigned short tmp;. T8 {# B  v+ a# L3 v
  108.     char ret=-1;% ]+ e+ [5 x. [) s" w

  109. 6 F5 c, T4 m/ c
  110.     for (i=0; i<len-8; i++) {3 J* s4 n( W, @! ^5 G
  111.         tmp = (src[i+8] << 8) + src[i+9];5 I/ v7 ^! x. V" P8 J! w0 ]; U5 z+ |
  112.         if (tmp == sync_code) {+ @% U( q5 Z$ \) Q
  113.             ret =0;. P  A+ }3 L1 e1 t8 |' o# Q
  114.             *valid_len = len - i;
    * b/ u0 i. a$ J6 G  h: @9 \
  115.             memcpy(dst, &src</span><span style="font-style: normal;">, 10);   //10Bytes equals 80bits
    2 ]* d9 k0 U, z1 X0 ~
  116.             break;! U9 ~7 R! K$ x: z3 U1 I+ P  i
  117.         }
    + Y" v3 Y, h0 `& ?+ U
  118.     }8 |& L( U. Y' N) E9 `* U

  119.   K; ?; |8 K4 A3 `# w/ q& g
  120.     return ret;; _4 Q$ D. O8 m0 _
  121. $ A8 ?; a' D/ j
  122. }
    8 m3 B6 q" Y" B5 \9 R( i! _* o
  123. + n6 r/ y* F+ x
  124. unsigned char ltc_dst_code[40][10]= {0};$ y, D5 R  ^" a  H! T
  125. unsigned char ltc_dst_code_count = 0;# P. i. {; u% j/ t# ~7 `
  126. unsigned char ltc_code_valid_len=0;6 L) Y# y9 ]8 C* ]
  127. unsigned char ltc_code[20] = {0};! x8 a1 K1 O& _6 ]/ U) q; K
  128. unsigned char raw_ready[60] = {0};
    1 l+ v- {7 p# a! @* |
  129. unsigned short offset_bits = 0;
    % F! b% s' y( y, f2 W# W/ p2 T
  130. unsigned short ltc_remain_bits = 0;
    . V6 ~. d1 J; d* a
  131. unsigned char sec_ltc_code[20] = {0};
    2 d: X/ U: Q& `! x" L: N
  132. unsigned char ltc_dst_code_cur[10]= {0};
    & u! q* u: g& |0 j
  133. unsigned char new_frame =0;! x0 N; J4 Z2 _: u# z7 A4 u
  134. 7 @4 D) u0 z$ k
  135. 3 k  D( F: X# Q1 j3 ^( ~$ |
  136. void parse_linear_timecode_raw()3 i) s6 _" I) N6 t2 L
  137. {1 `8 L- n4 t3 P7 Q; S3 `+ N8 U1 m
  138.     unsigned char tmp;9 D! ^1 u, a/ f% J' s- c8 v
  139.     unsigned char raw_mv_right_bits = 0;
    + r2 ?3 R7 q( X9 y5 g/ Y3 H

  140. ! J+ z! H" `) K
  141.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {& d0 o9 ~& l, l1 e3 F& v7 I
  142.         isjam = 0;
    8 Y7 E1 Y$ {  n
  143.         memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));2 ^! a$ h8 d& v$ @9 l3 Y
  144.         tmp = raw_ready[0] & 0x03;0 s1 q5 v- f% E( e* M
  145.         while((0 != tmp) && (3 != tmp)) {& m( T* y# }; H7 n. J, u) I# L
  146.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
    6 i& [5 l- z0 F, {5 [  B
  147.             raw_mv_right_bits ++;
    2 K( G& Q- n! U/ ], x9 A2 J& s
  148.             tmp = raw_ready[0] & 0x03;  o- V: a) l  j: S% r/ e: F, N
  149.         }, g8 i0 X4 ?- l6 \% ?/ Q' x' i9 T; D

  150. 4 {6 }* n/ D, U( T# S- A- R
  151.         for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {
    & \1 v" w+ a: a
  152.             memset(ltc_code, 0 , sizeof(ltc_code));; N! F" D3 L: F+ ~9 F; {
  153.             parse_differential_manchester_code(raw_ready,  ltc_code, sizeof(ltc_code));
    / P0 p( R2 p# y
  154.             //0xFCBF;/ I2 X1 _! z' k4 a* d6 x/ {  {
  155.             if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {
    : a9 z7 `. o4 M7 |& A! W* A
  156.                 linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;
    8 h$ T+ K4 _: C5 A( n) P* s$ E
  157.                 offset_bits = raw_mv_right_bits;
    . H2 l+ W7 T( N2 A; n
  158.                 break;1 M4 O) T4 `1 |* N3 r) W
  159.             }0 @5 f% B: Q$ y' c7 z+ B* ?- Z
  160.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
    8 O- ^/ T3 a6 Z- i0 e4 n& X3 u9 z
  161.             raw_mv_right_bits ++;9 ^; h/ f0 s/ v; p) X0 C# h; H7 R6 g
  162.         }
    , h4 N6 V( I$ W8 v  [
  163. 5 b7 z- S' z' v
  164.         if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {) ?& N: i9 o$ n/ B; r/ v
  165.             LtcInput.tim_count = 0;     //reflesh tim2 period0 S2 ~5 t0 a+ V- V+ I% T/ z; e. U
  166.         }$ r8 C' \( T" |& _/ F6 Z$ D& x
  167. " m5 @( M& H, ]5 `7 _
  168.     } else {
    7 F: G! u; n$ @+ u6 N$ G- @
  169.         isjam = 1;$ }- e+ E6 g1 r0 T* V; D8 ^$ v
  170.         memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));
    ( N' D/ k* ~5 ^, y7 X
  171.         parse_differential_manchester_code(ltc_code,  ltc_dst_code_cur, sizeof(ltc_dst_code_cur));. `7 g$ @1 i$ q3 f+ Z- P
  172.         if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {
    ) A  M# s; z; s0 ^+ ~
  173.             linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;1 P; r9 @3 b7 W% Z+ Y2 Z
  174.             LtcInput.tim_count = 0;     //reflesh tim2 period
    ' m( f5 K/ F6 v' s! v; k  v
  175.         } else {1 z: {6 }) q) U  j/ w: f
  176.             new_frame =1;
    - e4 E1 @( J; U9 S/ h- J1 \
  177.         }* D$ e+ l/ y$ ^
  178.     }
    . I3 F  \5 @2 ]5 D& M  _
  179. }
    ! k5 B* G7 v% F! o0 E
  180. </span></span>
复制代码
+ O2 J/ x# U) i5 a( H# A: _
4 T/ [8 W, `( X; k0 R% r; s
总结以及调试过程中发现的问题。
- W9 b& w# q' ^
# s. a6 m5 q# I, Q1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us
* `' Z/ ?2 }/ R& Q! ~, O& R$ K' n
" v- q# K6 l2 F9 [1 d; @3 V
20201127114629167.png
7 J* y8 R3 U4 |' i  V$ w4 z5 S1 @2 }  Z
  A0 k% u1 N% M& y4 Z
2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
8 O6 ~5 R/ ~% }, l3 g3 |+ {4 J" M3 H/ h* U+ G
异常1, 中断回调,里面调用HAL_TIM_xxx ,  导致反复进入定时器中断,! w3 U- Q8 V0 v1 v- s* _" F
) ^' [# ]' K, @7 G2 ^" F
20201127115308255.png
; v# W. z6 T2 H0 R0 a5 T) H! g7 r

% N% o6 x1 E+ ~, t异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行8 l& F) U1 ~9 P/ S4 ]7 X. P+ U

5 d& |# `3 t! w; L5 C4 h! z
20201127115925296.png
/ }- Q5 v: `1 a6 R* C
' J/ s$ g' }# _
解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形
# O$ y- O6 h) J) q& B
  1. void TIM3_IRQHandler(void)" I8 J4 X) v) F7 b9 M; y- V, C
  2. {+ d1 q8 F2 K! i* c0 o( E
  3.   /* USER CODE BEGIN TIM3_IRQn 0 */7 U: Z8 O% l3 R7 d

  4. 1 z& o/ v$ _* r. E, q% c, X( j) p
  5.   /* USER CODE END TIM3_IRQn 0 */
    6 L# J2 z) q0 Y9 ~. t; N
  6.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);& g1 H, |& d! d4 k
  7.   htim3.Instance->SR = 0;) y' {4 l* c$ n
  8.   htim3.Instance->ARR = LtcInput.period;
    $ l* q. [$ J6 a6 v' r& R; ]
  9.   htim3.Instance->CNT = 0;
    " I! N5 I$ @- O! ~
  10.   ltc_input_timer_callback();7 ?. n+ t' b9 E' r' l$ H

  11. 1 {, w" M8 {, h4 Z5 M. A
  12.   /* USER CODE END TIM3_IRQn 1 */* e! {3 d3 h3 |& _3 r
  13. }
复制代码
, m1 e- Z7 @* z( ?0 g
: g6 p1 P9 |+ L+ R! x
20201127120550172.png

9 e1 g; {- d# q# ]  \6 L  C. w5 G' [0 y. Q2 b
收藏 评论0 发布时间:2021-11-14 23:04

举报

0个回答

所属标签

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