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

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

[复制链接]
STMCU小助手 发布时间:2021-11-14 23:04
时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,
: X5 a6 l, N+ c1 \) G" U. ~& \& [2 m6 o! G0 i7 e
20201127093851207.png
; d; s( }. m! t& y3 l( w
2 R9 R1 L' l/ q+ O2 R) h3 O

- [$ N5 d5 u' d, |3 y2 k实现原理,7 Q( O) I0 b4 k$ V$ o

% D8 a& R7 `6 k/ J+ `4 D1.  EXTI  Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period4 S: D  o. g  {0 U; }

& f. l0 n7 F2 E) F2.  继续用EXTI  Rising/Falling 中断+定时器方式接收时间码0101值, EXTI  Rising/Falling 中断时,修正定时器中断周期为Period/2。! Y4 k1 {, Q; R

: b4 }. N0 A$ o9 ?- S产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period
* m* \7 @1 j+ {; L" R7 A. I0 k, _
3.  解析差分曼切斯特编码,查找同步码6 ?( O" r; _1 u2 `1 w

* o+ U" X0 M+ P6 }5 a' x流程图,
5 a  Y' Q& g2 V" G0 h+ n2 j+ e& K/ {2 i9 p0 H9 Y
20201127113610958.png
/ V2 j: R" V* H) V3 N
' j( l5 u. R. r
+ t' i4 @7 j, g/ g8 z! p7 t; ?
关键过程代码,+ r0 x6 N2 K3 V4 G8 L6 \: |
6 X+ L& t) ^0 M2 b3 C
1. EXIT 中断处理" T0 w! F9 b+ a* @' F
9 P( k# x; F2 N/ G8 F7 p) |
  1. struct LtcInput_s LtcInput = {  M: l% l) a# V, x+ e
  2.     .tim = {0},
    3 z1 q7 Z6 I9 V- {1 C+ b4 i
  3.     .tim_count = 0,& r8 U2 e# F( v5 w5 A9 U$ V
  4.     .period = 0xffff,; M; u! Y$ a$ s* r6 I- I' h3 m6 ^& h
  5. };
    9 t# C& A# o; [! ~( m' c8 k0 ^4 P

  6. 7 ?8 a. u3 J2 V0 ]6 _
  7. static uint16_t parse_tim_of_ltc_input_get_period(void)
    # G! I/ W) B0 j7 ^4 h3 z# z
  8. {  K. L# v! b" F
  9.     for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {/ _+ i, I5 [6 z' r3 z* n
  10.         for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {( J, r- ^+ \$ @: Q- P: M
  11.             if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
    1 f7 P- O- ~( Y$ l! d6 S
  12. <span style="font-style: italic;">                uint16_t tmp = LtcInput.tim;
    7 q' ]4 Z9 F: A8 t* q
  13.                 LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];* Q. k2 @1 K4 V  M
  14.                 LtcInput.tim[j] = tmp;
    . K+ I# z  S) i7 _8 n0 M$ q+ g
  15.             </i><span style="font-style: normal;">}
    3 `& |0 n, F4 a7 ]" _6 Z9 |
  16.         }7 N; q* }# I7 t7 |1 a
  17.     }
    . I' k2 G3 M, I$ a: w$ _8 w% R
  18.     uint16_t period = LtcInput.tim[10];- Z& z/ V) O! a  F# C) Z* C6 i
  19.     return period;! z1 u$ T9 ~, L# c
  20. }7 t, \1 H$ }/ G, X( D& H& ~& t0 m& M* `

  21. 5 ^) m, W! m' R4 x* u# R
  22. void ltc_input_timer_restart(int period)
    5 R5 ~" }$ ~+ Y8 G2 b1 Z0 X
  23. {
    : j- x( V, o$ O& ?3 D
  24. 9 ]! K+ R4 m5 M% ^" \5 P5 m4 Q
  25.   htim3.Instance->SR = 0;
    8 e$ E6 U5 u. d6 q) J
  26. htim3.Instance->ARR = period;$ M4 `, \: @; b4 W& k- Q' @/ q- p
  27. htim3.Instance->CNT = 0;. h/ h% ?, w# a% m4 d* s

  28. % Z, o4 i+ b) I
  29. }
    8 {9 f$ Q7 v& y) h

  30. . _2 O6 j+ n% n
  31. void ltc_input_pin_callback(void)
    / H% }7 Z- S" O2 J" _7 m
  32. {) ~7 C! C2 o* [
  33.     // HAL_TIM_Base_Stop_IT(&htim3);* S, [  r0 V7 q
  34.     if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
    5 @7 ~' q: G/ t& c& m+ F/ T" w
  35.         ltc_input_timer_restart(LtcInput.period/2);. _5 L/ [" r  x, l! }7 N
  36.     } else {& k* g# t6 l) U6 j4 Y5 P
  37.         LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;
    6 O+ X- p- d  X
  38.         LtcInput.tim_count++;
    5 Z0 D: f8 v1 X. \) G, l# V
  39.         if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {; V' ~# w: S4 m  T2 S  s8 u
  40.             LtcInput.period = parse_tim_of_ltc_input_get_period();( J- z) v1 }' I% P2 {- e
  41.         }$ R: g5 a( S; c. n) C' B  B, n
  42.         ltc_input_timer_restart(0xffff);
      z" v& [: y3 S  ?3 M, Y
  43.     }" h( L" O5 [& V; P* D( B
  44. }</span></span>
复制代码

1 `! k. F) K. y1 \2. 定时器处理" H  }1 G4 X3 u7 ?( K
  1. /**
    $ t8 U- z$ o( e' }1 w0 @/ ]
  2.   * @brief This function handles TIM3 global interrupt.; s( k+ G& l5 Y1 G* K3 h4 ]" g4 P
  3.   *// U8 \1 f1 K( T# x
  4. void TIM3_IRQHandler(void)
      O0 W3 X5 i$ K- v$ J) Q
  5. {( ~, F5 R- ?! i
  6.   /* USER CODE BEGIN TIM3_IRQn 0 */
      i! z; J" x' E' s& B3 M$ Z7 y

  7. " {8 b9 E3 j2 U/ b% D, W
  8.   /* USER CODE END TIM3_IRQn 0 */
    $ I; [5 M7 M( N" ^" p2 d: T6 w- ]1 l
  9.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);8 c  o& D) z2 @
  10.   htim3.Instance->SR = 0;
    ' U* e$ _* T/ N* v- f% S8 N5 b
  11.   htim3.Instance->ARR = LtcInput.period;* z  H  z  q9 y. Y2 B( R
  12.   htim3.Instance->CNT = 0;5 h( `; v; n2 U+ ?& e8 G% u2 B
  13.   ltc_input_timer_callback();
    " ~" F4 B9 N) c! b9 c
  14. ' C8 e( C+ ?+ ?) c
  15.   /* USER CODE END TIM3_IRQn 1 */$ B; P) L8 i0 k* @
  16. }
    % X; v$ T2 h5 R# b" }! O0 D; X
  17. 2 X# A' ]( [  y) p& X; c% _9 z
  18. char ltc_input_timer_callback(void)
    + Q# P# d+ d' ^$ N
  19. {  ^* c; v3 [+ D$ m% C" o# d
  20.     GPIO_PinState status;
    $ Q+ t, L/ q9 C" o- ^/ R$ A
  21.     unsigned char x, y;1 o! u* j4 V4 Q: A

  22. ! U$ J3 G9 y3 N
  23.     status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);) Q9 R  ?; z) f' G, ]" G
  24.     //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);
    6 L2 ^! ]6 V& _0 t
  25.     //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);$ u  Y& p3 v1 i  r
  26. + N% U8 N) O* H) ^6 S
  27.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);; `4 i3 I; A6 ^: z5 r. U
  28.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);
    ( a7 M* W6 |4 S  H
  29.     //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));
    4 L  I" Q( w8 _$ b( E
  30. $ s3 Y1 w+ L% L( I- ?, b. p: V
  31.     x = linear_timecode_count /8;
    , U+ r0 Q( w- ^3 I/ Z
  32.     y = linear_timecode_count %8;
    + y, [+ |+ x9 O$ a5 K8 y
  33. 4 W$ {8 P8 r3 V+ `* l
  34.     //buf[linear_timecode_count] = status;# d# M, v. ~1 i
  35.     linear_timecode_raw[x] &= ~(1 << y);. v* P+ E0 k* Q1 {* R8 h
  36. 8 s2 T; s# D8 s$ ~7 s3 `
  37.     if(status != GPIO_PIN_RESET) {
    7 Q: F# P- x- b6 {( D
  38.         linear_timecode_raw[x] |= (1 << y);
    $ Z6 M7 }4 x& r( ^
  39.     }
    ) h* G% |) Z$ R6 o% Q
  40. " ?  E+ L3 @8 X  ^* o5 \
  41.     linear_timecode_count ++;
    $ {2 ^! ]0 e! q% x! F* |1 Z7 X
  42. 0 X4 Y* I7 G: Q
  43.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    " {- x+ B7 d0 E# {. i* n9 {
  44.         if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {4 @+ V4 N8 H  p* X- d- P
  45.             linear_timecode_count =0;1 s; Y" G' a; l; f0 ]& C5 L
  46.             memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));
    ) {9 A7 W! B# h4 p
  47.             linear_timecode_ready = 1;0 }+ f* R9 h, {  Z
  48.         }
    7 g6 T+ T6 o# G) {) A  S
  49.     } else {1 o$ r2 w! Q( M% w% E7 y$ ~! X
  50.         if(offset_bits > 0) {
    0 Y8 v$ R5 ^9 N; e# K
  51.             //skip offset_bits
    . q+ |' B, z/ B* Z2 H  }3 L
  52.             //If offset < linear_timecode_count, adjust the offset to the next frame." R5 o/ E6 w' h7 N" ?/ X
  53.             //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.
    & Q  k( ^! u& ^$ |9 G* }- L& G7 I
  54.             if(linear_timecode_count > offset_bits) {8 M2 @& H8 }3 X8 {/ `0 K
  55.                  offset_bits += 160;4 U" Q3 O* I. I& F! h% K6 y
  56.             } else if(linear_timecode_count == offset_bits) {9 o+ _2 q' I5 Y+ b
  57.                 offset_bits = 0;
    , q8 b% A9 q. u6 B) R' L
  58.                 linear_timecode_count = 0;2 V2 ~6 g. u+ S* r7 m
  59.             }
    4 E0 L+ A2 n5 C; B
  60.         } else {) ]4 F7 G; A+ i' |$ z
  61.             if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {
    ! Q, ]( a: [0 u* `2 M% {+ s3 I' ^6 ~
  62.                 linear_timecode_count =0;
    * H, P5 [, P* u- z
  63.                 memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);' i) O$ f: L- e% M: F) \2 D
  64.                 linear_timecode_ready = 1;. Y9 x6 y& J+ s6 e8 Q
  65.             }
    ! q. Y' a9 l7 X* X3 j& i4 d
  66.         }
    - t4 X4 l8 A- b/ U! ?
  67.     }
    6 a7 Y5 w0 z: I+ I4 U" s8 B/ U- p
  68.     return 0;+ |% x. D2 z% A9 z5 O* w
  69. }
复制代码
8 |; l, \& g& [7 \  d* \: `. S
3.  差分曼切斯特码解码# ?2 ]: T8 B1 \9 Q7 L% H) w

  1. ) ^- U1 A2 E- U1 Q8 E/ t) |: l
  2. unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };0 X' S% B2 R, T& K% i
  3. unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };- ?4 a' Y5 S# i' ~  n$ {. Q1 U
  4. + b, X% R0 S, @$ M0 p! Q
  5. static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)# n( F3 n. N0 p1 z/ V) v/ V- M' ^
  6. {
    ; V8 r" F( V+ {- P
  7.     unsigned char i;5 {" p7 @1 E  J  L. @) O5 d5 [5 @
  8.     unsigned char tmp;6 P. u3 e+ a- r

  9. & G2 U! z( D2 V, d
  10.     if((nbits < 1) || (nbits > 7)) {+ D! u) q; i6 v) r5 U' q
  11.         return;
    4 H' x7 ?& h5 r' X* @. v
  12.     }
    ( @9 M( e, t  N. F% l3 Y
  13. $ E5 F/ t" A0 q: J" z  T
  14.     for(i=0; i<nbytes - 1; i++) {
    ! B( o- E" g$ i6 s
  15.         tmp = raw[i+1] & r_mask[nbits];! d/ V, W, P& G$ i  Z, ~8 y
  16.         tmp <<= (8-nbits);. z7 M. k  d8 d3 l: R
  17.         raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;6 f5 k+ u' l/ v. Y* Z0 d6 D8 b
  18.         raw</span><span style="font-style: normal;"> += tmp;
    7 [, V% l% L0 {  u: E1 Q- a
  19.     }( |& {& \! w0 N0 V' i" N8 U
  20.     raw</span><span style="font-style: normal;"> >>= nbits;
    8 H$ O8 x( \( h+ n8 \
  21. }
    ) a4 e/ g# x  {% ]) Y; o2 r5 g
  22. ) L% ^8 U" l* r& k
  23. static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)6 [- ]. F6 }6 K4 `3 U
  24. {6 o1 ~& }0 y( h4 ]
  25.     unsigned char i;
    5 w4 R  |3 T( R/ N; r8 }$ X
  26.     unsigned char tmp;
    5 Y; T: M1 ]9 ~% k+ W' @

  27. & p% d  j1 ^4 p
  28.     if((nbits < 1) || (nbits > 7)) {
    ! e9 u) ]7 G, p/ `% ~
  29.         return;
    5 r# P, Q: ^- n% O8 h1 ~
  30.     }
    3 t2 F$ L$ A; h# s) O6 r# M; Z# {
  31. , B) O% j* E4 v' R& @( F9 J
  32.     for(i=0; i<nbytes - 1; i++) {
    " k. k$ \5 {9 ]. h
  33.         //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;  ?/ D/ ^# h9 i+ e0 [, ?
  34.         tmp = raw[nbytes - i - 2] & l_mask[nbits];
    : n4 E; r/ ]! P1 o
  35.         raw[nbytes - i -1] <<= nbits;5 ?) C1 e) {6 p* ?) T& @4 I
  36.         tmp >>= (8-nbits);  p5 f  Q" Y: c; \
  37.         raw[nbytes - i -1] += tmp;
    9 q7 C. V; D  p0 [4 u
  38.     }
    $ ]' r* R! {! c, G5 N, d/ H7 j
  39.     raw[0] <<= nbits;5 l9 x4 p' ?3 p4 _8 i
  40. }3 _- e9 {/ o6 Z' M/ o- {( K- u2 S  L

  41. & S$ i5 P& X( \) Y4 A5 }* t  F
  42. static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)- U0 ~* l* l) y  O/ v9 d
  43. {
    " _1 z' x1 B$ e* @5 e5 W8 T9 b
  44.     unsigned char x, y;
    2 |6 b* J. d$ w& n% Q( x
  45. / {& |- E; e# c' t
  46.     x = nbits / 8;
    , S9 @. d0 o' t7 h8 p
  47.     y = nbits % 8;% ]; O6 r! H% q

  48. / v  a' @, S5 b1 [3 g
  49.     if(x > 0) {* S( Y, j0 O: ?0 v5 \
  50.         for (int i = 0; i < nbytes ; i++) {
    1 v) Y3 h* ^( s& @1 \0 \. H
  51.             raw</span><span style="font-style: normal;"> = raw[x+i];. [% Y' G6 t6 F, C4 a4 M
  52.         }7 H3 A# b  {, @6 L4 k
  53.     }
    0 x6 O! _# t6 i2 R6 {! I0 ?
  54.     move_right_linear_timecode_raw_7bits(raw, nbytes, y);4 a+ H# ?; d( \2 P, E
  55. }7 u8 j$ q  ]: U1 [' u, I

  56. 7 Q% N3 z) O0 c+ R% D

  57. 3 |: Y. K4 G+ ]
  58. static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)
    " o; ?* U, s% u5 J3 ^6 N) S! L- m# v
  59. {$ g8 f" G" l) c8 b* ~7 }1 _
  60.     unsigned char x, y;
    ! e$ G* T, p. x2 Y9 n/ t6 O; Z8 C8 n

  61. 1 f5 z; ?4 l  g; g: ~' x7 q# p
  62.     x = nbits / 8;
    ( ^8 n: T8 x' F: l1 ?8 x
  63.     y = nbits % 8;& Q  @" A8 s' @0 l$ E" n
  64. # a0 f! _4 O& z  a$ t0 b
  65.     if(x > 0) {
    ) B7 _! F6 }! l5 }* B$ K: Y; S
  66.         for (int i = 0; i < nbytes ; i++) {
    6 B# d% @- k5 l* L) R$ ]
  67.             raw[nbytes-i-1] = raw[nbytes-i-1-x];% Q# V( P/ t/ h
  68.         }
    1 Y3 G! I) G2 }
  69.     }
    4 h5 ], _! L8 U& g. A" A# \
  70.     move_left_linear_timecode_raw_7bits(raw, nbytes, y);8 W- f# h1 W: q3 p; G6 H
  71. }
    . j  D8 q$ q; i6 I4 ]

  72. 6 @7 H- b) X9 k7 o
  73. unsigned char get_bit_linear_timecode_raw(unsigned char index)
    7 l, D4 A& @& [3 `
  74. {
    % `1 T2 o1 ]" g1 ]% E
  75.     unsigned char x = index/8;/ I7 \1 {) O4 s; K8 D; n: @( x
  76.     unsigned char y = index%8;$ w' ?) |, H- k5 ]

  77. ! D; y9 R0 E2 \' g6 y: w. ?, E# @
  78.     if(linear_timecode_raw[x] & (1 <<y))
    ; L! g6 n! R$ \; R# k! J: ~7 j
  79.         return 1;
    $ k9 d; ]6 i$ W* N9 l" s* ], Y/ i
  80.     else
    ( H5 ^4 W8 ^' A; C6 B
  81.         return 0;
    9 B. e" h) e6 j  b1 i' Y
  82. }
    : x2 B2 I- m. W% P: Q

  83. 8 h. P! D1 U) r1 s8 l
  84. static void parse_differential_manchester_code(unsigned char *src,  unsigned char *dst, unsigned char dst_size)) [" C0 q; w6 P; b
  85. {
    " z' p3 K7 q& w0 n
  86.     unsigned char i, j;
    - W7 X5 Y/ |. i) j) M; [" r
  87.     unsigned short tmp, tmp2;; b4 v) ?8 [  F
  88. / ^9 ]3 V7 A. C1 D
  89.     for(i=0; i<dst_size; i++) {& h8 ~  \- z9 ^4 @; q  R7 a
  90. & ^1 }: \& w* C9 B1 B. E% e
  91.         tmp = (src[i*2 +1] << 8) + src[i*2];1 u' X. i* J6 E* V! H
  92.         dst</span><span style="font-style: normal;"> = 0;
      B4 o4 y: i7 }: @& h% r3 B- t. I
  93.         for(j=0; j<8; j++) {
    & W( _- Q# p- X( r! Z4 m
  94.             tmp2 = tmp & (3 << j*2);6 U( V3 q8 O! @
  95.             tmp2 >>= j*2;2 b. G/ j  I4 E* y# I. m1 c
  96.             if((0 != tmp2) && (3 != tmp2)) {$ Q$ H/ l0 @& \6 q+ x' o
  97.                 dst</span><span style="font-style: normal;"> |= (1<<j);
    0 T' t6 E# b: z
  98.             }: E. E8 W' K8 }$ y, P# `
  99.         }
    ' I* ?2 Q* Q& F$ ?& f9 F
  100.     }
    4 ]) W+ J% j& T" q7 A
  101. }
    6 O7 e. q4 c+ ?; M# D4 x# [
  102. ! ?" l2 d+ _" m7 @
  103. static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)
    - r; Z& u% r2 ]; j, f+ H6 ~
  104. {
    / T0 e8 v  y. O; ]* Y
  105.     const unsigned short sync_code = 0xFCBF;
    7 @9 K4 N6 U) x3 m; n, e" f
  106.     unsigned char i;, x( ]& I! u/ y+ _& j  S# o& [
  107.     unsigned short tmp;' ^+ D" G& s  X6 b' G) L
  108.     char ret=-1;
    ; y4 l( m4 H( u+ j

  109. ) Z2 x- m- Q* C
  110.     for (i=0; i<len-8; i++) {
      F1 l9 d  e* f9 P
  111.         tmp = (src[i+8] << 8) + src[i+9];
    3 q6 o2 G" i. c1 m6 Z( p
  112.         if (tmp == sync_code) {
    ' X' J! g4 f8 U& n" w
  113.             ret =0;% f0 M6 g4 \& r' ?, k) |  }
  114.             *valid_len = len - i;
    : d% \2 t/ d! ~. W0 p
  115.             memcpy(dst, &src</span><span style="font-style: normal;">, 10);   //10Bytes equals 80bits
    ' q) o$ a. H+ h/ W6 w2 n
  116.             break;. W2 s; ]" M5 Q2 q
  117.         }0 v9 C3 ^: k% o8 I% \$ M6 ?
  118.     }7 e( N; z1 M- o6 c$ U8 k. l; [; X
  119. . P( y' h  Y- s2 z, U+ [' o/ H8 \
  120.     return ret;! k  I0 V3 Y- T2 f7 s: n
  121. 5 Z; M! {4 z  O* R8 y+ j0 f
  122. }
    5 `% V$ U6 `% D5 ]! \

  123. + G+ K" W( q8 h' m, D; r
  124. unsigned char ltc_dst_code[40][10]= {0};0 x+ j+ ^- {; L, y' x3 _1 a
  125. unsigned char ltc_dst_code_count = 0;4 Z8 d8 s+ p6 p+ w
  126. unsigned char ltc_code_valid_len=0;
      A, M$ ^) E: q
  127. unsigned char ltc_code[20] = {0};
    " \) ?" n+ I" ]' d: }, a
  128. unsigned char raw_ready[60] = {0};
    - K- c6 {$ \8 p7 c3 W$ z. }
  129. unsigned short offset_bits = 0;
    : \' ^5 Q2 u- C9 b  Y# m1 ?% g, y
  130. unsigned short ltc_remain_bits = 0;/ [7 Q8 P" k3 X" F! [
  131. unsigned char sec_ltc_code[20] = {0};
    * c* }( G' \. U, n
  132. unsigned char ltc_dst_code_cur[10]= {0};
    ; _  m0 k9 r. a# @; |+ m* P
  133. unsigned char new_frame =0;& C; n' {1 c# Q# x; p. q
  134. $ L; \. s# Y$ n8 P9 ?: q2 X

  135. ! A9 j$ E1 S0 D8 T1 V
  136. void parse_linear_timecode_raw()
    ( E6 L7 l# g# _' O' C+ l
  137. {4 r7 e, J) ~& Q2 _4 j" ~8 T" C) l
  138.     unsigned char tmp;+ r; r; Q* I0 H& }3 z; y
  139.     unsigned char raw_mv_right_bits = 0;% {+ `2 o  T" ~# q6 z1 C6 G( m

  140.   z" k9 P( X# h; d9 Q6 Q
  141.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    5 \' c4 ^( `2 m) [, R+ U1 @" Q% l& y
  142.         isjam = 0;
    6 \, k3 W# C; V6 ]9 j0 v: `6 }; h
  143.         memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));
    4 @& i9 y/ L+ g% ]
  144.         tmp = raw_ready[0] & 0x03;* Z5 M) d* m& Z/ d3 A1 h& _
  145.         while((0 != tmp) && (3 != tmp)) {5 i' M4 K1 x: l: `
  146.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);+ u* q! e. d& ~1 F- F- }. U
  147.             raw_mv_right_bits ++;
      X, p. Q. @6 ?: }
  148.             tmp = raw_ready[0] & 0x03;
    . x6 @6 l0 w$ e8 R- B
  149.         }; ?" x1 h. x  i8 m% N/ G" {  W* v, C

  150. 8 v! B4 w' ]% m1 ~% V# U; z
  151.         for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {9 p$ D% y" N6 U
  152.             memset(ltc_code, 0 , sizeof(ltc_code));4 x0 A2 [) v0 z+ ^
  153.             parse_differential_manchester_code(raw_ready,  ltc_code, sizeof(ltc_code));
    ! w: I9 V$ @0 \  z8 H9 d8 j
  154.             //0xFCBF;) X* K( z! D) J; a6 b7 C/ X, w
  155.             if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {
    * g0 K+ m/ G7 f
  156.                 linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;
    0 ~' T: C4 g. w" F# A
  157.                 offset_bits = raw_mv_right_bits;* |  v  i; T6 j  k+ w; i* I
  158.                 break;
    ( E6 b0 X6 P: h
  159.             }, B6 \5 W) M9 N9 y
  160.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);" l. c( R& \; {- ]* L! V
  161.             raw_mv_right_bits ++;6 Y. x, }$ n- L1 u5 ^8 K
  162.         }
    ) H8 C& Y1 E8 H" O4 `5 Y
  163. % M; E, |# N  p: \# Z( B
  164.         if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    4 B+ K  W/ g6 e
  165.             LtcInput.tim_count = 0;     //reflesh tim2 period
    * W2 D$ ^- Z* q& F/ R- P
  166.         }. w- r' V' n! \" t6 |6 W0 X. h3 D8 Q

  167. 7 W1 h& u- {. Z& m& d) {! b: u/ b( F* Z
  168.     } else {
    % H7 W: T6 X+ D) ?1 \* a+ g/ _" N
  169.         isjam = 1;
      @( S; P* A, i$ e
  170.         memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));
    7 I8 R, H+ o8 y
  171.         parse_differential_manchester_code(ltc_code,  ltc_dst_code_cur, sizeof(ltc_dst_code_cur));
    & h. j/ A6 s, I! D+ V7 C, r
  172.         if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {- \2 o6 I& s3 t, D& i9 H8 h
  173.             linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;9 x+ n' `5 |3 u+ Z' O
  174.             LtcInput.tim_count = 0;     //reflesh tim2 period- {; y. R; h9 Z0 X, z. ]
  175.         } else {
    5 f6 y! f& A. l% l  |
  176.             new_frame =1;
    7 S! q% c( \, z! \. K/ _7 ?
  177.         }
    % E5 v. z  H$ J* t3 f
  178.     }
    7 a# i) {; p( h. @! H9 H
  179. }
    ( K! e$ Z+ S& v- R+ T5 U, q" Z
  180. </span></span>
复制代码
2 W' t9 D& o' `; O

) Y) b  ^6 A8 R# {8 X总结以及调试过程中发现的问题。
) [- h; L& I7 b! i+ X& h" v0 K3 r4 v; Y( }* y# m6 z: [; f% k
1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us
9 p% m# F' ], y8 B  s( R7 y
) V& Q  _0 u: K9 @) g( X
20201127114629167.png
6 A2 P) ]8 \/ `

3 k  X: ~. ]4 Z2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
* v: v& S, A; h5 M+ A- t- T: `! ]) t& H4 p% J/ R1 P& v5 E
异常1, 中断回调,里面调用HAL_TIM_xxx ,  导致反复进入定时器中断,3 A1 g3 x* I4 `: j( _" h2 u

! N  q# D) m4 d, k% F
20201127115308255.png

* D- W+ E: z, c0 V& k! R, x; I/ Z
异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行
4 Q2 J8 Q. o( y9 [# C% ~
5 H# i. b0 ]3 f  {" d: q4 R
20201127115925296.png
" F" x% X! V4 y. A! W, H+ o

7 Z3 W, k& i% N0 s9 a3 W& z解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形
8 K; D1 Y* B# D, `% u
  1. void TIM3_IRQHandler(void)
    5 [* {+ h5 @0 e" Y% p
  2. {# I- c- ~9 w# U3 h3 k" ~& \
  3.   /* USER CODE BEGIN TIM3_IRQn 0 */8 @/ {  p6 k. T- A
  4. & C5 O) n0 q# y: H; _" c
  5.   /* USER CODE END TIM3_IRQn 0 */
    # r# a5 g2 {! a6 R3 @" A: ^
  6.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
    8 z5 h: @6 a' ~# n8 s, k
  7.   htim3.Instance->SR = 0;
    , I/ @0 l. X/ a. k' _# K
  8.   htim3.Instance->ARR = LtcInput.period;
      e9 ?, j1 k* I5 J) H( G& m
  9.   htim3.Instance->CNT = 0;
    & q* r) O3 K) Z; O  h# q, ~
  10.   ltc_input_timer_callback();
    5 V$ m: J) |/ ]! N4 N% |

  11. ; m; I$ [+ p& L. R1 v. {  D
  12.   /* USER CODE END TIM3_IRQn 1 */4 i* i) Q9 n9 c( G! L5 G
  13. }
复制代码

4 A$ p( B  _0 j% ]& ?; |2 T( Q: V$ |
20201127120550172.png
4 N/ ^1 W# `8 m) r# {- t

. N& j8 O" k  Q0 P, B
收藏 评论0 发布时间:2021-11-14 23:04

举报

0个回答

所属标签

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