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

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

[复制链接]
STMCU小助手 发布时间:2021-11-14 23:04
时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,9 J  V! M5 T9 ^$ v( G
6 p% _" v8 V* C# e
20201127093851207.png
' ?$ ~' U. Y2 L) x; ]# _. f

4 Z" h( w" p4 X, |) K2 L- \6 q# N
实现原理,
) H/ _9 U5 ?( s" k& X; t4 ~; W1 Y9 z  G
1.  EXTI  Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period
% Y2 J' d+ P! ^8 S0 ]3 h6 n  O: z* {8 B6 Q6 C& g# ]/ ~
2.  继续用EXTI  Rising/Falling 中断+定时器方式接收时间码0101值, EXTI  Rising/Falling 中断时,修正定时器中断周期为Period/2。
7 ]/ e9 ~: c/ m" F4 b" ~- q, w2 J. t3 \
产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period7 Z  N& h/ J2 c
, `! h9 E( r& k' [
3.  解析差分曼切斯特编码,查找同步码, {" d( s; k4 v

+ l' V: B8 W* ?+ |. Y流程图,4 b% A, I1 R2 \# }, p

& q0 M5 F- q- n  p! F* D
20201127113610958.png

; e% Y% Z* T9 P7 P5 {
* e  ~1 ?# x, y! f
% R) q# E! e9 ^8 S& A$ }关键过程代码,
8 o( k0 w% l$ }1 J1 \: e( e+ A
. x" h$ r$ Z% }' R' t1. EXIT 中断处理5 O& j& c/ a' J* W& y) v3 X% J
) o+ t( I/ p! L, }" V) _8 H
  1. struct LtcInput_s LtcInput = {
    " D  ?8 }2 L' B' `) p! n0 K& r
  2.     .tim = {0},
    # g& A8 d* u8 y- h
  3.     .tim_count = 0,
    * ~. W. k* d8 c8 e% F: A' ?# X
  4.     .period = 0xffff,
    8 T6 a  i- M+ _! M6 u! ]
  5. };5 r% q2 p0 a) u8 }: w
  6. 4 S0 I% M6 P3 {+ |
  7. static uint16_t parse_tim_of_ltc_input_get_period(void)- k; Y0 o6 t8 f5 ^
  8. {3 V; q" W2 d% Y4 u+ q4 P+ a
  9.     for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {- [% E" G1 @4 J
  10.         for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {
    1 W& z9 S" b3 h
  11.             if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>4 N* s; e- I# _# }6 P7 I8 M& ~# Y
  12. <span style="font-style: italic;">                uint16_t tmp = LtcInput.tim;
    ) S* H" F( N1 F
  13.                 LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];, K( \' P. _, O" J; R( y2 m
  14.                 LtcInput.tim[j] = tmp;2 O' H, p( K# ^& I9 g) h' n% P
  15.             </i><span style="font-style: normal;">}  V5 p8 D6 C6 \9 S/ ?9 W
  16.         }* R7 P- r' ]& ]. b
  17.     }$ z* _5 b1 _! D. v
  18.     uint16_t period = LtcInput.tim[10];
    9 J% O. Q. v1 n6 F! R* H0 I+ u
  19.     return period;
    7 B2 H! ]  P) M, m% D
  20. }
    , K" e* {4 l- X; `/ n0 h# R, J: @4 o
  21. 8 v7 _# {1 Z( r% Q3 V$ R4 M
  22. void ltc_input_timer_restart(int period)
    - S# x: R! z: `5 l% F0 \5 @9 m
  23. {
    $ f9 l0 Y' ^' |5 f3 W- a% H

  24. , u: y1 `9 v% L6 E3 t5 e1 j
  25.   htim3.Instance->SR = 0;8 `0 @3 S: [" }
  26. htim3.Instance->ARR = period;
    6 m3 z6 q% n& a8 g
  27. htim3.Instance->CNT = 0;1 o4 R9 `3 ~) R' _
  28. ! h$ q0 i; k5 c1 {2 g1 o6 }
  29. }6 D: n: V5 ~9 O. X
  30. & f* H; ^% `8 w2 H$ |3 [
  31. void ltc_input_pin_callback(void)
      c- P4 R; w3 G; l& [
  32. {* k# g+ y' t# s
  33.     // HAL_TIM_Base_Stop_IT(&htim3);
    . e9 |; g% i0 g% J/ ?3 K9 m' {3 E
  34.     if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
    1 U* p8 m' T- D7 e% L& |2 \8 s
  35.         ltc_input_timer_restart(LtcInput.period/2);+ p+ s4 I# u+ x- R
  36.     } else {  W8 F9 x$ u" `
  37.         LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;1 ^5 I$ t, g) b7 k  ^) Z
  38.         LtcInput.tim_count++;
    0 f7 @8 j! J) ?/ C
  39.         if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
    - B9 `* p! J+ u& V' H! u
  40.             LtcInput.period = parse_tim_of_ltc_input_get_period();
    ' Q! O- M. c! n6 @2 D
  41.         }
    ) c  h3 I" G3 V3 C
  42.         ltc_input_timer_restart(0xffff);
    # o* f' v( v5 O* A; w
  43.     }3 |5 I2 C! {1 c- B3 s0 Y
  44. }</span></span>
复制代码

2 J9 Z+ v; L  Z2. 定时器处理& _) u6 ]2 c1 k6 T( }' u
  1. /**
    * S$ B) _, u' F2 b+ i: y% M
  2.   * @brief This function handles TIM3 global interrupt.' e6 V9 W; x2 M+ ~5 u4 p
  3.   */( K, r3 h& r" W- e: \
  4. void TIM3_IRQHandler(void)
      T- h% O, r% D7 ~4 {( J
  5. {1 z0 a/ k$ c9 I. \! c7 G
  6.   /* USER CODE BEGIN TIM3_IRQn 0 */) y1 U7 w' n& Z
  7. : s% V7 ?0 M7 A4 O0 q8 ]! d( f1 ^
  8.   /* USER CODE END TIM3_IRQn 0 */3 f( M& f" U% j2 C- L3 O4 y
  9.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);8 d9 m6 Y3 f2 a7 |. p4 @4 \9 {" m4 h
  10.   htim3.Instance->SR = 0;8 D, `& g" h! b# U% r+ ~
  11.   htim3.Instance->ARR = LtcInput.period;
    8 z, d5 [% k- k) z- d' }: s
  12.   htim3.Instance->CNT = 0;7 q/ Y' A+ F! v' r
  13.   ltc_input_timer_callback();/ R* \  I- j5 K
  14. 8 w3 {. g3 ~& z4 I4 Z+ j
  15.   /* USER CODE END TIM3_IRQn 1 */
    0 A, {: e' R9 }2 _4 d
  16. }) j4 x/ a# B' L$ s- s; a2 [

  17. . y; T9 n: n4 q+ ^- O
  18. char ltc_input_timer_callback(void)
    . d& K6 t1 M& \& I; D2 ^
  19. {
    $ ^" p; X) _% Y" |% G% T- N- d6 D) d
  20.     GPIO_PinState status;; T( }7 N% v! x$ b9 M3 t# w' b: ?
  21.     unsigned char x, y;( K7 k7 T+ x) z; X, c1 J4 J2 U
  22. % y6 X8 K* g0 ^& I, ]$ g
  23.     status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);3 y# J; p/ j: n* c
  24.     //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);
    ( f7 A" I1 \1 g! q/ W
  25.     //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);" D$ q# g( u' x- l$ a- i. M8 A

  26. 7 D7 Y5 T$ F% c4 P0 ?  o
  27.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);7 p3 b0 I& A5 ~7 o7 _( m3 [/ s" j' x
  28.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);8 k7 Q( q  ]  m: p9 G. G( a- P7 u/ R
  29.     //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));& ~* I0 G1 B( ~% r  X) |5 ^
  30. 1 s5 f  D6 {+ m+ b
  31.     x = linear_timecode_count /8;
    * G2 i- A; f# x4 p( y8 n
  32.     y = linear_timecode_count %8;4 @# ]1 n% p3 ?- ]

  33. , ]* @; m3 U% q- l- X' F% V
  34.     //buf[linear_timecode_count] = status;2 N3 A0 ]2 H( f* P% S$ ]
  35.     linear_timecode_raw[x] &= ~(1 << y);
    ) d4 p# d- t1 o, K
  36. * G% R" F( y+ `$ V4 g7 Q/ m; U2 ^$ U
  37.     if(status != GPIO_PIN_RESET) {
    ( U0 W/ a% \) S! |
  38.         linear_timecode_raw[x] |= (1 << y);5 J( `4 h, V) r; k0 K7 q& j
  39.     }
    1 P/ s& J  h& i6 k* |
  40. $ _2 S5 O, a( R3 O: ]
  41.     linear_timecode_count ++;! S! S( R$ }6 `" ~
  42. 5 J- o3 @( D9 ^9 i# g' q: h: M
  43.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {$ I# O. P. v' x# V+ }+ \
  44.         if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {
    $ j: X/ @4 ?. E; P: N0 S
  45.             linear_timecode_count =0;
    7 _& I5 F1 i1 |2 f; G1 F. |
  46.             memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));* D1 n- e6 _' s3 M/ v* f( ?5 w
  47.             linear_timecode_ready = 1;- Z* ?8 m( S; F- B/ j
  48.         }4 Q; j5 h" Q& t" I
  49.     } else {! H: D- s/ u6 ?5 |' ~8 N: T
  50.         if(offset_bits > 0) {. y) H' O: K$ E# u2 ~# N! ]6 ?# q% f
  51.             //skip offset_bits4 s" T) {8 \2 z$ j# V) ]
  52.             //If offset < linear_timecode_count, adjust the offset to the next frame.1 M  [0 e! V! G3 R- X3 Z( i
  53.             //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.6 k! R5 I& v& v) F5 W
  54.             if(linear_timecode_count > offset_bits) {
    9 i: y8 M  t' g) `
  55.                  offset_bits += 160;: n+ _' h% x) {" J
  56.             } else if(linear_timecode_count == offset_bits) {- @6 v9 D' L, k% n$ w& |6 h
  57.                 offset_bits = 0;4 T) v: I8 a7 Q
  58.                 linear_timecode_count = 0;
    7 ^* B: E' p3 O; g
  59.             }
    ; y7 M4 ]3 @. S1 P/ u$ a/ b0 C* q
  60.         } else {
    - R6 J$ ^( ?+ s1 U! ~0 l
  61.             if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {0 I" F: t' o$ z: B/ x
  62.                 linear_timecode_count =0;
    , O/ Q9 J8 `- B+ O! Q
  63.                 memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);
    3 n- s# h$ t+ E' T9 [& B. p7 F9 g
  64.                 linear_timecode_ready = 1;# t2 }# E- Y6 q8 j; Q0 k. D
  65.             }
    # z6 B3 \( F8 R6 n
  66.         }
    " }% o: V  C- E% [
  67.     }
    : V! N+ x2 N. d
  68.     return 0;% \# i" L, y# X3 ~0 z- f) h& v7 M
  69. }
复制代码

* U* G2 `1 j- Z3.  差分曼切斯特码解码
6 S# [3 e6 s( }) u: u
  1. 6 m+ j! R+ N) r8 s( Q: F3 U
  2. unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
    7 k& z2 u$ F0 t6 J$ x  y7 X4 W
  3. unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };! E. R" K. U4 e! L( v. w, U5 B: k9 d

  4. / _% z7 z) S1 D" |
  5. static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    3 g! A0 Z+ a  Q
  6. {
    ; O* y: d; \+ H! l2 F9 X
  7.     unsigned char i;3 v5 c8 J/ N1 J9 I
  8.     unsigned char tmp;9 P( w6 N1 t' m. w# r* j
  9. : H4 ^4 k0 H$ {, o
  10.     if((nbits < 1) || (nbits > 7)) {$ B( R. A" n0 Z9 I
  11.         return;
    , i6 |1 n( n1 O6 k
  12.     }
    + Y# N9 f: ^' f+ F4 ]! J: v7 r; V( o" X
  13. * t6 x3 K5 [+ [+ d9 n/ ]8 g4 f
  14.     for(i=0; i<nbytes - 1; i++) {8 x4 z) b, P: ]$ r
  15.         tmp = raw[i+1] & r_mask[nbits];; P! b& V0 L6 J2 E8 [; @! S
  16.         tmp <<= (8-nbits);
    * M8 M8 Q% i" u# c
  17.         raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;
    + Z5 N/ ~5 D4 I' G4 v+ x
  18.         raw</span><span style="font-style: normal;"> += tmp;
    7 V2 X0 d1 k  C2 d5 z
  19.     }
    + b0 X! P+ l% D! v8 _: H* A5 c$ G" q
  20.     raw</span><span style="font-style: normal;"> >>= nbits;6 l6 \6 A# U/ m8 E
  21. }
    . k/ M4 ?6 ]' d; p1 h( Q2 t( Y% A% O

  22. 5 e" u6 V, A# }9 Q: G
  23. static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    * F3 Z- p2 P! x1 _6 i
  24. {
    + G* J1 s- ^; C# m
  25.     unsigned char i;. m6 x2 s( c) r8 n
  26.     unsigned char tmp;5 T  A: w5 }) l! K: W

  27. ) G0 k  a' }5 H. W+ X% b
  28.     if((nbits < 1) || (nbits > 7)) {
      E! u0 c, f, \: h0 j4 ~3 L/ m* a
  29.         return;
    4 ~; O$ A- j# v5 U% E- B- @2 Y1 \
  30.     }" r# F+ s1 h, w  U; }
  31. % Q7 @* q: i5 g" i# K
  32.     for(i=0; i<nbytes - 1; i++) {
    1 m6 f$ a1 @  _( {( P
  33.         //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;
    ' J, A2 v/ z% [1 J
  34.         tmp = raw[nbytes - i - 2] & l_mask[nbits];
    . d- {4 ?/ L' b# t; P0 W
  35.         raw[nbytes - i -1] <<= nbits;: ?# F/ q( ^9 ^6 |3 A2 F
  36.         tmp >>= (8-nbits);: p1 @. D8 w7 K+ L% {' B, P
  37.         raw[nbytes - i -1] += tmp;3 ~& l7 b& U( z8 `+ K" Q
  38.     }. {4 l# @+ X' t
  39.     raw[0] <<= nbits;( H6 c- Q! |0 h7 L* E
  40. }- A6 X( {5 C' M9 y

  41. 0 m6 _# Q9 o8 o0 ]( D: P/ X
  42. static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)4 A3 }+ a5 P  ]/ C) z! T
  43. {* c+ ?% z! }. f7 r4 v4 s5 J5 k
  44.     unsigned char x, y;
    / ^+ j% b4 |3 b: q4 P8 q
  45. & @. P1 d0 n" Q# ^# G% Q
  46.     x = nbits / 8;
    ) {/ o7 m9 w6 m
  47.     y = nbits % 8;
    & G0 ^- B( i+ Q. |+ x

  48. ) o+ T* h0 F3 w* I# h6 K7 ?
  49.     if(x > 0) {! Q( ^# F$ b! R( ]9 }% |
  50.         for (int i = 0; i < nbytes ; i++) {0 j- R1 S& w- G9 s0 J( r
  51.             raw</span><span style="font-style: normal;"> = raw[x+i];; {5 z5 M) G; D" d. ~& X* ^9 R4 I
  52.         }
    7 X; G/ ]! K4 b+ X' h* C) e
  53.     }
    , a$ l$ s; E# b5 |2 D& a
  54.     move_right_linear_timecode_raw_7bits(raw, nbytes, y);
    7 _9 _6 f% B! l) E. t
  55. }
    1 k, n8 h: Z  i6 ?0 J/ Z
  56. & u- `4 w7 A" T) E) m! M

  57. : V5 C% S  H! m2 D: P# E2 @% z
  58. static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits), t# L% u* h$ T1 E4 [
  59. {( \& W& f, L4 o0 G+ N, m, G  k
  60.     unsigned char x, y;
    3 `1 _& ?; p0 a( u% w& i& H

  61. 9 K9 p) {) Y6 p; K( Q) h# i
  62.     x = nbits / 8;& k" U/ S& a( i
  63.     y = nbits % 8;
    5 H" H6 t) g) C% R
  64. ; ^! x7 G; ~  [% L
  65.     if(x > 0) {2 Z1 J4 L* _* Z) E7 l' w5 U
  66.         for (int i = 0; i < nbytes ; i++) {
    0 i# d- X% j8 I" t# S
  67.             raw[nbytes-i-1] = raw[nbytes-i-1-x];4 U& X* c  c+ n, u, {" p: B
  68.         }
    7 A( X) u* \$ s
  69.     }2 e0 ]2 P- d( X- [$ N+ t. J
  70.     move_left_linear_timecode_raw_7bits(raw, nbytes, y);# b6 B, ~) H' L) E9 `5 a/ @; I
  71. }
    ; {. c1 N% Z. K, F4 H$ X) ^

  72. ; e1 O; ^9 I$ Q' t
  73. unsigned char get_bit_linear_timecode_raw(unsigned char index)4 m5 S* t, ^3 A6 Y" s. @
  74. {
      b! _/ u  D+ a9 l  E
  75.     unsigned char x = index/8;
    2 [8 x5 F  \* |% J3 u; L0 ]3 C
  76.     unsigned char y = index%8;
    . P& }' e& X  B6 ]

  77. # ^# [1 A5 O8 T7 I* F: F
  78.     if(linear_timecode_raw[x] & (1 <<y))+ I4 ?4 f6 n8 h/ y  M" e
  79.         return 1;6 f( N2 E: g. k7 H" R( T7 x* z
  80.     else
    , f$ c' K' f! F2 |% K9 o
  81.         return 0;
    9 q+ ~' r( m4 Y1 s
  82. }
    1 ?9 V  r) T3 R. w! _  O3 |
  83. , s! Z) v% f# `" G
  84. static void parse_differential_manchester_code(unsigned char *src,  unsigned char *dst, unsigned char dst_size)* Y% E. Z4 {: \
  85. {, d3 f! P$ d4 b& [8 B
  86.     unsigned char i, j;3 k( V" M* J1 b( ~7 Z$ F
  87.     unsigned short tmp, tmp2;
    # Y& k' S3 I( T6 v+ A) @7 b6 a: i/ h
  88. + j5 }: G$ ^, {( Q
  89.     for(i=0; i<dst_size; i++) {% x4 ?5 g/ H* d# p

  90. 6 `8 \9 V* C! x% M8 d- ]' S
  91.         tmp = (src[i*2 +1] << 8) + src[i*2];3 D- v2 ^) N5 |. x: Y
  92.         dst</span><span style="font-style: normal;"> = 0;' W2 R5 H  o8 J; `" b* P
  93.         for(j=0; j<8; j++) {8 [6 {3 L/ T/ S# W" {
  94.             tmp2 = tmp & (3 << j*2);0 `  l8 _* B) G" z* G
  95.             tmp2 >>= j*2;+ q- g7 R3 k) V1 c/ H
  96.             if((0 != tmp2) && (3 != tmp2)) {
    % j5 ^' N7 V8 z5 ]  K- ]
  97.                 dst</span><span style="font-style: normal;"> |= (1<<j);, C- n9 q6 ]# M8 q7 w) v) ]4 o
  98.             }
    , c/ _8 z, I" b) Y' H
  99.         }
    , C- K4 z7 }3 I+ {; f, {
  100.     }  B" s& r9 K2 |1 e
  101. }" j) N9 f% C3 f( z6 L9 M& j
  102. % S4 X& X( W3 u
  103. static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)
    $ B) \  p# V* i% X
  104. {
      m: E1 {4 f% p- E. C
  105.     const unsigned short sync_code = 0xFCBF;
      |. ^* o' e' D0 N
  106.     unsigned char i;1 _; ?8 I' a, A2 d0 T3 N' |, u. q9 P0 N, E
  107.     unsigned short tmp;) F  J8 x5 L& e3 [9 ^3 v
  108.     char ret=-1;- L" A7 T. X- T1 M9 {3 K& H

  109. & q7 O# E# T$ W* q
  110.     for (i=0; i<len-8; i++) {2 s5 D8 _$ j, x- N# |9 U9 t9 x) R9 `7 b
  111.         tmp = (src[i+8] << 8) + src[i+9];
    1 j  X. @8 j  t7 H
  112.         if (tmp == sync_code) {
    1 y+ I4 T0 N( B
  113.             ret =0;
    ; r; }8 |0 [( F# F% O; v
  114.             *valid_len = len - i;+ [- d; r4 u3 u* G4 r' ]
  115.             memcpy(dst, &src</span><span style="font-style: normal;">, 10);   //10Bytes equals 80bits
      s0 [; E; A, M6 X- f8 K! a1 }" O
  116.             break;
    0 v/ }; n3 B9 L' q' {: C- A1 G
  117.         }( m3 h5 w, |0 y6 q5 @
  118.     }
    # \4 I$ [! c" R
  119. ! R. e6 B) Q- r, B5 E
  120.     return ret;# w, r# a& `) ^

  121. - I4 _3 p: [0 M9 e: c2 h1 Q
  122. }
    7 W4 C' f" K1 T9 v/ \+ R

  123. - N- D! z& I: w" Q# n; N
  124. unsigned char ltc_dst_code[40][10]= {0};: B+ c+ f% k+ X, v. L* O
  125. unsigned char ltc_dst_code_count = 0;
    , I; A6 w2 b  d/ f, L: s% q
  126. unsigned char ltc_code_valid_len=0;
    ! q1 j2 e" i- C8 A- z1 N
  127. unsigned char ltc_code[20] = {0};
    ' y/ n. \& [! T& a
  128. unsigned char raw_ready[60] = {0};
    ( e4 h0 K: @! }2 R
  129. unsigned short offset_bits = 0;
    0 Y; j. E* l+ C/ h9 e- ?
  130. unsigned short ltc_remain_bits = 0;" a: V& @7 R+ L6 S# [: _0 {: t4 f  W
  131. unsigned char sec_ltc_code[20] = {0};0 r) p3 r' j2 z$ A3 u! H( O
  132. unsigned char ltc_dst_code_cur[10]= {0};
    ( r6 N- T9 n. G1 ^5 j
  133. unsigned char new_frame =0;
    # `' t; q6 W/ }" w( P* ~% |
  134. 5 g7 K8 A1 A$ r1 m2 _, W
  135. # L- z. U8 l2 T$ H5 s+ ]- u  J
  136. void parse_linear_timecode_raw()  O( Y8 M8 |# l% |% h5 L6 d& t
  137. {1 v/ }' ^- x9 c$ u' s
  138.     unsigned char tmp;1 q0 M; P2 f. C4 a$ Q% J
  139.     unsigned char raw_mv_right_bits = 0;! `7 s# w* j0 h/ R) W

  140. % E0 A5 S4 W. c( K
  141.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {# I/ @2 z- y5 f. S- t" J
  142.         isjam = 0;
    ; E& Y0 D$ m/ O5 F: ]
  143.         memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));
    + w- }: r3 L& B* f" H" t; Z3 l: }: P
  144.         tmp = raw_ready[0] & 0x03;
    4 B2 k2 p" [  {5 L
  145.         while((0 != tmp) && (3 != tmp)) {2 E3 l8 a4 L* C( W6 Q9 w
  146.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
    % C2 K" u4 T' L: K
  147.             raw_mv_right_bits ++;
    / z& G3 P3 t+ w, Z; _+ z4 S
  148.             tmp = raw_ready[0] & 0x03;
    : [2 ?' z3 `4 @  r8 p
  149.         }- \- e3 d" u7 x! U3 o+ b# P
  150. 1 O# F8 L! A5 @8 Q6 @- g
  151.         for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {7 O, s8 p% U' V, ^0 i! O
  152.             memset(ltc_code, 0 , sizeof(ltc_code));1 [. y! m, O/ l3 J5 l3 j# j# G
  153.             parse_differential_manchester_code(raw_ready,  ltc_code, sizeof(ltc_code));, f" h5 ^+ Q- I& n
  154.             //0xFCBF;
    / y, N: o  M0 n2 v/ F
  155.             if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {
    6 C  f  V" o, u+ u- X
  156.                 linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;
    + j4 i4 L' b$ M
  157.                 offset_bits = raw_mv_right_bits;
    6 D5 X' B6 n* |, [6 U4 [
  158.                 break;
    5 s8 n- ~  ~7 v1 e! Z, ^: L$ B  Q
  159.             }5 A; l1 d# ~  T3 r
  160.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
    1 f9 J0 T: y) o! L+ J% r
  161.             raw_mv_right_bits ++;
    $ x1 o; k3 M9 _! D( ]6 I& k
  162.         }/ }) F9 H' k3 Y+ s& P
  163. 1 I( s) Y, |7 F" \: j. q! ?
  164.         if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    4 V" G9 |- l/ m. v
  165.             LtcInput.tim_count = 0;     //reflesh tim2 period
    ' K/ V" f3 C  J. w, s
  166.         }3 s: }! @2 }  i8 O, I7 [: @- I

  167. ! Z; a, @# H  p1 |
  168.     } else {
    2 m6 K' ^, O: s0 o9 Q# R2 }- ?$ h
  169.         isjam = 1;
    % z/ {& S& P2 k) k3 X4 o) g- d
  170.         memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));4 v- E7 W4 W1 P* f* [% A
  171.         parse_differential_manchester_code(ltc_code,  ltc_dst_code_cur, sizeof(ltc_dst_code_cur));
    6 y; c; S- E8 Q9 f
  172.         if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {
    " y8 [9 j5 l% s7 E9 u% C
  173.             linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;
    8 Q+ |1 B' p# H- X% J
  174.             LtcInput.tim_count = 0;     //reflesh tim2 period% s, k3 w! Z  U" X
  175.         } else {
    ! ]* r3 L+ b$ v5 X2 A5 M
  176.             new_frame =1;
    4 C2 K. m2 b- a  ~
  177.         }2 s, _$ _! Y5 p* C) u
  178.     }/ i( n! m# I1 s' K' N
  179. }( F/ \; v/ |8 P' \9 e+ H0 p& D
  180. </span></span>
复制代码
6 G, R; w4 |6 F; [
5 g5 a- T; ]) v! Q5 p* L( K
总结以及调试过程中发现的问题。
9 `" p- S& t* a9 d' w, v; ]# K. j/ E  Y: p4 u5 P
1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us
  d+ g/ A' g# x7 \/ D5 ]9 z
( W$ c0 `+ W( C" P; j0 T
20201127114629167.png
  l3 S# b- z8 D$ m) u6 J
; K" I7 n! S4 `( W0 D2 Q
2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形$ T; F# e1 d( G+ j( x' b
* e4 R& @/ K' Q; f4 Y
异常1, 中断回调,里面调用HAL_TIM_xxx ,  导致反复进入定时器中断,9 A9 d) R; i' V& Y+ U

- }$ V0 p* }$ f1 t
20201127115308255.png

7 u0 N/ K0 h3 f* B+ n* y* X+ {) b4 _; @7 c& T5 U7 n% w
异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行; ?( G1 n' V9 n' ?: [* t: ^; A/ u* [

3 E; Y4 T7 o, N9 V* e2 g# N
20201127115925296.png

1 J+ D% Y. p6 g( M0 L2 b
4 F8 m' d/ B0 K解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形. v  I1 {3 b# M6 n* r2 T
  1. void TIM3_IRQHandler(void)
    3 d( l3 I# O$ C. Z" J2 i6 f1 [
  2. {% k0 y/ n4 q7 o5 ~. t
  3.   /* USER CODE BEGIN TIM3_IRQn 0 */
    ( v4 K  }+ B2 a2 l9 o: O
  4. 7 Y- N9 f- H6 Y) y1 ~4 [) Y
  5.   /* USER CODE END TIM3_IRQn 0 *// \5 U, I' {1 D, S- N
  6.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);5 w. p5 l. t% w# I8 x
  7.   htim3.Instance->SR = 0;4 |0 w5 `+ C2 P/ E5 J% _
  8.   htim3.Instance->ARR = LtcInput.period;
    ' T1 j$ s1 z% J: g/ \
  9.   htim3.Instance->CNT = 0;  K) \* F5 l( m3 J- a
  10.   ltc_input_timer_callback();4 Q' ?* x- n3 x. ?  `

  11. ' m  g2 q, S5 r$ i6 z  V$ l; ~/ t, }
  12.   /* USER CODE END TIM3_IRQn 1 */
    ' C# o: W8 F$ K8 C
  13. }
复制代码
( R+ A- W! O, \# N4 G* y
/ }! q0 G% z/ Q  N) s
20201127120550172.png
/ Q' \" p" J' p1 ^, t$ T  ^8 b5 Q

7 d- F2 j: u  n' L& i: J
收藏 评论0 发布时间:2021-11-14 23:04

举报

0个回答

所属标签

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