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

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

[复制链接]
STMCU小助手 发布时间:2021-11-14 23:04
时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,* V6 X4 @; k& l# ?! s$ E
& c' Y. T4 `# q. B: h
20201127093851207.png
) R4 G) g6 w" C1 p

* c1 K+ Q+ K$ g2 L, J. M4 G( ]$ ]8 h8 i1 x) [! \; |$ y
实现原理,0 w; _% w& e# ?# E* Q+ D
& r5 r/ {) [- a" x" |; T% n
1.  EXTI  Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period
/ F* E$ i( u$ w% u. k: Q& f0 F" M8 J3 M+ R. m" H
2.  继续用EXTI  Rising/Falling 中断+定时器方式接收时间码0101值, EXTI  Rising/Falling 中断时,修正定时器中断周期为Period/2。
8 n. I4 R7 H% q% o2 ^: E3 @$ i% }
0 {" a9 A; G( Q& \4 U$ g2 t1 _" _2 [产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period9 V( J% W9 ^! F, K9 l6 K  B. C& g

0 e- B6 ~  o# `0 |+ X7 N% D1 I: Z3.  解析差分曼切斯特编码,查找同步码5 i. H9 |) i; o6 w! L* U

0 c$ ^8 w  d: j5 |% B! c. E% u流程图,
% {8 A+ \: i9 H; J1 ?6 v3 f9 e* g/ M% N
20201127113610958.png

; M3 ^: r( V0 ~3 h- u9 W
/ l$ A; ^) |! T* S! ^; v  d1 w% K! U; k4 j( c0 [
关键过程代码,0 |+ e8 |% y. a6 ?2 g/ n% K: y
: a( M# s" l5 d6 t  Q5 k# E
1. EXIT 中断处理$ Q: _  V9 i6 e& X+ ?, m7 u
; D4 s+ ]7 N& W8 j% L3 D
  1. struct LtcInput_s LtcInput = {
    ( h+ f$ T" K; x7 u" s
  2.     .tim = {0},4 y" s  h* M, v9 X& E6 ]4 F) J6 ~
  3.     .tim_count = 0,7 e+ p" P  |( h  |# l7 j  K
  4.     .period = 0xffff,
      R. O7 `3 R" B! k/ S
  5. };
    * j; \" v4 n# s7 ?3 j

  6. & y0 a8 F* N& T- g* I
  7. static uint16_t parse_tim_of_ltc_input_get_period(void)0 K& i/ q8 z3 a: `/ Z7 F$ `
  8. {6 q: U5 e8 e" M) J, h1 m+ G( I: U
  9.     for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {2 s  r2 N% K4 Z) f: `% q) n
  10.         for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {. q9 T8 q; j. \" V
  11.             if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
    . s+ U- y7 y; a2 H
  12. <span style="font-style: italic;">                uint16_t tmp = LtcInput.tim;
    # L7 @+ m  h1 h& E
  13.                 LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];
    0 l9 O) w  o+ B4 C. _8 g( @
  14.                 LtcInput.tim[j] = tmp;
    5 `7 S: @4 F; m& `7 `/ w$ W$ B
  15.             </i><span style="font-style: normal;">}. e% F; D' M6 M1 ^7 c0 c
  16.         }
    + s6 w- I. ?3 G! O% U4 z5 ~, @" D4 a0 y/ T
  17.     }# X; U8 \4 _. a% S' s' t
  18.     uint16_t period = LtcInput.tim[10];
    $ j: z- i5 j% O1 T$ x2 c
  19.     return period;* F5 ]! {) i- P* {$ K( A" L9 J
  20. }" Z/ k9 V2 M8 l0 f

  21. & N. Q  M  ~5 b
  22. void ltc_input_timer_restart(int period)
    2 p4 W6 v1 N& f/ U' ]
  23. {  s& Q, _0 n+ l4 g' {1 _
  24. 6 T8 E! S$ I* ?- k: F5 x& u
  25.   htim3.Instance->SR = 0;" D9 ^5 d5 ?/ |5 |
  26. htim3.Instance->ARR = period;
    7 X2 C  H* p7 W0 z3 T, M
  27. htim3.Instance->CNT = 0;( |2 [# j  \3 j) U; m
  28. ; K$ R; @6 E$ ], F! W! n" s$ h5 N% l; Y
  29. }$ l. u9 U- S0 O  X% Y# q

  30. 1 M* b* \: Z+ s) Z9 s
  31. void ltc_input_pin_callback(void)- _  p! c  b1 f4 P- J& B
  32. {2 Z3 f0 C$ V$ s- a0 i: m
  33.     // HAL_TIM_Base_Stop_IT(&htim3);
    0 N9 q3 h$ U8 R) ]* z) p6 K1 b0 h
  34.     if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
    , g* j7 b2 p, N" r7 z
  35.         ltc_input_timer_restart(LtcInput.period/2);
    ( S/ C2 M+ K& v
  36.     } else {
    4 `4 I" }- g5 c+ x
  37.         LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;# S, H, V# v5 s7 Y, M
  38.         LtcInput.tim_count++;( O% ?% ]7 U! C6 A8 J
  39.         if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {$ e% N. V% h0 ^; n2 B5 t- Q- [
  40.             LtcInput.period = parse_tim_of_ltc_input_get_period();
    4 b' V1 ?/ J: B8 M# t$ T
  41.         }
    - c& p2 y" W: ~# c# I
  42.         ltc_input_timer_restart(0xffff);3 U6 ^9 v4 q" r
  43.     }
    1 z% O* S% A& v
  44. }</span></span>
复制代码

9 _' N7 w. l# K8 s( y9 e2. 定时器处理6 T3 H, n$ S7 p+ X5 ]* G! m0 s
  1. /**. V+ g+ B) |/ }8 J
  2.   * @brief This function handles TIM3 global interrupt.7 P1 [4 D" w! ~
  3.   */
    6 E) `$ v! Y5 f2 Y
  4. void TIM3_IRQHandler(void)& Q/ q# D, m1 G% y$ S! g
  5. {
    8 g. w1 R+ w& G. O( h
  6.   /* USER CODE BEGIN TIM3_IRQn 0 */, _; {' |" f" c! j+ [
  7. , L. N' [0 @) r8 H8 p: b. a) ~' [
  8.   /* USER CODE END TIM3_IRQn 0 */6 T" k) p# [+ W! D! _
  9.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    9 x6 D# W$ M0 N% h
  10.   htim3.Instance->SR = 0;
    # b- S+ f5 h! j1 I. V4 w0 H
  11.   htim3.Instance->ARR = LtcInput.period;  ^- [$ ], G3 w
  12.   htim3.Instance->CNT = 0;0 I# q$ K) [# d% v6 N+ g6 ?6 |
  13.   ltc_input_timer_callback();
    % r/ w, G/ w) Q7 b7 a
  14. 4 l* c/ A4 ]# {* J9 ?* C% `' m
  15.   /* USER CODE END TIM3_IRQn 1 */
    5 Z% }% x: q& v4 y: `" L
  16. }
    3 O/ [5 N' J( t0 v/ ]. j, _/ s

  17. * N! G; C9 A+ ^* K2 r7 m4 V
  18. char ltc_input_timer_callback(void)
    5 t* Q& ?) ]) z6 i! F+ Y' L
  19. {* _9 Y0 ~7 _+ B0 H4 _. t
  20.     GPIO_PinState status;- }( y3 ?3 Q1 w2 Q$ o
  21.     unsigned char x, y;( s: v* F6 {$ J. w
  22. , u/ i; L$ m0 U$ I. h+ [6 X
  23.     status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);
    5 r" f+ p# V  T" o2 D+ H
  24.     //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);0 S$ _- |/ T0 a$ c3 {8 n) ~$ V* A
  25.     //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    ! \6 O. T8 C  Q

  26. 6 p9 |+ ^/ A. {3 R" `  W
  27.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);, \8 K+ E- G5 @) l- X3 u, U7 x
  28.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);
    . l: Q9 e- m; D* o5 B& h
  29.     //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));
    : L& L3 M/ C3 u

  30. % F6 Y; o8 J5 u5 K, `
  31.     x = linear_timecode_count /8;
    ! V' U$ I% b( ^) |5 C+ Z9 u$ O. u
  32.     y = linear_timecode_count %8;7 |2 d* ]" p" ?# Z* S, L. y
  33. 8 K- y! h0 \6 }4 ^8 L3 f& M- j
  34.     //buf[linear_timecode_count] = status;" n& d" e3 M. o& i9 f
  35.     linear_timecode_raw[x] &= ~(1 << y);. Z' g! w) O' ]  e- O
  36. 9 k0 {/ K& X9 W& L
  37.     if(status != GPIO_PIN_RESET) {7 ]8 y2 J6 a$ n" y# ~) s
  38.         linear_timecode_raw[x] |= (1 << y);
    4 `7 H1 e4 J* ?  d* R% ?3 n
  39.     }0 g/ _' S3 u; D2 Y1 \( Q; N9 A

  40. + |" d# U# I3 P
  41.     linear_timecode_count ++;
    / S& N. h4 K1 h% g
  42. - ^# s+ \: _; P1 D1 v% d  {+ H' ^, j
  43.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    3 ]& u' N: L; ~: p) L/ w
  44.         if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {
    : A$ e) I8 L( f8 N0 [. @% H
  45.             linear_timecode_count =0;: m' U* o) \6 `8 Z7 _$ ]/ M
  46.             memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));
    2 j+ ~- I  ]3 \1 ?" a3 _; _; \( a- ~
  47.             linear_timecode_ready = 1;
    ( r' i! @& f& F- y  v. N
  48.         }, B" _' d: c- N" e: G+ m; {
  49.     } else {
    & M1 ^5 `2 b$ l. ^* Z2 y  n+ E
  50.         if(offset_bits > 0) {
    : M2 A8 t! a- v
  51.             //skip offset_bits2 K# y& k, B1 B! F5 g
  52.             //If offset < linear_timecode_count, adjust the offset to the next frame.5 D5 d" i1 j: A- n
  53.             //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.7 L' r, W% Q6 z( H' e4 I
  54.             if(linear_timecode_count > offset_bits) {
    ! ?9 T8 v% d1 O7 A3 N6 \
  55.                  offset_bits += 160;
    7 e7 l! `7 i& I3 t4 |) H( F
  56.             } else if(linear_timecode_count == offset_bits) {* [4 T& C; R" k+ d' z
  57.                 offset_bits = 0;
    * T% ?& p7 {; i6 P1 G3 k2 }1 w  m
  58.                 linear_timecode_count = 0;
    ( n5 A$ p0 _: J/ J" u8 K5 p& L
  59.             }
    8 H4 s9 @+ }; G7 o4 j0 Q- l$ i
  60.         } else {/ k- G, d2 l4 s( W' y' y
  61.             if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {
    2 T& w$ y# n% v+ o
  62.                 linear_timecode_count =0;9 T9 R% E& [' Z! D
  63.                 memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);
    , z3 k# L% Q) E7 D; D
  64.                 linear_timecode_ready = 1;+ V! C, g6 b" @8 R6 q( u# Q8 d6 B
  65.             }2 j+ l' u9 A2 f" Z( ^" A* A# D
  66.         }% y# \6 N9 s( C+ o$ t$ F& |
  67.     }
    * y& Y/ [/ p; f" q
  68.     return 0;  A7 ^& s( l) i- S8 T* N
  69. }
