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

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

[复制链接]
STMCU小助手 发布时间:2021-11-14 23:04
时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,
; g+ `' E4 v4 }# ?; V( O: W& R8 o$ I* E2 x
20201127093851207.png
$ r4 A, F3 E5 p- \4 z0 }
+ j$ d1 B5 f, ]
8 G5 E) n4 K3 Z6 n( Y# z: [
实现原理,
- a. G' d6 R! }- `: s+ l: x+ J
, b+ ?1 z0 S8 w* }( g, N1.  EXTI  Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period
9 g. u- S/ |& S/ j2 E$ E* T
1 {/ {* u- R( g( Q2.  继续用EXTI  Rising/Falling 中断+定时器方式接收时间码0101值, EXTI  Rising/Falling 中断时,修正定时器中断周期为Period/2。% F- _  c3 m6 L1 M( e0 h' s

5 [- r2 R& r7 ^, K$ U: T* ^4 k产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period$ d# C  n3 v( P( s6 |
0 H3 d3 H- n, B( o9 Y: h) E1 E
3.  解析差分曼切斯特编码,查找同步码2 }+ \! V0 p7 `/ [( N6 {" g

( [9 G1 {8 |( |: q# ]6 o( M流程图,$ }# V. t& x! X7 Z4 u- x! h
3 W! h+ F2 x  f$ t
20201127113610958.png
1 j  @) G6 n8 m# v: c

* ]$ R+ e' [' H# {/ F% z" Z, N& ~1 P3 P# i7 i) M
关键过程代码,' n0 |) ?3 t% e* L' T4 n

& e6 k2 X: d4 U$ O% q7 H. P1. EXIT 中断处理  r0 P2 Y9 G. G* |

/ ]! Q4 n' I% x% W
  1. struct LtcInput_s LtcInput = {
      P! j# q; y4 V. b" F' R
  2.     .tim = {0},8 v! i& g5 F$ I7 p
  3.     .tim_count = 0,
    : t, Q* Y5 V* P  r
  4.     .period = 0xffff,% L  ]" l9 [- ~" p. x: b$ H
  5. };# @) k0 K. m/ }; D/ l* P. t: y0 u% h
  6. + p: v( V# e% @. F9 o
  7. static uint16_t parse_tim_of_ltc_input_get_period(void)
    % B( I3 I/ _  T6 x, U
  8. {" V/ G4 h/ h! j: H
  9.     for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {
    ' ~: N% D  l4 M; q- P% a2 S4 h
  10.         for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {: c; Z# A' p+ a- {. N; u2 @2 C& q( t
  11.             if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
    & C" h% Q8 \* k. U% @  G
  12. <span style="font-style: italic;">                uint16_t tmp = LtcInput.tim;0 w! W9 m( f/ H
  13.                 LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];' q2 o0 y) C- f) @% e" z" K; b  g
  14.                 LtcInput.tim[j] = tmp;
    2 c7 D. x' J2 i. Z  y
  15.             </i><span style="font-style: normal;">}
      w; [. H* a& N! S+ R8 f8 ^
  16.         }9 {9 k9 [. ~( t# f
  17.     }
    + x1 [# ~0 y( D6 G. C& P
  18.     uint16_t period = LtcInput.tim[10];4 N( N- Z$ p5 S) P
  19.     return period;
    $ |, M. h, z- `) J- b( G
  20. }# d# d# v- s4 ~% j" P  X
  21. 0 ^0 [/ @5 e3 D; G
  22. void ltc_input_timer_restart(int period)
    1 R$ Z! j3 x* F
  23. {
    : f) G( r; h" R; I

  24. & w8 i* k# N# f1 r, k
  25.   htim3.Instance->SR = 0;3 v- _1 R3 U" C) j6 R3 W
  26. htim3.Instance->ARR = period;
    8 r: A: \9 t3 R' g0 i6 a2 r% K
  27. htim3.Instance->CNT = 0;6 E( y; R1 ~+ |  R. G
  28.   N; m" E3 l: M/ C0 a' X% w
  29. }. d: x- x' C" D: M: e
  30. ' Y  M6 p" f% _4 V; d6 e+ Z
  31. void ltc_input_pin_callback(void)6 O2 c& [$ s4 N6 ^
  32. {
    5 O- \/ ~1 B* z
  33.     // HAL_TIM_Base_Stop_IT(&htim3);
    $ ]  i* V) x; W/ J
  34.     if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
    6 R5 ~3 ?7 y3 I# t6 b/ `$ V$ w
  35.         ltc_input_timer_restart(LtcInput.period/2);  s7 f% H( ]  T2 p; o4 ]$ v0 L
  36.     } else {9 s8 p' R8 w0 d' n) k( N- V0 O
  37.         LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;8 y4 ?1 c! ?$ f9 |: i2 ~- ^: S0 ~
  38.         LtcInput.tim_count++;. q1 [6 G9 I9 J- f, ]
  39.         if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {+ H. h$ k& i. ~5 r# }$ T
  40.             LtcInput.period = parse_tim_of_ltc_input_get_period();  I/ ^6 m/ z' l* c/ B" w
  41.         }
    3 {' `8 q! m+ k6 y! ?
  42.         ltc_input_timer_restart(0xffff);
    . `+ l7 t% [. K" B1 w5 S
  43.     }
    $ q0 N. b& b7 ~
  44. }</span></span>
复制代码
8 z+ ~# v7 A$ k- J* H& K, x! z( i1 f1 u
2. 定时器处理9 q, b. N5 l. s. S5 e7 O) x
  1. /**
    / K. o+ E# s; S6 x: v& b
  2.   * @brief This function handles TIM3 global interrupt.
    / a6 t0 X" ~' A9 u; _+ t
  3.   */
    , m6 ^& q' s+ x2 |/ U
  4. void TIM3_IRQHandler(void)" T3 A- o" ~- l/ [% @3 n4 O+ }
  5. {
    & u1 n4 d5 f' _
  6.   /* USER CODE BEGIN TIM3_IRQn 0 */
    : U! |/ d& o0 t
  7. 5 E2 q: e! I" s9 D0 `% B
  8.   /* USER CODE END TIM3_IRQn 0 */" o$ k8 Q! I8 m7 u' D& N- E' T" ~
  9.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    2 B! j7 |: c! _0 p7 C
  10.   htim3.Instance->SR = 0;
    7 m: I- C9 i7 K  x- g; l
  11.   htim3.Instance->ARR = LtcInput.period;/ a7 _% A+ C1 b3 \: `# I( y5 I, y) n
  12.   htim3.Instance->CNT = 0;2 u. \  m; `$ s0 a' F7 R
  13.   ltc_input_timer_callback();9 ]# A2 b" b# P0 M1 |3 U+ G+ l: x
  14. " a3 A( Y7 x, o# y3 n
  15.   /* USER CODE END TIM3_IRQn 1 */
    ' ^0 @3 N# g% r6 C' O: |9 V0 Z% A
  16. }" d: ^  X6 E# R, K+ B  @

  17. - t' C/ [, B8 N2 X% v
  18. char ltc_input_timer_callback(void)
    $ H8 w0 L% ]3 h, W4 e
  19. {
    - G: F% G, O3 y. S: r$ K
  20.     GPIO_PinState status;  @$ l3 J3 e# ^  O
  21.     unsigned char x, y;1 _3 I1 O; a( k) [. l4 s3 E0 ?: D
  22. ; ~! F1 {3 x* d# A8 w
  23.     status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);, w; A! y4 [5 k( U$ c, A
  24.     //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);
    1 U% m8 e# N- x- V4 |# x  O$ U2 K
  25.     //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);2 Z4 B) \, F1 t+ J& L5 P$ w; f
  26. ( t3 k( V5 X' |- |! S
  27.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);, v  m" R( F9 c2 B1 T. w$ ^
  28.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);; `3 I2 w' m. b  M# `
  29.     //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));
    + P! u* ~1 a: X4 g
  30. 0 E# ~' E; i' Z( G
  31.     x = linear_timecode_count /8;  ^/ ~7 ?3 t, M: y& o
  32.     y = linear_timecode_count %8;7 Y) g. v+ i+ C8 A

  33. ) R' Q7 W5 I  e
  34.     //buf[linear_timecode_count] = status;
    : ^$ B5 z1 n0 u
  35.     linear_timecode_raw[x] &= ~(1 << y);
    4 @/ h1 E/ a0 ]& s% L, {
  36. ) u2 G6 U' _) s- {( F2 `+ d, {
  37.     if(status != GPIO_PIN_RESET) {
    * M6 e  F1 _! ?
  38.         linear_timecode_raw[x] |= (1 << y);* r0 Z. P9 b: a6 K
  39.     }/ E! L5 V4 V" j8 Z

  40. 6 E  ~  @' {4 I) S, J, h: j
  41.     linear_timecode_count ++;
    5 z4 j4 V8 J$ f  z2 A/ |
  42. # k; t  H, o, @2 z/ o7 T5 i
  43.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    9 e" z( R6 U0 m3 k9 ~
  44.         if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {: S( D! }, Z' x: i: I( f# z5 P
  45.             linear_timecode_count =0;
    3 i2 u! g8 }8 K* `; V# g* W
  46.             memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));( N* T: [6 t7 n! D- i
  47.             linear_timecode_ready = 1;
    3 M0 e- I1 S3 N+ @3 u: ], ]8 ?# s
  48.         }
    / F% R: x7 }9 ^2 w" ^4 U
  49.     } else {& n: }$ |; V) e* _( s* `. Q
  50.         if(offset_bits > 0) {
    7 |. J! F& b2 X0 Y$ N3 h8 B3 [
  51.             //skip offset_bits
      ^3 A" z( R3 q. {
  52.             //If offset < linear_timecode_count, adjust the offset to the next frame.
    + }8 A3 j" u! n
  53.             //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.
    9 r8 K2 ]' v- }
  54.             if(linear_timecode_count > offset_bits) {
    2 S; y/ h& R( R2 M8 w" n7 Z9 L
  55.                  offset_bits += 160;
    8 S% a4 n0 R, H4 T( V: i. b2 z
  56.             } else if(linear_timecode_count == offset_bits) {8 _; m5 A3 T* ^% H. n0 x
  57.                 offset_bits = 0;2 y/ f6 `, Z2 x2 b. ]0 I5 @( `
  58.                 linear_timecode_count = 0;! C# h! a7 a) f8 k! N# h
  59.             }; S& i4 [  y6 z# c) {
  60.         } else {* B. \' J2 ~4 u( g( D8 X4 H
  61.             if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {
    2 F  {2 R4 ~/ Z8 t/ E. y- Q
  62.                 linear_timecode_count =0;
    % C, d3 w5 p* Q5 o7 f+ }0 M* J
  63.                 memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);
    $ Y/ l8 @, E' P
  64.                 linear_timecode_ready = 1;3 @! g8 Q2 v) x5 ?; ^7 X
  65.             }+ J" v6 E1 Q  p6 R+ p. c- ?
  66.         }
    + F# J( n0 f; v2 T
  67.     }
    8 N5 E9 K7 v! F
  68.     return 0;+ q# R( Z% w$ ?+ N
  69. }
复制代码
8 l( ?5 f2 R/ n) D
3.  差分曼切斯特码解码2 ]& f! j& }# s+ ?6 W/ j  [

  1. 3 L4 A; E+ b( ?* {: T
  2. unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
    8 }, r0 v/ s+ C
  3. unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
    1 q) u) e0 m4 n& Z& k# t8 @+ |

  4. / r! G; z, k% b1 O0 c
  5. static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    ; S" `# f# e" m( ?
  6. {8 P: ^  O  k2 t  J) ]8 D9 I* W
  7.     unsigned char i;
      w. l4 }9 C; ^5 M
  8.     unsigned char tmp;6 C2 r5 j! S9 O( m& P  e7 V# o0 X
  9. 7 r) o* ~- @5 M' v, L$ Y2 c6 v. R8 N
  10.     if((nbits < 1) || (nbits > 7)) {, X) `, T# ?* h6 P
  11.         return;" C, J" X$ k, s5 v7 L) T$ i
  12.     }; p  J$ P: D- I

  13. ) x* P8 X5 I- W9 p* u  H
  14.     for(i=0; i<nbytes - 1; i++) {5 B' g/ c+ {6 Y" w7 ?( b. f
  15.         tmp = raw[i+1] & r_mask[nbits];
    0 N8 [7 c, u& D, x
  16.         tmp <<= (8-nbits);
    . @$ ?  Y' u7 O7 e1 ~
  17.         raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;4 ?- c! q# m0 v, Z
  18.         raw</span><span style="font-style: normal;"> += tmp;5 B7 J' A( k; {5 J4 c5 o- K
  19.     }
    , ^3 n: a# b# _8 `) g, ~+ f) Z
  20.     raw</span><span style="font-style: normal;"> >>= nbits;
    # I* j* K( D% z5 W8 b6 m5 M2 a0 H9 c
  21. }* R: T1 [2 B* ]! ?: ]$ u

  22. $ |+ v3 |: f1 D$ @
  23. static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits): ~+ K; v/ x% c% n  \6 [
  24. {# [7 \8 `7 J" o2 M1 {
  25.     unsigned char i;
    ) d% k7 y9 o% G- i+ Z
  26.     unsigned char tmp;( |; G& |! ~3 o6 D4 ^$ q+ J4 U
  27. 5 X0 Q3 m# X* W, }0 d
  28.     if((nbits < 1) || (nbits > 7)) {
    ( r2 j/ i8 v6 I' Q% R- u
  29.         return;
    2 i0 c; m; e6 q: C: _5 `
  30.     }
    ) U& R: D: n5 g1 Q9 F
  31. : n" ~) q" P0 M- i' Y1 C& t% N
  32.     for(i=0; i<nbytes - 1; i++) {- i! E! k( Z+ V  ?# ~0 ^
  33.         //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;
    ' R3 `! o& O$ {+ i% B/ U" [- C+ _
  34.         tmp = raw[nbytes - i - 2] & l_mask[nbits];
    1 S' t& T- o- W
  35.         raw[nbytes - i -1] <<= nbits;
    1 X4 V, g- E8 F) ^& K& w9 [
  36.         tmp >>= (8-nbits);
    - h8 X# Y, N+ N
  37.         raw[nbytes - i -1] += tmp;" U: ]) {$ u5 J  P6 ?$ T- ~
  38.     }
    0 g: |1 _! ~5 z5 e* v: s! Q
  39.     raw[0] <<= nbits;/ C* k$ U, o& k3 t
  40. }
    " `4 W# T6 i6 G% i

  41. " W! X% k6 L- Q8 D- r$ q$ y
  42. static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)0 W3 E; D2 m- T) u
  43. {( V+ K3 S( q- L7 ^* v2 `
  44.     unsigned char x, y;
    2 _: e0 u1 _  N7 O

  45. 7 g; @) i/ n/ E8 X) J, A+ D  t
  46.     x = nbits / 8;0 S3 [6 M. V' D: i8 L
  47.     y = nbits % 8;
    * Y5 ^8 @' g4 g" i) V' S

  48. 2 F" W% H0 P& R0 P* S
  49.     if(x > 0) {* P8 d, H$ v8 V" f
  50.         for (int i = 0; i < nbytes ; i++) {8 \8 z, h! I# J2 o$ G
  51.             raw</span><span style="font-style: normal;"> = raw[x+i];0 m; I# g  r6 d, ?" }8 E/ X
  52.         }
    ' P/ J7 G; t. f9 h) J/ D
  53.     }
    ) C9 n5 L& A. f+ R8 j
  54.     move_right_linear_timecode_raw_7bits(raw, nbytes, y);
    & P: q: a7 o! D8 P. l, U/ k7 y
  55. }3 L( G: H& Z# E+ w: T: V5 b7 s& ?0 Q
  56. ) Q% F, W. z7 D0 }
  57. / U$ ?$ S+ [1 e5 ~2 g; H
  58. static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)7 R0 N4 z! c9 p
  59. {
    & S5 s' z# L  K8 u& c0 E
  60.     unsigned char x, y;
    ! P& y6 u: g! L
  61. " H  l5 B, B  l. B
  62.     x = nbits / 8;
    : T' O& U* x* i" e" e. x2 A' J% E
  63.     y = nbits % 8;
    * [8 O: Q- ^% X0 z+ k
  64. " B% z3 i; s7 H, q0 e& p
  65.     if(x > 0) {+ x  ?% M$ r9 f* C
  66.         for (int i = 0; i < nbytes ; i++) {
    5 g) L+ H, d7 M+ I' n  L" G
  67.             raw[nbytes-i-1] = raw[nbytes-i-1-x];1 M- t- V7 C! S7 Y- g$ Q8 A0 m/ {- {
  68.         }
    ' ]. x0 k5 W1 |# u: n2 t: Q
  69.     }9 j' ]* V# f2 i, N- M+ E9 N
  70.     move_left_linear_timecode_raw_7bits(raw, nbytes, y);
    1 h; O+ q2 c# N6 i
  71. }) j# s( q6 E0 l+ v- w5 y
  72. ! `4 p6 r/ Q, S2 w( p4 n
  73. unsigned char get_bit_linear_timecode_raw(unsigned char index)! V5 D. s! h4 H9 A
  74. {
    2 y& N6 ~& {) ]. D1 K
  75.     unsigned char x = index/8;
    5 G- ], i8 \" @, K# q4 ]+ e7 e
  76.     unsigned char y = index%8;
    5 Y# j- P& o2 w# Y: n

  77. & i: O" A5 C: X5 E5 H- z
  78.     if(linear_timecode_raw[x] & (1 <<y))+ e6 P6 z1 c9 k7 E! \# `- x
  79.         return 1;# V% X# h* i* H* T
  80.     else
    ! G( J7 G! p1 F' N. S
  81.         return 0;6 x* G+ l+ F: B# E# V* H3 ]
  82. }
    6 P& }2 o' a2 n1 k6 K

  83.   l# W# T7 J: v% X1 f
  84. static void parse_differential_manchester_code(unsigned char *src,  unsigned char *dst, unsigned char dst_size). g1 n4 S  w8 q% M. ~( A
  85. {
    $ o% j! T% P0 L6 O4 K) S# ]4 P
  86.     unsigned char i, j;
    * F9 L9 y' t; G9 n# d4 P; G
  87.     unsigned short tmp, tmp2;
    ! b( |4 n; q7 r8 t' w
  88. # ]0 H4 ]- }7 l/ Q, x
  89.     for(i=0; i<dst_size; i++) {% k: J% @  E1 S2 Z/ _6 H- ~! j7 b) B

  90. 9 [: z' m2 C0 o; V2 d
  91.         tmp = (src[i*2 +1] << 8) + src[i*2];
    " K0 Q" O  f. B4 G
  92.         dst</span><span style="font-style: normal;"> = 0;
      l. X5 c/ z9 J! P2 [  B
  93.         for(j=0; j<8; j++) {. L: r4 V  y0 H- o! X$ L. l
  94.             tmp2 = tmp & (3 << j*2);
      {8 b3 ]) i9 u9 g/ r
  95.             tmp2 >>= j*2;4 R2 u: A0 c# D& M* @8 C8 v
  96.             if((0 != tmp2) && (3 != tmp2)) {
    5 U; T7 y9 w0 v' j& Z# X
  97.                 dst</span><span style="font-style: normal;"> |= (1<<j);: j: m3 j7 y# ?+ }" g: F6 ^
  98.             }
    . l! a' @4 D" J
  99.         }' x" ?) t' G8 M+ H6 M7 {3 b$ z
  100.     }
    * o+ P7 D3 u; L
  101. }3 w$ r; c: E3 Y

  102. 2 _$ q6 T/ {5 H. _6 R8 I: C1 p  ]
  103. static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)
    4 f1 f7 i/ e9 d: j. O+ S: I" u
  104. {
    # ]; Y5 y" W, Q
  105.     const unsigned short sync_code = 0xFCBF;) h* s+ D/ D9 n4 \4 e
  106.     unsigned char i;, R  `3 X0 u- W7 e9 C! O9 f) C
  107.     unsigned short tmp;
    ) Y5 |' s& }- x8 g. P6 o/ @) P
  108.     char ret=-1;
    . s6 l5 C0 m: N- u: w8 T. R

  109. 1 u; X; ?- N3 X: q6 {0 w" n' [
  110.     for (i=0; i<len-8; i++) {
    + m- C3 j$ Q" N5 {  D& N( ?
  111.         tmp = (src[i+8] << 8) + src[i+9];
    - p9 T: q; @: ~2 P
  112.         if (tmp == sync_code) {; q1 T! o6 r0 t; B+ Z. J& ^
  113.             ret =0;
    ! |. V6 T. }/ q; T' C  I# K5 @6 ?
  114.             *valid_len = len - i;) E$ t8 \1 u6 }8 c# B
  115.             memcpy(dst, &src</span><span style="font-style: normal;">, 10);   //10Bytes equals 80bits
    % I# L! h% T3 i& [4 V9 a
  116.             break;5 d! M( ?0 ~$ @* v5 q2 m" O
  117.         }
    ! ?; S5 N+ r" r5 \% |
  118.     }
    6 h7 n  T& T# }' X% H

  119. - p0 g. O) p( c
  120.     return ret;
    7 c0 r1 P6 |  C" s% W

  121. 4 b, I, J, \% n
  122. }
    5 ?( D! x2 S5 M7 t. T  q" ?
  123. * m( N$ h/ `* [$ s8 x" b7 s
  124. unsigned char ltc_dst_code[40][10]= {0};! c% n7 T: o! x, b% @- d) c
  125. unsigned char ltc_dst_code_count = 0;
    2 F3 N2 \% c# @1 Y6 B8 J1 c/ _
  126. unsigned char ltc_code_valid_len=0;
    ; \% ~5 t( t. ]  t- T" ]
  127. unsigned char ltc_code[20] = {0};6 P* q: q3 o( Y
  128. unsigned char raw_ready[60] = {0};: R$ o" x% R) y$ y& V
  129. unsigned short offset_bits = 0;: N% O' q5 y  U! E8 t* R  n7 H  w) o
  130. unsigned short ltc_remain_bits = 0;2 S6 J/ b5 i* |+ ?1 d
  131. unsigned char sec_ltc_code[20] = {0};6 r" g+ T0 [. B% ^3 m' ]8 H
  132. unsigned char ltc_dst_code_cur[10]= {0};/ D# A% |& b5 P3 t1 F: L: w1 r1 M
  133. unsigned char new_frame =0;  ?' l( p7 m' p9 h9 p% B7 D

  134. ' {( [7 w  P. o% u0 n
  135. . Z& w- G2 c7 `% P( \5 A, V
  136. void parse_linear_timecode_raw(); u' S3 [& b: H: b% m2 C0 B6 F& _
  137. {
    & S7 X8 ?$ _! @4 r+ ^6 w, r1 k  f
  138.     unsigned char tmp;+ v; Z& `' S6 h6 B1 U6 l
  139.     unsigned char raw_mv_right_bits = 0;9 W. A7 n. k1 Y' U8 f

  140. : u; H6 ]# j2 u4 W4 x
  141.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    * v8 q& ~$ q" i  b/ _
  142.         isjam = 0;
    5 ~3 r2 j' |  C0 p' Y
  143.         memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));
    6 n9 Y1 {- W' S
  144.         tmp = raw_ready[0] & 0x03;
    : y$ h, o7 F' q! r* L
  145.         while((0 != tmp) && (3 != tmp)) {1 Z& Z/ @1 h0 O% v: p$ V1 e6 [
  146.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
    , \' L0 J- ^6 l. o, X
  147.             raw_mv_right_bits ++;
    ( E4 [+ }- i3 {. {
  148.             tmp = raw_ready[0] & 0x03;4 T, B- `6 h- ?9 W
  149.         }& A1 c3 c, P& X- {( i

  150. 4 m2 S0 P' z4 J; d5 N  L
  151.         for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {
    / G2 j; F7 j. ?4 {1 S1 F
  152.             memset(ltc_code, 0 , sizeof(ltc_code));- Y2 Y* }9 L/ h
  153.             parse_differential_manchester_code(raw_ready,  ltc_code, sizeof(ltc_code));
    , L: d0 s* y) |0 v
  154.             //0xFCBF;
    / C) k- U: ]0 c' C
  155.             if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {
    " l8 ?* Y  v3 z  K% ^' z. o% o5 B1 w: t
  156.                 linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;& c/ ~! |# v; C+ W; i
  157.                 offset_bits = raw_mv_right_bits;
    8 \  Z' _4 @8 D2 J3 ~, B9 a
  158.                 break;& l3 U+ a4 h' F! k3 Z
  159.             }
    . o7 k1 v* k* B8 n* g" c" n
  160.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);9 T0 `( A( b# m$ p5 `% @9 @
  161.             raw_mv_right_bits ++;
      e: h: B  [0 }% ]8 ]" u" q
  162.         }8 B% q6 o- j% v+ m

  163.   ~) b1 N4 {5 I4 k" E) M" b
  164.         if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {; I9 y; z- ?& |, `! z$ b  z8 C6 I
  165.             LtcInput.tim_count = 0;     //reflesh tim2 period
    5 m( z! X, c4 l: ]& I
  166.         }" y: \) S# A: I5 \$ V+ E
  167. $ [9 ^% i4 q& h8 p
  168.     } else {) y# O3 n# t, m" E& P1 k
  169.         isjam = 1;
    , a+ T1 N! u, \# S
  170.         memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));+ W+ q3 d4 i1 i6 h6 ^, J2 G7 w2 |
  171.         parse_differential_manchester_code(ltc_code,  ltc_dst_code_cur, sizeof(ltc_dst_code_cur));
    ! h9 ]' ]/ c( ?5 G0 j
  172.         if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {( z! p! N( L2 |) B# }5 t
  173.             linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;( x6 B/ [3 t( W/ x
  174.             LtcInput.tim_count = 0;     //reflesh tim2 period
    4 H# N+ p5 m* y1 J* l
  175.         } else {
    2 Z, }& N, h  d. e0 L( D$ \
  176.             new_frame =1;
    # A$ N7 H) d0 m# m8 y* F0 n- G
  177.         }
    " m# }/ N. k$ Z9 T4 T
  178.     }
    4 r5 o1 k1 r( X3 @* \+ |3 \
  179. }
    * c! `# L# N( D
  180. </span></span>
复制代码

! n8 E( I* m4 Q2 p
" U+ y# v9 c7 k* a! S总结以及调试过程中发现的问题。
. }' I( U! L0 o! X- ]2 U$ I& ^8 Z9 `9 H$ s6 T
1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us$ U6 k6 \8 k5 n8 U# G3 U; H& U& ~! D

1 R: j, x3 f8 K7 D: y. S- R- n6 f0 v
20201127114629167.png

) y' q. q" t# N( Q* h: K- p- @; y# c$ H# ^1 W9 s: a- ?5 e' g# @
2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
0 H' b+ D8 d! T$ }# [4 P' F# U* \$ f' ]3 F$ D, K. |8 R
异常1, 中断回调,里面调用HAL_TIM_xxx ,  导致反复进入定时器中断,
4 I  D) d* X1 f4 k, x( d: L  N# U; ^. m* ~( A, L
20201127115308255.png
. t4 `$ Q- U% _/ I2 F9 G8 Q9 K

2 @3 w  m2 @% {4 f% O异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行
; Q- \+ g, u, }4 R6 H* o/ D2 I& F; p: R
20201127115925296.png

8 i, r* v' L6 @. k, u( |- }3 J. l/ |9 w/ @
解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形: u3 w" c4 x9 X3 z4 }5 ~
  1. void TIM3_IRQHandler(void)
    , X5 n: D+ ?$ N/ ^# O5 f/ q, u
  2. {
    ; l6 \* M- }+ [% w
  3.   /* USER CODE BEGIN TIM3_IRQn 0 */
    4 u3 C# n; m9 v2 U

  4. 4 }# `* }. X  n5 |0 [* Q# b
  5.   /* USER CODE END TIM3_IRQn 0 */9 u* Z4 U6 d. a7 N6 `0 e- C0 W
  6.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    : }& q" d4 V7 |) W7 ^' a9 g) {
  7.   htim3.Instance->SR = 0;* s# o. l) O2 t! y9 Y0 b7 W
  8.   htim3.Instance->ARR = LtcInput.period;3 i8 k( W0 J+ x8 z( l! [
  9.   htim3.Instance->CNT = 0;
    1 v  [& z( q# C$ x; w1 r4 W/ _
  10.   ltc_input_timer_callback();9 w. o: H; p& x# ~  k2 Q
  11. $ [3 [; v  F, u" ?
  12.   /* USER CODE END TIM3_IRQn 1 */
    & O& L& o% f& n* R7 b9 f9 b
  13. }
复制代码

. Y; w# H* n  S, s* s$ M
1 f$ E" @/ T3 D
20201127120550172.png
8 s( F% C4 f) X4 a; Q* l6 U
4 A! v, l) h5 J( z
收藏 评论0 发布时间:2021-11-14 23:04

举报

0个回答

所属标签

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