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

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

[复制链接]
STMCU小助手 发布时间:2021-11-14 23:04
时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,
1 h3 @/ a7 V( F& I0 Y
4 P4 y1 [& T& Y8 ]% x* l
20201127093851207.png

4 ~5 |' o3 i9 P" z: M7 I* i( e. K7 o; [+ n' }; F% u" h
, ]. C6 S* G6 i4 Y  h4 U6 U0 t" x
实现原理,* i. C! F8 x( s& ]( q
! Q- F8 `% U; [5 t
1.  EXTI  Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period* I8 z. b- x* H7 Y1 ?

- z# N* c) a) _2.  继续用EXTI  Rising/Falling 中断+定时器方式接收时间码0101值, EXTI  Rising/Falling 中断时,修正定时器中断周期为Period/2。
3 C! j) g1 E" O' ]# a; E- G5 g0 x' t
产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period! s( P9 ~# K. B' I7 h

7 J+ Z" W% ~1 @! c2 Z2 j7 Y3.  解析差分曼切斯特编码,查找同步码
0 G4 Q) {5 m( L# L! b7 E1 k+ O/ j% N9 c( a- ?+ d/ l
流程图,
# I/ b. _* l& f! E' {! K; A
# [& p4 m7 Y3 _9 p) X7 H
20201127113610958.png
0 n, x- z8 q( R3 O0 q7 D) k
6 E& r( t6 V8 f- ~: E
- r* d+ a" O; {' R& [
关键过程代码,8 {3 [# N5 \& w( u* j5 K

) |4 Z/ ^1 ^; L1 D( z1. EXIT 中断处理( B$ F) l& p! i3 i  z6 f

: [+ K! f- K- o9 v
  1. struct LtcInput_s LtcInput = {
    ( `; S5 i. F/ @2 M) `" r
  2.     .tim = {0},& L5 O5 W$ \4 W. d" w: }5 U! q
  3.     .tim_count = 0,) I$ l( }2 A& s3 \
  4.     .period = 0xffff,8 O9 n$ Z5 f; `
  5. };- c  y# R0 E, t- a. M) P
  6. ' T/ `. \0 y6 ]2 h& N9 C; J, n
  7. static uint16_t parse_tim_of_ltc_input_get_period(void)/ L" O0 x' q1 w0 }# Q/ Q
  8. {
    & K2 z& d5 [- t% h, f/ w2 Y+ g
  9.     for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {
    2 O5 A6 m( @" w; a& f- n6 a
  10.         for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {
    ) n1 c& K) U+ C* U
  11.             if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
    . U8 E; a4 O% O' v+ X& q6 @; p. [
  12. <span style="font-style: italic;">                uint16_t tmp = LtcInput.tim;
    + @! [8 X; k4 F3 O! r/ m) T9 X
  13.                 LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];0 w+ |, e6 u: D4 ]9 M
  14.                 LtcInput.tim[j] = tmp;/ b% s7 }+ w- O  V0 h
  15.             </i><span style="font-style: normal;">}
    9 N1 E& e* H( z( y/ K
  16.         }. }2 N4 l8 [" |5 s8 ~6 e+ \, @! L
  17.     }
    ! x% W& {/ K9 i5 ?
  18.     uint16_t period = LtcInput.tim[10];
    7 V) Z6 {: t' k9 E* s1 [; t3 ~6 ^
  19.     return period;6 _/ Q/ ^: @3 n; E( Q5 Q  N
  20. }
    % v$ T; l# ^+ O# C: n( L) ?6 H
  21.   E7 O0 J: ~' b" V' e$ m
  22. void ltc_input_timer_restart(int period)% i% ]2 e, N  C0 W# k! D, r
  23. {; k1 c7 R% T2 _8 [7 t& t
  24. . S# K1 ?1 l9 P( m0 Q  u! _7 i
  25.   htim3.Instance->SR = 0;- A9 Z6 A" A; p8 E
  26. htim3.Instance->ARR = period;
    5 Y! Z) m" e9 z; }- X
  27. htim3.Instance->CNT = 0;
    # t: b" y2 Z" M: r1 E" r

  28. ! c: I) b" o9 f
  29. }
    $ ?# z1 l/ @+ x3 F4 S  V1 a. ~3 o7 r
  30. % T0 f: P9 ^. F  i1 n5 D' T
  31. void ltc_input_pin_callback(void)
    ; E# g) A& L( q
  32. {; D' t$ ^* x5 Z, l7 q6 E6 {& ?
  33.     // HAL_TIM_Base_Stop_IT(&htim3);
    $ s; M" b1 h! M
  34.     if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
    . Q0 Q+ k; k2 V$ `. w6 s! d2 D
  35.         ltc_input_timer_restart(LtcInput.period/2);$ n, a8 `( X, ?7 L5 [3 v
  36.     } else {1 G* _6 ^1 c# ^# l
  37.         LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;1 B( O6 B, B8 m, g4 j
  38.         LtcInput.tim_count++;; V( s$ y" @6 C: m* k
  39.         if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {- E# ]8 E/ \- a6 G5 a
  40.             LtcInput.period = parse_tim_of_ltc_input_get_period();  Y- P7 M4 Y% l
  41.         }$ i6 k& L0 S6 L5 w. W
  42.         ltc_input_timer_restart(0xffff);; k  z. s2 f9 T- `+ u" X
  43.     }$ f5 Z: j8 w/ ~1 N. C% E
  44. }</span></span>
复制代码
# r% U" {, h( g4 h0 b3 r
2. 定时器处理
6 N9 |+ [( O" y# o7 J
  1. /**
    + D5 D7 \) h6 L$ V
  2.   * @brief This function handles TIM3 global interrupt.
    7 \1 Q4 _- E* |% [
  3.   */. s5 P; l4 N4 m0 e; y6 ?# D
  4. void TIM3_IRQHandler(void)7 W8 b2 z% j) Q! l1 z; T& ?
  5. {
    ; V& q" G( U6 \. \" w
  6.   /* USER CODE BEGIN TIM3_IRQn 0 */
    # v5 S3 w8 R8 v- L* Z" K7 y4 M
  7. + R8 i! ]0 f2 F2 T; [' _6 `
  8.   /* USER CODE END TIM3_IRQn 0 */; X' H; E4 N: g: W3 l& s
  9.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    ( x4 I5 y2 O+ R( ^
  10.   htim3.Instance->SR = 0;+ \! H. Y' j& n
  11.   htim3.Instance->ARR = LtcInput.period;
    & M* o8 q( Z  x( u4 D
  12.   htim3.Instance->CNT = 0;. f9 H% y( E- n& e$ U
  13.   ltc_input_timer_callback();
    * b2 H; z( X; T/ O* v
  14. 9 R1 }" m5 E0 \4 `# n& V
  15.   /* USER CODE END TIM3_IRQn 1 */
    / |4 R0 [3 l. Y
  16. }
    % c4 e* ?2 }8 V% m

  17. . d1 R. `/ w) [) q1 F5 O
  18. char ltc_input_timer_callback(void)
    7 E& ~+ S8 y0 @: S% ?: ~5 p! |0 {7 [
  19. {% ^! X3 T' t& i$ l$ v
  20.     GPIO_PinState status;- c3 X0 k; C! r/ e
  21.     unsigned char x, y;7 L6 G7 i$ O/ H

  22. : A8 l/ J! f0 x6 n# S4 J
  23.     status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);+ I' o0 C' |1 C7 s7 A1 u  l) o- b
  24.     //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);4 ^9 \% p6 a7 U8 }3 ^
  25.     //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    & E' `. Z$ ?( X

  26.   s+ a2 I/ b& Z! D0 ]% u1 q) |' E, @% d1 @
  27.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);
    % p. S+ p1 v. o4 v. p# E: _
  28.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);5 S) |1 U% t1 n( e# m/ k3 v/ A
  29.     //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));
    6 `, a1 o; k1 _" s% G, S3 s. p

  30. 1 L6 r6 \' Q7 W
  31.     x = linear_timecode_count /8;
    * H5 E3 q4 n/ a  ~( Y. @
  32.     y = linear_timecode_count %8;
    ! m4 U% h5 i+ x: h- y) o, F# N
  33. # x3 v5 L$ G" T( v4 ^# f! h' U  H
  34.     //buf[linear_timecode_count] = status;. g: _0 B9 t" l
  35.     linear_timecode_raw[x] &= ~(1 << y);$ ^  g0 D" `! e  y" u* }, a. ~
  36. 7 ^/ J# J  r6 g5 g: f0 C
  37.     if(status != GPIO_PIN_RESET) {
    % d  I$ t! L* g3 Z  k$ T1 S+ |
  38.         linear_timecode_raw[x] |= (1 << y);
    3 d% s5 y/ h; ~5 N! D0 S; n
  39.     }  S6 b" f# `2 |) J) r4 A( k5 R
  40. 7 P. H* @# i7 o2 G: C' `+ K
  41.     linear_timecode_count ++;; R3 J8 m1 Q- b$ p5 M$ x5 S/ V' [

  42. 7 M1 ^, B! j6 Z& W( R
  43.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {, M- a6 `6 Z/ Z' {! t+ J/ X3 ]
  44.         if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {! B. n5 E! E& W' o. X( c1 T6 O2 S3 m
  45.             linear_timecode_count =0;+ ~( N. k4 G. r8 f- i6 S
  46.             memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));: X+ V/ H# k0 ]8 ?7 ?  K
  47.             linear_timecode_ready = 1;
      {9 m  s. o9 w: C
  48.         }3 C4 v- b# t" H5 }. {
  49.     } else {/ m1 o: J+ ]: g
  50.         if(offset_bits > 0) {! n+ J* h* ?' w' @; x) p& r
  51.             //skip offset_bits
    ) k6 W  K) U) J  L7 c- n/ @9 y
  52.             //If offset < linear_timecode_count, adjust the offset to the next frame.3 \/ s/ \; t1 D2 D% O+ F- v
  53.             //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.
    8 A% w& [: P6 N" f! H/ ~( T
  54.             if(linear_timecode_count > offset_bits) {; D% c% `7 H3 u9 L' ^- U" s( v# {
  55.                  offset_bits += 160;4 Y: |& S+ I' n5 C: T) w
  56.             } else if(linear_timecode_count == offset_bits) {" X& c8 |6 h& z, a
  57.                 offset_bits = 0;( P1 }# [2 U3 J* W: i
  58.                 linear_timecode_count = 0;3 f4 D; p0 }, B
  59.             }
    2 E) l, u7 R6 g4 k" T6 N
  60.         } else {
    & j5 R# L8 n( D! |5 b
  61.             if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {$ t* r- T1 u8 M! G+ @
  62.                 linear_timecode_count =0;5 v3 C5 K+ r5 s6 v" e3 p
  63.                 memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);
    * U6 j" Y- ~5 B0 R
  64.                 linear_timecode_ready = 1;* ]  ]' j- b+ A
  65.             }
    , _& C5 H- t8 m0 l4 E
  66.         }
    - {9 O6 p( t1 [; m% d2 _
  67.     }8 _0 W7 l6 x( d  M$ A+ v' s$ r2 j
  68.     return 0;% x# t+ {2 e# E% V
  69. }
复制代码

5 D& g( W5 J1 M  C  L3 R# W3 T6 y3.  差分曼切斯特码解码
+ E( j) J# P9 u, c" |3 |% S; T4 I

  1. 9 k5 P2 T( n- s! e* C% k
  2. unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };; N3 g, T5 l' O3 B) }. I$ {
  3. unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
    3 f3 o+ D9 K: e! a2 O! v

  4. ( t- Y7 T4 M) k3 C7 P9 T
  5. static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    5 X3 n: }) ?5 Y5 d* }
  6. {
    ; @7 N& J" ?3 g$ h) y' S9 `8 q
  7.     unsigned char i;. j/ K$ Q# P+ E0 u/ t& n. m
  8.     unsigned char tmp;
    / g: U. Z9 [# ~
  9. ; I- v' {4 I# B3 i3 f5 y- X
  10.     if((nbits < 1) || (nbits > 7)) {
    8 H9 L" B0 K1 i, W, r, ^
  11.         return;
    5 j' ?1 r2 q) x# B9 R8 P) s1 Z. j
  12.     }- {2 S7 e! d8 y0 }, H3 P

  13. 2 P  @5 q% Z+ o  F8 h/ V1 G# z
  14.     for(i=0; i<nbytes - 1; i++) {: n6 O  }) V* X9 v3 c0 f+ Z
  15.         tmp = raw[i+1] & r_mask[nbits];
    $ p& M) O% y& I7 U9 [% W+ k3 r
  16.         tmp <<= (8-nbits);
    ' b  y3 H9 a* [" {1 j8 j# Q: q3 F0 ?7 g
  17.         raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;# p8 E) ]( u+ k% O) J8 F" Y% o4 P3 f
  18.         raw</span><span style="font-style: normal;"> += tmp;, M' L& `& h8 c
  19.     }  G& U+ o5 }5 {. @: d6 r- L
  20.     raw</span><span style="font-style: normal;"> >>= nbits;/ Y; J( I: m4 P, ^4 S
  21. }2 ?- P( L4 d' u- X5 a9 f

  22. ( F; f3 L9 [* C8 n
  23. static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    4 O9 d" A9 o- {: E$ [; Z
  24. {
    4 M+ W% e2 c) i
  25.     unsigned char i;$ h  g) ~1 ]% G: K" {9 [4 I
  26.     unsigned char tmp;0 X3 {0 m3 d. y% Q4 a# ^) x4 ^3 A. l
  27. ) V% t( k% d8 @7 `# ]$ K
  28.     if((nbits < 1) || (nbits > 7)) {( i1 P6 V9 S2 w
  29.         return;8 J' H  v) I2 K+ t8 q. r7 k
  30.     }+ b) w! u+ ?& }3 o1 V, q
  31. * h& a) u( G# Z, ^* f3 V
  32.     for(i=0; i<nbytes - 1; i++) {
    0 q3 ~; N3 M9 f- X0 j" t
  33.         //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;
    # @1 z- @3 e' ~% M
  34.         tmp = raw[nbytes - i - 2] & l_mask[nbits];* O+ N5 @$ N. v3 X# c
  35.         raw[nbytes - i -1] <<= nbits;
    , \8 D8 `. }2 s$ l( Y: ]. n
  36.         tmp >>= (8-nbits);5 X: y8 ?2 a& b4 Q( @7 R
  37.         raw[nbytes - i -1] += tmp;7 z  t$ u: a7 @) c# T$ F: g
  38.     }
    ! X: A; c8 d$ N
  39.     raw[0] <<= nbits;
    / a& [7 t2 h" S
  40. }
    / F, q8 c: J# {1 r

  41. 6 I# S* @) l+ @; _1 c6 ?( U
  42. static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)# U3 C/ _4 N& R5 s5 `$ h
  43. {
    : E! m+ ^. G9 Y
  44.     unsigned char x, y;& E6 q6 g) q% ^( ~5 `/ F9 `

  45. - m+ M, k9 L( k+ ~9 I  n5 U, |% O
  46.     x = nbits / 8;: u) H4 i  Z" i
  47.     y = nbits % 8;3 J* T6 _( r3 |  f# t0 k

  48. , U- P9 a% O! ^! x  ^6 U
  49.     if(x > 0) {
    4 p* v0 K2 N. a
  50.         for (int i = 0; i < nbytes ; i++) {
    ! `. c; u/ ?2 S
  51.             raw</span><span style="font-style: normal;"> = raw[x+i];
    0 f* e& i& W3 `' I& L( `, W+ f
  52.         }
    - b: T. D5 T. Y6 ~
  53.     }
    7 q6 V7 Q* o; P. D% e8 y1 |
  54.     move_right_linear_timecode_raw_7bits(raw, nbytes, y);
    % Z& m0 I1 v5 `! {: m  M0 T  g
  55. }; K0 O; E, A9 l% g3 b! S( ~# H

  56. : d' d  M1 i) ~2 ~/ f4 _
  57. # G+ D7 T; Y7 p1 a1 |+ R8 U, U* o# S
  58. static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)  Z6 J" }- d* z; f0 n& H. N
  59. {
    : p8 ^; m7 r5 R
  60.     unsigned char x, y;
    - N1 D. r5 {8 Y
  61. # ~: P$ m, t4 w1 C9 x2 ^
  62.     x = nbits / 8;
    * W6 M) a, S, `
  63.     y = nbits % 8;* \4 {5 ^: q5 ~- @
  64. , Z6 v6 m( \, N) p
  65.     if(x > 0) {
    / E. w9 G. J1 _/ x8 E' S
  66.         for (int i = 0; i < nbytes ; i++) {
    0 a; Q: E, k! h7 j! g! M, O$ O
  67.             raw[nbytes-i-1] = raw[nbytes-i-1-x];
    * J: W4 l3 ~1 o1 C! `" E# I
  68.         }
    & W9 ?. O& r4 B9 `& v' {
  69.     }6 T0 T: G7 a/ _. h2 Z
  70.     move_left_linear_timecode_raw_7bits(raw, nbytes, y);5 m& H' l; k$ x8 ?
  71. }* M7 J7 T1 K+ D3 a0 e$ ?( K
  72. # }/ z2 p. y+ B' j+ Q" ~. G% X
  73. unsigned char get_bit_linear_timecode_raw(unsigned char index)
    6 U1 r; p( c& z9 v& C( j
  74. {( S, f) I% m6 q' j! h
  75.     unsigned char x = index/8;
    2 a: m9 h% G( ^5 j# Y3 I# ]
  76.     unsigned char y = index%8;  X* q5 X" O: d
  77. 1 p7 K& N  \! r( U# C4 o+ I
  78.     if(linear_timecode_raw[x] & (1 <<y)); f' y" K: \' ~% R. P
  79.         return 1;
    + o$ N; B1 }# a0 J
  80.     else
    0 [, a. U/ V0 \4 V; t. d
  81.         return 0;) m% H7 K& d7 f7 m
  82. }, }/ d- J, `9 i/ G1 I6 O
  83. 5 w- ~' E) y) q, t* t
  84. static void parse_differential_manchester_code(unsigned char *src,  unsigned char *dst, unsigned char dst_size)
    ; W( m' m8 a) Z: T/ b
  85. {
    7 m! U7 L3 f8 H
  86.     unsigned char i, j;, m/ n/ A6 f. J2 `% T+ h; p
  87.     unsigned short tmp, tmp2;
    " {1 A3 D: K) p+ E9 I0 b

  88. " c1 {! A; [; y1 p. z; |
  89.     for(i=0; i<dst_size; i++) {
    ' b' @: u4 k# N5 @7 x

  90. 9 }3 ?% R2 G/ X- l
  91.         tmp = (src[i*2 +1] << 8) + src[i*2];0 h0 }8 ^% L6 w4 ^; _
  92.         dst</span><span style="font-style: normal;"> = 0;
    : X" Y& d  l, k/ L. n
  93.         for(j=0; j<8; j++) {
    5 x: Q, t- i4 O9 f9 a
  94.             tmp2 = tmp & (3 << j*2);* k% o5 [, Z' D5 H# C
  95.             tmp2 >>= j*2;+ p4 r$ f! S  S: b- P# S
  96.             if((0 != tmp2) && (3 != tmp2)) {
    " ?9 ]; M2 {* A2 O3 x% H/ a  `
  97.                 dst</span><span style="font-style: normal;"> |= (1<<j);7 A1 m4 O: W4 X8 B" z) @/ ~7 j
  98.             }
    7 S' t% T' \: T0 u8 p. Z3 E
  99.         }
    2 i. B7 q! r  J5 D4 q7 r2 h
  100.     }" h  b: ~3 Q  F+ A) }
  101. }
    ; o4 k- K2 b- u! _8 G" P
  102.   B, M. D) |( R$ D, }' b( a0 P% g
  103. static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)# F6 r' m2 b# |2 Q) W8 D% H& V" y
  104. {
    3 Q% p: X5 e" \$ g
  105.     const unsigned short sync_code = 0xFCBF;( ~  \: @( V# ^1 A' b# V0 r
  106.     unsigned char i;) h- F- ^4 T( h6 n$ j- g
  107.     unsigned short tmp;
    6 o$ }0 o. c  \; P3 Z" w
  108.     char ret=-1;; p9 ]9 t, O( {9 K4 g( [, p

  109. ' T% T" \* }& B4 H5 w' F
  110.     for (i=0; i<len-8; i++) {( H& j# n9 L4 \$ U6 R& c; O3 e
  111.         tmp = (src[i+8] << 8) + src[i+9];
    $ ^1 b! |% ~; r& S" w3 r, b
  112.         if (tmp == sync_code) {
    / h+ e9 S) c4 a2 ~( F! P
  113.             ret =0;2 E6 n$ H' v# `  E  F' @
  114.             *valid_len = len - i;
    2 z7 K2 X. Z( G  q) j
  115.             memcpy(dst, &src</span><span style="font-style: normal;">, 10);   //10Bytes equals 80bits  e6 _6 J4 h5 \* [7 k- J
  116.             break;
    $ q; ~6 t) Y' z- N
  117.         }
    - ?- T$ q! a4 w. f) T. l' }# u! Z
  118.     }- U. O2 g" Q0 U5 Q- z
  119. ) s8 a2 T6 x! V2 F3 r& n# b
  120.     return ret;
    $ M! h7 G6 H. t* ^3 R

  121. ; T- Q2 M! `& w$ H
  122. }
    : `0 s" x3 r% [1 r* L6 O$ r) J
  123. , P0 R( h# T- ?, n" L7 A6 l3 A; ]
  124. unsigned char ltc_dst_code[40][10]= {0};
    : [2 Y. x' b) I$ `( H5 |  X
  125. unsigned char ltc_dst_code_count = 0;
    8 B- F0 e1 W% X+ d5 m
  126. unsigned char ltc_code_valid_len=0;
    1 _4 P* U# _/ {- O) _
  127. unsigned char ltc_code[20] = {0};
    " d3 W: H' a* E. V
  128. unsigned char raw_ready[60] = {0};7 e" F& g0 p( E# I% m
  129. unsigned short offset_bits = 0;
    ; G! @7 D0 f' r, l7 ^
  130. unsigned short ltc_remain_bits = 0;
    $ t3 w; Q& w; s& M: p
  131. unsigned char sec_ltc_code[20] = {0};
    # A$ v- {' E. r+ o; v0 z
  132. unsigned char ltc_dst_code_cur[10]= {0};  _7 F( x' M9 k8 U8 p7 ]
  133. unsigned char new_frame =0;
    % ^+ y- p$ k" d$ }) k. Z
  134. 5 b' f* _! k% K  m- f5 _+ O

  135. 9 K# E, w' w0 t8 p
  136. void parse_linear_timecode_raw()
    2 w. g3 a) J( R" b4 B
  137. {
    + u/ _8 a: l) S" K
  138.     unsigned char tmp;9 }6 d3 }" J+ O' V
  139.     unsigned char raw_mv_right_bits = 0;" X4 S6 L/ J9 e7 x1 t+ n0 E2 Q# D4 p! s
  140. $ d) _" s, A% v2 E+ d: v2 h
  141.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    9 ?4 e/ B5 W  t% L. M. O- g, _' [
  142.         isjam = 0;2 b& m8 y. @! O! }
  143.         memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));
    / C# m( {9 W0 g
  144.         tmp = raw_ready[0] & 0x03;+ N" L0 ^# I( l4 W* n) z$ }
  145.         while((0 != tmp) && (3 != tmp)) {
    2 D# P( [$ A2 O+ h$ b0 K
  146.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
      f# G( L: C4 E! [9 n; {
  147.             raw_mv_right_bits ++;
    ) e! F! G# F  k0 w" v4 g
  148.             tmp = raw_ready[0] & 0x03;
    2 u# ]7 g# c- c$ s* U% K! Q
  149.         }- T( j$ K) P/ D/ m4 h
  150. 9 x3 ?! s6 L( `8 a( w4 Z4 q
  151.         for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {
    ) O5 u: ^" S& z% V+ \6 i) Z, |
  152.             memset(ltc_code, 0 , sizeof(ltc_code));1 F, m4 n( Q/ Z' h9 b
  153.             parse_differential_manchester_code(raw_ready,  ltc_code, sizeof(ltc_code));
    8 x5 N- E/ P; W. Y& x
  154.             //0xFCBF;
    9 \3 _5 q! o5 V) J: N9 r/ }0 T
  155.             if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {; L, g. n% |* S0 E. r7 y
  156.                 linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;3 R: q% w! {" n% z8 l  Y/ Q
  157.                 offset_bits = raw_mv_right_bits;" `' b, L, v; W, E8 G) ^
  158.                 break;" p1 M* o( W' `# J# t
  159.             }7 c- z2 _" `# A. V* D
  160.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
    * a( e/ N: {, L! f) v
  161.             raw_mv_right_bits ++;: B; m. F# _4 g8 `: S* l" b/ j
  162.         }4 U4 n, n6 E/ h

  163. . q8 V" |2 o* E3 c$ |
  164.         if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {) S4 }- b1 Y; A0 l) }# F0 I# S
  165.             LtcInput.tim_count = 0;     //reflesh tim2 period: D3 \6 W; h, R- g
  166.         }; J3 @% `- y+ i$ {6 J, k' C
  167. * G& r4 r5 \- h8 _3 N* I
  168.     } else {* B( @  `5 N8 j% h. y1 J  a  i
  169.         isjam = 1;
    # Z' `5 I, F2 u1 |& E- s
  170.         memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));
    7 ?( b0 D& p5 v! J7 t; n. a# E
  171.         parse_differential_manchester_code(ltc_code,  ltc_dst_code_cur, sizeof(ltc_dst_code_cur));
    9 s, M2 b$ a$ ?; H. P7 R2 U8 @
  172.         if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {8 ~6 p) @: C2 A" j
  173.             linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;
    ) U  _3 x$ H& ^2 M  ]* J( S6 l% x
  174.             LtcInput.tim_count = 0;     //reflesh tim2 period% h; D& r+ C5 J9 ~! g! i
  175.         } else {1 |+ F* o4 o8 c) N# ~
  176.             new_frame =1;$ y7 [# H2 }: L# L
  177.         }
    0 n2 y- U  ~0 d
  178.     }
    $ B/ d3 j! W4 K. q
  179. }1 F% q/ S# h9 c3 p. |8 w  q
  180. </span></span>