复制代码

1 t8 J3 t4 n# ?9 A1 o. P3.  差分曼切斯特码解码
: M& P& Q8 P1 c3 k! U- |8 I

  1. * b5 |4 C8 t5 X/ E' j
  2. unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
    ( q# E% @# T$ x  C3 O8 {
  3. unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };) m7 ^7 z6 Q7 R% m& d* d
  4. 7 Y& U& B& T) d' x7 }$ s. N
  5. static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    ! e8 H4 k; j$ X7 R6 g$ `. B  c
  6. {
    , R% M  n+ w. Q# y+ w/ ]2 f
  7.     unsigned char i;& S) J( X6 f* v3 z$ x4 G
  8.     unsigned char tmp;
    7 k  b9 \, y' g% `
  9. 8 E6 A. |' ?  b$ f
  10.     if((nbits < 1) || (nbits > 7)) {2 Q8 b' \. S3 U! k
  11.         return;
    ! T4 d1 _4 y* M9 ]3 h- T) {2 P
  12.     }
    6 V1 _+ I5 o' ], P" M% X
  13. + u6 M* T" |! a+ G# [( {4 N
  14.     for(i=0; i<nbytes - 1; i++) {
    . F) s/ b6 y! l3 K
  15.         tmp = raw[i+1] & r_mask[nbits];  W; }) b2 S9 j% d$ G
  16.         tmp <<= (8-nbits);
    9 U0 E- `; e: u& @0 e7 \: K
  17.         raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;
    ' D+ A/ N* _4 k, n8 Q3 ~. m
  18.         raw</span><span style="font-style: normal;"> += tmp;) h5 K& V" Y$ L# J3 B$ Z
  19.     }9 N8 |; h+ k0 J2 K
  20.     raw</span><span style="font-style: normal;"> >>= nbits;% n  C, f2 n1 ]2 M, V( h1 ]
  21. }% K/ H4 `! b5 [

  22.   Z+ B# z. E  u
  23. static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    , g/ v* Z$ S' y/ K
  24. {& x: @# R; h1 W8 ^1 l
  25.     unsigned char i;
    7 u; g  {. h8 l9 w; N, `; O4 E0 ^
  26.     unsigned char tmp;* P. g6 k- B( B7 \0 \/ Q

  27. 0 L$ G. v3 p! d+ J; y. M/ e4 ~% m! \
  28.     if((nbits < 1) || (nbits > 7)) {& A2 l& D6 u  j8 d% @# z  P
  29.         return;
    / F. C2 C& p5 W( ]4 T1 t0 u: b
  30.     }
    ' j3 `; Q1 b& l, F

  31. " Z2 S: K- g  u) K7 b$ v& G
  32.     for(i=0; i<nbytes - 1; i++) {
    6 I% U" L) S/ y+ e
  33.         //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;
    9 j- r0 T7 c* }( |: W& E
  34.         tmp = raw[nbytes - i - 2] & l_mask[nbits];! I6 x3 |+ p, C7 i
  35.         raw[nbytes - i -1] <<= nbits;
    1 K9 N# e3 d  h# M
  36.         tmp >>= (8-nbits);- @* |7 c5 S# ^8 e3 D( x
  37.         raw[nbytes - i -1] += tmp;5 P. r' e# ^  V/ s5 T+ g
  38.     }
    $ g& o" J# W& i$ c
  39.     raw[0] <<= nbits;3 r0 ~* i# L/ l2 ^4 U, U2 R
  40. }
    8 k% Y4 v  C; M

  41. ! V! p" }- g$ {& W/ c* S$ {8 Q
  42. static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)
    3 @% i8 D( E3 x
  43. {
    % {1 R! i: ]. z7 k+ m
  44.     unsigned char x, y;: ?5 m/ _! H+ `( o4 t1 ^7 }
  45. 4 f* ~) ]9 B1 `
  46.     x = nbits / 8;
    ) h3 A+ B. I8 j) J. `, B
  47.     y = nbits % 8;$ c* ~+ T1 q5 k; Y) [
  48. 7 I- v" @" ~- C# C3 c1 P6 p
  49.     if(x > 0) {5 }4 W% m8 {4 f8 L8 c
  50.         for (int i = 0; i < nbytes ; i++) {
    5 w% k( ~% N' @# Y! T1 I
  51.             raw</span><span style="font-style: normal;"> = raw[x+i];- t2 Q: ?) z, _! k: ~
  52.         }
    % R2 t) v+ x: H, M+ a7 _; m* X
  53.     }
    7 P4 C; b, {4 n# _
  54.     move_right_linear_timecode_raw_7bits(raw, nbytes, y);/ Y% ^; Y* x# K0 M9 K" F5 K
  55. }
    ! ~2 }$ B" k8 ]8 U. P
  56. 6 M9 g' B" w8 X

  57. 8 P: G  y& l* ^8 H) s
  58. static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)
    1 R$ U. [) s/ u
  59. {
    ! T7 m3 V$ t$ W/ S6 l
  60.     unsigned char x, y;
    & r- [3 c$ B  c2 T" q
  61. / Y2 z# m* z8 \% |3 G
  62.     x = nbits / 8;
    , p' C! f0 l. f1 t: v
  63.     y = nbits % 8;3 ?+ J; {+ e, |2 U0 V) f5 x
  64. 8 w6 t+ `5 ~* z4 p. E$ _' p1 U
  65.     if(x > 0) {' P+ g; v( U% d( A
  66.         for (int i = 0; i < nbytes ; i++) {
    * O- D. l! f% I. [0 J
  67.             raw[nbytes-i-1] = raw[nbytes-i-1-x];
    4 R" D7 O6 b3 o. P& a
  68.         }2 d! O& c6 c  G: W
  69.     }
    ; e- B- a& l, c  N) M, c/ U
  70.     move_left_linear_timecode_raw_7bits(raw, nbytes, y);: ?  _/ G9 t5 u: `. ~; O, S4 F) `
  71. }  t  _7 S, ^( U; _

  72. 6 g, u  W4 k# K# w" v/ {$ G
  73. unsigned char get_bit_linear_timecode_raw(unsigned char index)
    7 g$ [" I! p" \  x; C: C6 {0 {9 x
  74. {4 H, V5 e% V! m( o
  75.     unsigned char x = index/8;' K2 R9 ?; S/ F4 ^
  76.     unsigned char y = index%8;! l( F9 Z0 E! x. k7 T7 A& K
  77. 7 ]( A' D" @0 i0 ?6 L* ~
  78.     if(linear_timecode_raw[x] & (1 <<y))
    6 b6 H/ u! I- c
  79.         return 1;
    # G( p* |, h0 ~% W& a: o& r# a
  80.     else
    ) T  D0 k4 [3 ]6 e, h) t
  81.         return 0;+ t' g/ \; h# f9 e$ g
  82. }7 D6 Q0 K3 T) E( W' `- ]! o
  83. 9 b; k2 L$ ?8 l' s
  84. static void parse_differential_manchester_code(unsigned char *src,  unsigned char *dst, unsigned char dst_size)/ |8 d* {8 A' |- x& S
  85. {
    % D) F, c' u) z4 h, |) v
  86.     unsigned char i, j;
    2 P3 ?9 o* A  f1 l
  87.     unsigned short tmp, tmp2;
    7 b1 }; V4 g) p; U' t% D4 e

  88. / P& ]* @. T" ~# V, S* |* J
  89.     for(i=0; i<dst_size; i++) {7 _% i+ S2 Z+ W) t; x  g
  90. 9 Z1 L+ U& t7 `' J; B: ?# A' s* h
  91.         tmp = (src[i*2 +1] << 8) + src[i*2];
    ! }8 {4 m6 Y( C9 Z: `9 ~" T' u
  92.         dst</span><span style="font-style: normal;"> = 0;
    / p" {9 i8 h; r$ J8 K1 o
  93.         for(j=0; j<8; j++) {' m% m6 {0 V6 n9 n, t
  94.             tmp2 = tmp & (3 << j*2);
    4 `- S" s: r; S1 d  {
  95.             tmp2 >>= j*2;
    ( G% W6 E1 C" ?5 l# G) ~
  96.             if((0 != tmp2) && (3 != tmp2)) {5 x9 r1 a9 a( s- y7 d
  97.                 dst</span><span style="font-style: normal;"> |= (1<<j);
    4 x- }6 x& @8 l
  98.             }
    . R9 h9 k6 q! }+ o6 U9 Z/ M4 P4 B
  99.         }  r9 ~" a0 a2 n1 U+ s1 X
  100.     }
    / g2 p; R4 W& z5 {( e( |
  101. }
    5 s: b& |- t$ y- {! c( @
  102. ; D# Z  z: j8 m, g+ P' N
  103. static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)
    + p5 U5 P( M/ K9 ]& n4 C& G1 j8 \; z
  104. {
    3 w1 L2 i7 J; @* _; k' r
  105.     const unsigned short sync_code = 0xFCBF;! z# r7 \# j2 G) u3 l
  106.     unsigned char i;) Q3 J. J( C  t' b9 m7 W2 t: j
  107.     unsigned short tmp;- |; `9 ]& T" a" J) A
  108.     char ret=-1;9 n/ o& r/ ]: l

  109. 5 U8 x3 F2 j' s6 W4 k2 _
  110.     for (i=0; i<len-8; i++) {0 L5 D& k! s- S/ s, I* X
  111.         tmp = (src[i+8] << 8) + src[i+9];
    / I2 _" P8 [5 }! \" f
  112.         if (tmp == sync_code) {  Y1 A, H/ i+ a& P( ~# x1 s
  113.             ret =0;
    3 |2 G- a  W$ J" _4 m( [
  114.             *valid_len = len - i;3 g6 i: p0 p% z& E$ A3 @6 _
  115.             memcpy(dst, &src</span><span style="font-style: normal;">, 10);   //10Bytes equals 80bits
    4 C; c4 A% ]0 W0 u: n
  116.             break;
    9 \, X) @7 R" c9 m- F
  117.         }
      d4 Y8 n5 [* R* _7 T
  118.     }
    2 c7 \8 u( f' R, U6 c

  119. ! L3 K; w8 p+ r* g
  120.     return ret;2 i% p5 r7 N$ v

  121. : d/ H2 {$ `+ o: i
  122. }
    ; U, Q9 s+ J% ?2 o8 B5 E

  123. 8 |3 C  Q/ b* h$ H
  124. unsigned char ltc_dst_code[40][10]= {0};: l3 z) V' G- H8 z+ ?
  125. unsigned char ltc_dst_code_count = 0;
      y! ?+ n& r4 ~5 @
  126. unsigned char ltc_code_valid_len=0;6 J0 B2 _. C+ I- O8 L! I
  127. unsigned char ltc_code[20] = {0};. O3 U$ H7 w* l
  128. unsigned char raw_ready[60] = {0};2 k( N+ ^8 f4 u/ i, b7 m3 M
  129. unsigned short offset_bits = 0;
    . R2 S' ]2 Y5 ?( g& d# M" Q
  130. unsigned short ltc_remain_bits = 0;
    9 n, F  c8 z' [! P0 A, v7 W- x
  131. unsigned char sec_ltc_code[20] = {0};( j. S( g: q1 S
  132. unsigned char ltc_dst_code_cur[10]= {0};
    4 H, y' }" Y. B# B, a: s
  133. unsigned char new_frame =0;
    2 y6 `, ]$ D4 r* l7 f5 `, F9 D

  134. + i& f: r) J& t$ o  k% e
  135. 5 K  |+ P5 S0 j* D% L- K
  136. void parse_linear_timecode_raw()
    6 J' U9 T0 b! q
  137. {
    $ ~" e& H: f2 x' [" T
  138.     unsigned char tmp;2 l! x- [( J' J0 v% F3 B
  139.     unsigned char raw_mv_right_bits = 0;) S& v; b; o* L( p* j
  140. 0 H2 I: o9 g* _
  141.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
      t# C8 n6 E* I" K& ^0 `5 Z- E
  142.         isjam = 0;
    3 E/ I, b* ~2 s
  143.         memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));
    ! n% V7 w0 W# r
  144.         tmp = raw_ready[0] & 0x03;, B. n. T! _2 c0 Y1 F
  145.         while((0 != tmp) && (3 != tmp)) {
    ) v6 Q3 V" D. l2 x( B4 l/ L: R2 |
  146.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
    ; B( [8 X) X- e# _4 C  p. W/ a
  147.             raw_mv_right_bits ++;% M8 @+ f9 t  T9 s* `2 k( o
  148.             tmp = raw_ready[0] & 0x03;8 g4 ]/ z# Y& r7 V  U
  149.         }1 N% `6 T* a- L; \: i7 P# _
  150. 7 G4 Y& d! q- M
  151.         for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {$ r' o% @! O& P" i
  152.             memset(ltc_code, 0 , sizeof(ltc_code));! a( b& y" |- w9 H$ g& c
  153.             parse_differential_manchester_code(raw_ready,  ltc_code, sizeof(ltc_code));
    ; z2 }% ?. u; W
  154.             //0xFCBF;- X# i% ~8 z7 m3 a
  155.             if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {6 \% _5 o  |8 M7 k. M$ D, x
  156.                 linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;
    6 Q. j/ W1 I' k9 J, s
  157.                 offset_bits = raw_mv_right_bits;
    9 u1 A8 k, \1 I/ ^2 i
  158.                 break;8 x3 d, t* r7 j
  159.             }% m$ M& E! c$ v" ]8 O1 v5 C3 S
  160.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);, c  [# I. u$ c9 \0 e
  161.             raw_mv_right_bits ++;: X. ]' g- O2 u
  162.         }( A! N* M* p9 z
  163. 2 W  {9 X; w; ~) [" i
  164.         if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    $ M9 R$ d, |' W+ H- S
  165.             LtcInput.tim_count = 0;     //reflesh tim2 period
    2 p3 O) i/ v# o* A  T
  166.         }4 r' G/ k$ V% r9 ~0 o# O

  167. 2 E% Y0 C2 t- w3 n, g" u" C: b8 y
  168.     } else {' t/ y# v  e; A% r9 j
  169.         isjam = 1;
    + t& J! F) I; a( H+ ~& A- R
  170.         memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));4 g; H3 E" o4 Y
  171.         parse_differential_manchester_code(ltc_code,  ltc_dst_code_cur, sizeof(ltc_dst_code_cur));
    . ~% o; d) \1 ^" y
  172.         if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {
    ; \% o: N* o0 F3 M, h" W9 P
  173.             linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;
    , a7 c; r, p* E( U# h
  174.             LtcInput.tim_count = 0;     //reflesh tim2 period8 C8 v8 _. G, i  K+ p. e
  175.         } else {
      Y5 c5 h+ u, ]0 x* H; A
  176.             new_frame =1;% ]7 ]) G+ H" w5 \& F' p3 Z; ~
  177.         }* ?' z/ [: `. D
  178.     }
    0 r1 R/ v6 }7 A, ^" Y$ t+ F6 w
  179. }$ o8 B/ A( P+ ~" N
  180. </span></span>
复制代码
8 W8 E! ?2 E, H( U, g0 g
+ v& s, K/ m" G0 D: h2 F
总结以及调试过程中发现的问题。
! L4 z% }% @6 e- l; T; `4 v* T
' R5 E$ K* @1 B  b# j0 F+ b1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us; C* L  `' u# M) P

0 @4 _  u, X# _; E, s6 a
20201127114629167.png

6 Z. _! n, }: y' i/ ^) C
- o6 _5 E2 b; N, q; B3 w( p6 R$ I$ k2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
. y$ x7 k! S+ J8 H( Z: }9 L( w. |' C. r& b  I! i% a" U  y
异常1, 中断回调,里面调用HAL_TIM_xxx ,  导致反复进入定时器中断,
) V' t: @+ Q8 g/ j  c- v/ [. v4 G: |2 V& q- b; [1 l
20201127115308255.png
5 A5 ]2 }% C$ A# V# v7 H; [. M

* d, u7 P6 k: |/ ?6 d异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行
5 ~/ j8 v  S. s! C! C. S& [; Q3 O% N# Y* f0 v
20201127115925296.png
8 i* D* A' d& T- I) B8 J

3 |' }& q0 ~+ H5 p  T* z解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形) r5 F. b3 z2 K5 |; t8 ~
  1. void TIM3_IRQHandler(void): y( ^/ l2 U8 w  U
  2. {- A% ]4 d8 l: ]# C* h1 b
  3.   /* USER CODE BEGIN TIM3_IRQn 0 */
    + h8 ^8 T: D# h# O$ V0 V4 P+ j

  4. & E9 i+ B7 h* {/ b* C1 Z
  5.   /* USER CODE END TIM3_IRQn 0 */
    8 \7 v2 E# X2 t/ q
  6.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    / d/ M, i: g7 q5 J! R; q) K
  7.   htim3.Instance->SR = 0;
    2 M& |. ?5 T+ l+ l
  8.   htim3.Instance->ARR = LtcInput.period;
    , Z! S+ Z, K( @  m) [
  9.   htim3.Instance->CNT = 0;
    8 p) F0 J  B% Y' U& B1 E
  10.   ltc_input_timer_callback();
    2 j4 _  ?6 z& r7 T7 a
  11. * V* H; V3 ?5 T8 K" @
  12.   /* USER CODE END TIM3_IRQn 1 */7 X# k+ S* B3 v& [" M" q
  13. }
复制代码
$ P: o% T. o" r( {. Z; J
9 w8 i* S3 ]1 V. r
20201127120550172.png
- i3 G. J8 H& x( q

4 F% q. u+ S$ q7 E5 _7 R+ [
收藏 评论0 发布时间:2021-11-14 23:04

举报

0个回答

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版