复制代码
1 k  A) ~) C4 ~, \- a

3 O2 K* T1 m. B: Y总结以及调试过程中发现的问题。8 _  F% s& I- w- w/ r: C

# I2 ]. [7 {% r9 x, B$ m: b1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us7 T" n0 L. Y& X/ J9 E# m
( O* N8 q" f+ \% q, t7 W9 p
20201127114629167.png

/ a3 ^- U, {4 Z! T' H5 o3 E: H5 ?. I  D. m* @
2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
5 J1 e5 _0 w+ \" M( u! ^0 |6 }% z2 m  a! A9 Q( r
异常1, 中断回调,里面调用HAL_TIM_xxx ,  导致反复进入定时器中断,' e2 Y$ }2 h* k' y0 r6 ~, r

: D4 z: d8 e5 R1 F& h) X" A9 F2 u
20201127115308255.png
) @# a+ d# z: a: W" |

: T+ v% s( X/ T2 {2 w& M异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行
+ \8 p. Q$ h5 r8 }0 Y0 X* Y' ~; H6 {- }2 U; K! D
20201127115925296.png

, I  n/ K# y8 \) S9 w
* Z% _5 j! K1 p1 y8 K" N  `, `解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形
: R. o7 y. h0 e" w
  1. void TIM3_IRQHandler(void)/ c9 @1 T9 Q& M6 g0 S) |9 Q) U
  2. {% w# r: q! C2 c  x8 C
  3.   /* USER CODE BEGIN TIM3_IRQn 0 */9 z" V6 T2 Q: x9 k6 t
  4.   p* q. U8 P6 f8 S0 j
  5.   /* USER CODE END TIM3_IRQn 0 */( K; [7 i" T4 n" }% q" g
  6.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    - r- m* N" Y+ l- w
  7.   htim3.Instance->SR = 0;
    . T) c. z8 N7 z# h: n! `
  8.   htim3.Instance->ARR = LtcInput.period;
    * q: P& F7 y3 D) G) ?
  9.   htim3.Instance->CNT = 0;8 a+ I( e/ g) Y
  10.   ltc_input_timer_callback();
    7 X+ J/ s, h3 E" C
  11. ; t) v$ y1 U3 p$ y% Q* m% N
  12.   /* USER CODE END TIM3_IRQn 1 */
    $ R0 E8 p  f0 ?$ b' m+ k' G
  13. }
复制代码
) r* i. F+ ^+ b

0 f, s9 L4 ?. m$ ?- l. v
20201127120550172.png
$ f8 U$ T5 N* h3 S# B

( |/ r2 n7 H/ S8 z
收藏 评论0 发布时间:2021-11-14 23:04

举报

0个回答

所属标签

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