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

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

[复制链接]
STMCU小助手 发布时间:2021-11-14 23:04
时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,
4 W4 {( E! i2 T* T! i  C
* B' b9 t) F; H9 V6 f( \
20201127093851207.png
1 Z9 W2 M1 _' G8 z" l
! }2 R2 Q: e6 }- p+ Z+ K* P) {

6 A$ v# Q0 z% a实现原理,: N) _' Y/ t( Y$ F+ C/ ~/ L! A' U" M/ {
+ y+ @, n6 j  r( H4 F
1.  EXTI  Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period
- t- }2 O7 {" s2 Z+ N
: J! X- [) |9 W2.  继续用EXTI  Rising/Falling 中断+定时器方式接收时间码0101值, EXTI  Rising/Falling 中断时,修正定时器中断周期为Period/2。
. N2 U' _, U8 \- }0 D! |" q8 G! p, T' K
产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period
2 P7 c! t7 E! P3 X5 ]" h
- V4 u4 Y3 `' W  z, }( n3.  解析差分曼切斯特编码,查找同步码
' }2 {. P! c2 U  y0 o& N) l
% D) _% N' m5 y1 E# i1 Y流程图,% `% s% K* k6 `+ d9 @0 E

% X& T6 e+ _2 d3 s8 o
20201127113610958.png

+ S+ W: d9 v5 u1 o$ e! x# {, M8 @  f! U, F7 C: g

" O$ y' L  j' L关键过程代码,
) l6 i0 ]1 Q+ S' R6 U) V0 h: w9 U& o: O( _
1. EXIT 中断处理
# r5 d( b* O0 H7 a( E  y8 T0 `( @1 Z! k$ `9 u: S
  1. struct LtcInput_s LtcInput = {4 W8 s" P5 ]6 j& H
  2.     .tim = {0},
    . j  @8 d) M0 |& Z2 T* _
  3.     .tim_count = 0,
    0 g+ H3 r, f5 Q! x
  4.     .period = 0xffff,+ ^/ A2 X' ~( d% T% Z5 m7 \
  5. };5 }& X) |3 O8 x" P
  6. 8 ]" z! C! x* p4 ?+ ]$ K3 X
  7. static uint16_t parse_tim_of_ltc_input_get_period(void)* ^) ~/ W( k$ A* _' x
  8. {$ [2 ]9 ]6 u% v+ k  \
  9.     for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {+ ~0 s  ^" [" }4 I4 V, E
  10.         for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {  a, O2 R) \& @' Z* @# w+ r
  11.             if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
    , e3 O. L' a- Y; u( {& w# |
  12. <span style="font-style: italic;">                uint16_t tmp = LtcInput.tim;9 ^/ T/ n% {& R9 s% A9 A) c
  13.                 LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];
    & U) U5 f% W) I! C8 G3 }. R* `% ^
  14.                 LtcInput.tim[j] = tmp;) k: }3 t, h# A! C4 v' @3 m  o
  15.             </i><span style="font-style: normal;">}
    0 s% y5 ^* u; V) {; p; P
  16.         }; y3 V* q( H% `$ o+ m( ]' J. a. ^
  17.     }: a' a+ I' x) Z+ p( {6 `& A
  18.     uint16_t period = LtcInput.tim[10];
    1 \! v1 G1 v7 R. t
  19.     return period;
    3 D6 I0 U" g; Y) {4 h/ ^( e) D
  20. }- ^; F7 ?7 l" O0 x1 J
  21. ! X& A, F  d# G8 ?. ^7 }2 b
  22. void ltc_input_timer_restart(int period)' Y1 r3 z0 T( Q5 w$ J- T" e# |. }
  23. {3 b# m4 F# [! ]

  24. + q2 A0 x& g2 m" c7 T6 @' k% }
  25.   htim3.Instance->SR = 0;
    ' W8 }9 l5 U1 P1 |1 g  Y! q! t& O
  26. htim3.Instance->ARR = period;
    8 R7 K. `8 z2 Z& B2 x$ K: L1 t% B
  27. htim3.Instance->CNT = 0;
    ; N8 |+ s6 X9 Y  M

  28. 3 J/ h( m- E3 ]" P' T
  29. }
    0 S$ K6 `2 E" i. @

  30. + n/ `/ b3 W! \$ b  {  S
  31. void ltc_input_pin_callback(void)  k2 s- q( i) h  N  r- V
  32. {
    # |, ^3 F# ]1 m0 S( q) B2 ^
  33.     // HAL_TIM_Base_Stop_IT(&htim3);3 r9 a) n" l7 g. e- S; W
  34.     if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {5 N* s, S: `0 A; ?: L* _
  35.         ltc_input_timer_restart(LtcInput.period/2);
    , O9 `2 m/ M. {! |; D. H7 e1 [" @
  36.     } else {4 h: d  Z2 D/ F: S: L. j8 N2 _
  37.         LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;. O, ?# I& F7 T
  38.         LtcInput.tim_count++;
    ; {" G4 }3 D2 f  l; Y2 B7 ]
  39.         if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {# Y. j- h1 m% i$ J0 N, h
  40.             LtcInput.period = parse_tim_of_ltc_input_get_period();7 q" e; n  i& e
  41.         }. G$ z( I4 x+ Z; h! X  O4 V, C2 h* {. K
  42.         ltc_input_timer_restart(0xffff);
    2 b1 R. r8 {; g3 Z3 H0 M+ q5 r
  43.     }4 s! [. `: i5 H- d3 ]& o- r; F' z
  44. }</span></span>
复制代码
, a$ t7 }( |) z
2. 定时器处理
  T7 l6 r( X" }" P2 V$ x$ L
  1. /**2 d5 K/ P% w4 U2 L# R0 H0 r1 D
  2.   * @brief This function handles TIM3 global interrupt.: @3 J. V7 V; W" V/ }' n2 a1 o) w% [
  3.   */2 t+ N4 z6 x$ i$ w1 I$ {
  4. void TIM3_IRQHandler(void)
    # ^$ C, |! v5 W1 F
  5. {$ _% A. h9 a, Y) |+ x
  6.   /* USER CODE BEGIN TIM3_IRQn 0 */9 t9 Q: U5 ?: L& L9 f8 s
  7. - `' h1 i( y5 h8 s" i' I  |
  8.   /* USER CODE END TIM3_IRQn 0 */
    $ U) ^3 X7 e+ M+ y; R0 c
  9.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);  k0 o3 D4 O. ?1 z- _) `( e6 R
  10.   htim3.Instance->SR = 0;
    7 s0 I( O/ }" s# C: |9 o  L
  11.   htim3.Instance->ARR = LtcInput.period;: D9 ^% E1 K+ I/ ]8 f) l: S
  12.   htim3.Instance->CNT = 0;" |/ F4 M+ C" U! L5 V8 Y$ {6 z
  13.   ltc_input_timer_callback();
    ! U+ n+ g9 O% A. ]' s

  14. + Q( T$ s' `1 ?# y2 V) }# [% U
  15.   /* USER CODE END TIM3_IRQn 1 */
    $ \6 g* [. J% u- ~. l
  16. }
    : d6 k  h" m8 @+ x: D8 C
  17. / l. a% _) b/ m, c4 y2 y
  18. char ltc_input_timer_callback(void): c6 {* e) @1 h8 o9 p: F
  19. {
    . J, h* I9 j9 }/ [) G" B* I7 e" s4 W
  20.     GPIO_PinState status;" B% F8 ]9 O1 r, o2 L" [
  21.     unsigned char x, y;* P6 s0 T6 G/ D) C" [

  22. 6 ^0 E0 ~) J0 n3 J4 Y6 i, R
  23.     status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);
    + Y- ]% a$ n. I1 z8 h) {" Y
  24.     //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);
    * y& U; a* H& i) ~9 {4 I
  25.     //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);8 `. J1 B4 J. O
  26. * V. N0 P) @" z" u' X7 J
  27.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);& b) J: J: w2 @
  28.     //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);
    : K5 q( ^& K) X2 Z5 N0 z/ ~" v/ S
  29.     //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));
    ! L2 k! D+ G( r7 V# T: q  c
  30. 4 C7 [$ S! \! Y9 g
  31.     x = linear_timecode_count /8;
    " \3 }- B. {: ^! {2 h) r, f( ?
  32.     y = linear_timecode_count %8;
    / C! b; G" ]0 |" R* i! N

  33. ! J* ~, t! i1 G
  34.     //buf[linear_timecode_count] = status;- `0 [, R4 D) F  a
  35.     linear_timecode_raw[x] &= ~(1 << y);4 Y0 k6 U7 F; A1 p" b9 n, U+ U

  36. 4 v' E9 Y3 n2 c3 ~# K4 p
  37.     if(status != GPIO_PIN_RESET) {, k9 B; T# O% E, t% \) ]* a( f/ X
  38.         linear_timecode_raw[x] |= (1 << y);
    . _% R5 b+ U& t5 [$ `' l9 r
  39.     }0 m+ A. _1 `, L2 t9 P

  40. 8 S, ~2 w2 A# d" H
  41.     linear_timecode_count ++;1 U! ~/ v+ o' ~/ K- t7 `% P
  42. + K2 o, W5 _5 P$ v( h3 l) T
  43.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
    $ h' V6 z* p3 K; R) e: }
  44.         if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {% |4 E  |6 N# ^$ |& `  X
  45.             linear_timecode_count =0;- l" @9 a  K( ?9 E
  46.             memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));7 I- E2 h$ r1 t) W3 U3 @( u% v, }* p
  47.             linear_timecode_ready = 1;' z7 `& c1 o1 L( E
  48.         }
    " f/ x1 H' U; J, |& d
  49.     } else {) q7 G9 h; h1 ^4 a# _5 P1 L& D" H
  50.         if(offset_bits > 0) {
    & v% j& a( ^, i( [* x
  51.             //skip offset_bits
    ; J1 W$ T) R3 C* a6 K8 y7 o
  52.             //If offset < linear_timecode_count, adjust the offset to the next frame.
    9 f4 y  i. a; g6 `4 }/ w( P; c% \
  53.             //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.
    ( O5 t8 Y( H! i' E" S3 r
  54.             if(linear_timecode_count > offset_bits) {
    6 W2 f! M, J/ d" ]; F8 K- g
  55.                  offset_bits += 160;
    ) S3 C, N) C5 N1 k0 R' D
  56.             } else if(linear_timecode_count == offset_bits) {) B0 c; Z4 i- A/ }
  57.                 offset_bits = 0;
    ; T* u5 j# ^6 z2 j$ z
  58.                 linear_timecode_count = 0;
    ' B0 k/ T! Y3 r0 N1 H! G
  59.             }
    / {, A' M' h2 u- c/ x
  60.         } else {
    9 C' D$ ]) p0 h4 r+ f; r
  61.             if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {4 A; B+ }5 l1 P
  62.                 linear_timecode_count =0;/ b" H2 S+ o# s. \& P
  63.                 memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);. t& t4 Q- ]0 V. H0 a* v" r! z
  64.                 linear_timecode_ready = 1;
    8 ?3 ~2 U* L" e% C. a6 V
  65.             }
    & A3 n# O4 j. }  }- u; E& Z/ L9 m& @
  66.         }
    * y3 p6 u1 u* z9 q7 e: K. X* r
  67.     }
    3 g# ~8 Y, P: I3 U9 j& \. X
  68.     return 0;
    / O/ C* t' c% ]) i5 D; j& y
  69. }
复制代码
! h. g  D( `1 x( q9 t% C
3.  差分曼切斯特码解码
& a+ N3 U$ _- L

  1. 4 D0 p9 `* Y# W% s; z
  2. unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };7 x! B% p' p& ^& y
  3. unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
    ( z, W) J& d7 d" I" [. _+ r2 J5 X

  4. / Q; E. J2 \# {8 X' ^7 m
  5. static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
    5 Z8 c% l- S1 u  I' Y
  6. {4 i9 g+ H# H0 F0 Y' Q! t
  7.     unsigned char i;6 v1 g$ [) M  T( P& K& [# n# J
  8.     unsigned char tmp;5 n5 ^- y, c. i8 q; w" n% Q' F$ }

  9. " k& a. F; k! j* U: v/ y( g0 r( W. _1 Y: \
  10.     if((nbits < 1) || (nbits > 7)) {1 Q; l2 i! T4 {8 H+ B1 n
  11.         return;
    + |7 q- V9 ~/ A0 B4 l3 ~
  12.     }9 l# V% M1 I: y2 _1 t

  13. ; y% A) ]! G6 g- a) ~1 N7 L/ v0 D
  14.     for(i=0; i<nbytes - 1; i++) {
    ( K  e, g5 |1 J& h! c* }
  15.         tmp = raw[i+1] & r_mask[nbits];7 }4 q1 J5 s) r/ U, l
  16.         tmp <<= (8-nbits);1 ?# j# Y- D& s& G1 U( s, o9 g
  17.         raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;6 n; ^9 U# I. |1 {( x6 Q
  18.         raw</span><span style="font-style: normal;"> += tmp;: I8 `  J+ d" m2 l* `/ q. c) E
  19.     }5 F+ c( q# X$ P# r8 v$ t
  20.     raw</span><span style="font-style: normal;"> >>= nbits;
    2 {- Q( ~  h. e; O# q* P
  21. }
    8 x0 x( U4 g. C; d' z- E

  22. & z* R. g3 ^( {# z+ S1 A- e( w( _, O
  23. static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)' _6 z6 {' T* h2 o3 q
  24. {1 w0 Y! t: G8 z5 {, d2 e
  25.     unsigned char i;
    " B* l8 k* o4 u8 P/ `, o. M( A4 w8 h
  26.     unsigned char tmp;
    6 k, n5 k2 c* ?$ T0 V6 I

  27. ( z; |, X3 W7 ?) [* K, e
  28.     if((nbits < 1) || (nbits > 7)) {4 ]9 Q# r9 Y, t
  29.         return;
    ! u* L1 [& _6 `) U
  30.     }
    $ G( g$ s, f( S! p" V

  31. % g1 M7 R' h$ Y* J4 A
  32.     for(i=0; i<nbytes - 1; i++) {
    & f/ C% V: K) J# ^
  33.         //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;$ ^7 W, D( _3 i) X1 j- {; j0 [
  34.         tmp = raw[nbytes - i - 2] & l_mask[nbits];
    / K! O3 }1 n1 m6 x
  35.         raw[nbytes - i -1] <<= nbits;
    / R. D1 T6 M! |, I0 E; f
  36.         tmp >>= (8-nbits);9 U' w' c% U$ M2 Q2 X
  37.         raw[nbytes - i -1] += tmp;1 b  r! u# p1 y, e/ K# Q' ~
  38.     }- {! |- i- W6 U4 Z2 `0 L* f3 f3 D4 _
  39.     raw[0] <<= nbits;
    3 m% G' e  a$ D2 s
  40. }
    : P2 z" G4 x: x) [
  41. 0 n8 c% j; Y, L4 u
  42. static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)) A/ q: |0 I: E2 P4 w
  43. {  @+ ]/ Q. G5 ]8 ?1 S
  44.     unsigned char x, y;6 B& h+ j) r- t+ ^3 W+ h; B, U* e
  45. & l2 C. w0 \! ]% K. j" e1 M
  46.     x = nbits / 8;3 |9 s# d- W2 x! W
  47.     y = nbits % 8;8 j4 h# W3 ?3 f3 e
  48. 8 u, }0 g; ?& @- D
  49.     if(x > 0) {9 D" l; u7 q+ i
  50.         for (int i = 0; i < nbytes ; i++) {
    + \* V# c; m, w; @4 ?
  51.             raw</span><span style="font-style: normal;"> = raw[x+i];
    . R0 Z7 |! z8 P0 Y% O
  52.         }8 a# {/ J- N- f+ J5 S
  53.     }0 d. {3 ~- w1 w/ L
  54.     move_right_linear_timecode_raw_7bits(raw, nbytes, y);
    " n% a  G8 T- d, ?
  55. }; a: f: O- z# Y
  56. : J& e1 U9 ^( X9 x( I
  57. 0 c9 d' C# Z% v) I! Y
  58. static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)
    9 K' Z: m1 O8 r9 R" h$ x" B6 _3 |/ O
  59. {
    & F8 A) I1 J5 q* u/ _4 {* n; ?% O
  60.     unsigned char x, y;
    8 b7 n+ n, R" @8 S$ u. N( M, |: g, J/ Y+ X
  61. * J) B! M7 [. z& X# [
  62.     x = nbits / 8;
    ) G- H" l4 [" p1 E1 N/ ]1 |& L/ m$ R
  63.     y = nbits % 8;* S' |3 S6 |7 |4 k9 q2 e
  64. # b1 T5 l1 v* ?+ q
  65.     if(x > 0) {
    5 s3 {9 X6 @* w! E! v: a
  66.         for (int i = 0; i < nbytes ; i++) {) ?8 x# R( V  x  t9 E
  67.             raw[nbytes-i-1] = raw[nbytes-i-1-x];0 v7 N8 u3 D7 o) t2 v
  68.         }, o: D7 _3 u9 X+ ^+ E
  69.     }1 I$ j; m5 Q- T: G
  70.     move_left_linear_timecode_raw_7bits(raw, nbytes, y);3 K/ X; N8 z' K" I; a& R
  71. }  y* Z2 i9 t0 R& T! F
  72. ! n4 p. D4 p+ M: I$ X, o5 |7 Y6 a
  73. unsigned char get_bit_linear_timecode_raw(unsigned char index)' {7 l7 J" d- f
  74. {
    & E) T! x5 \: H0 g3 d! |  S- w! |
  75.     unsigned char x = index/8;
    6 m1 |( k1 M" g7 K  S
  76.     unsigned char y = index%8;
    ) L' B8 C' y3 X7 Q+ o" t1 Y
  77. ( y' k. B2 X& m" ^- P
  78.     if(linear_timecode_raw[x] & (1 <<y))9 ~9 X0 ]# P2 D$ u
  79.         return 1;" a" X' v9 O( e5 I
  80.     else+ Z  J6 r$ D# b7 {
  81.         return 0;
    / a$ E  i; s! B/ P& w
  82. }
    - h& R8 A  `  s1 D! f! A5 n
  83. 1 H2 ]1 v/ e5 s% J. r/ @
  84. static void parse_differential_manchester_code(unsigned char *src,  unsigned char *dst, unsigned char dst_size)
    2 o9 D& X! y& F8 e( D% u' Y6 X% V
  85. {& b& O9 x; K( o' t
  86.     unsigned char i, j;
    6 ~# Q; S9 `, g: I, p
  87.     unsigned short tmp, tmp2;* i) \4 y6 |$ M) g" b' A# r. ]# d# D
  88. % t' S! D2 r, _7 o% w! u
  89.     for(i=0; i<dst_size; i++) {
    7 e3 p  O+ E5 x" T( \7 }
  90. 7 \, `* `" G7 g- l# \% n. ~
  91.         tmp = (src[i*2 +1] << 8) + src[i*2];
    1 d# ~6 ~7 n  @4 e6 A: O4 x
  92.         dst</span><span style="font-style: normal;"> = 0;1 t% O  l& ~! |/ c
  93.         for(j=0; j<8; j++) {9 h' L9 Q& u  p6 D4 c: X
  94.             tmp2 = tmp & (3 << j*2);
    - Y4 C' c5 y9 Y  ^; w$ }  S$ q
  95.             tmp2 >>= j*2;8 Z( e9 ^/ q. ^
  96.             if((0 != tmp2) && (3 != tmp2)) {
    ' t2 K2 w# ?- w$ x5 t4 y4 W$ a3 l
  97.                 dst</span><span style="font-style: normal;"> |= (1<<j);
    3 I  v! H+ @1 Y) M; I, R5 h
  98.             }
    & [+ h9 _1 i" [" L3 u6 q9 `5 U+ B
  99.         }2 g( B, n9 g) h2 Q& `
  100.     }
    ) H* m* j, R  Y  u
  101. }
    8 g. }% Q4 E- L4 j+ |4 }7 Y

  102. & m2 h5 Z- i4 k) v4 Q0 g2 e7 f
  103. static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)
    9 B4 w+ y" t! S* d* L
  104. {3 G; _9 Q9 M2 J, i; b" B
  105.     const unsigned short sync_code = 0xFCBF;
    * e# ~5 `( e+ r5 q& f
  106.     unsigned char i;5 j: B7 j- I" f
  107.     unsigned short tmp;
    % {* n/ X; T3 l, x, G
  108.     char ret=-1;
    7 p7 O. T6 L  H- o: `1 G

  109. 4 ~4 y# N2 p: d% \: D( \/ z( T
  110.     for (i=0; i<len-8; i++) {
    " `" @  w, I; F; h5 N( U9 K
  111.         tmp = (src[i+8] << 8) + src[i+9];; v- R1 {" Z  X9 y% }0 ?. r  i
  112.         if (tmp == sync_code) {
    ' T0 n  n; A6 H! p6 K
  113.             ret =0;
    7 c8 ~0 o6 j+ h( Z, G5 {
  114.             *valid_len = len - i;+ P% _; c' B9 S- m# {3 h3 h
  115.             memcpy(dst, &src</span><span style="font-style: normal;">, 10);   //10Bytes equals 80bits7 l& e$ |9 m+ v
  116.             break;( ]2 o3 p8 M" Y) ?& t0 |- _
  117.         }9 f. V4 m% n! y- [* g- [
  118.     }
    , q( A9 u) u2 K; {
  119. 7 d5 s' `+ ?8 R
  120.     return ret;
    + r. {! Y, E; c- f* u( i  q

  121. 5 t: w; D4 D& P8 d) ^" o1 _3 U
  122. }5 n. X7 ^5 M) v! u6 U

  123. ( U! l* u4 S% {$ f: z. y9 @
  124. unsigned char ltc_dst_code[40][10]= {0};
    ) D+ Y' w' h! V# h0 m- b7 w% r; G
  125. unsigned char ltc_dst_code_count = 0;
    : R( b! p$ G4 U* e
  126. unsigned char ltc_code_valid_len=0;
    2 g: j: n( z# Z) p6 `; P1 ^
  127. unsigned char ltc_code[20] = {0};2 E) c6 W" |9 ?, Z, I  p4 }
  128. unsigned char raw_ready[60] = {0};6 s* Y. o" r, J; i3 k+ E
  129. unsigned short offset_bits = 0;
    ( \) v, _$ @# |1 d8 Q
  130. unsigned short ltc_remain_bits = 0;
    4 j0 `4 M0 e' @( G3 }  Y
  131. unsigned char sec_ltc_code[20] = {0};6 b* L7 q" J+ ?) q
  132. unsigned char ltc_dst_code_cur[10]= {0};
    % T* }5 e: w2 ~+ n- W. [
  133. unsigned char new_frame =0;
    ! S/ Y: t4 J; n2 h. l$ Q6 f
  134.   r& u6 v' o' }( M* i
  135. : U  b- }% P# Y1 K
  136. void parse_linear_timecode_raw()0 Z8 w; M9 s8 q8 f& r4 N% I
  137. {
    ! s0 Y, y& d: U) b9 z
  138.     unsigned char tmp;: A" ]) a6 G% n; i$ Q
  139.     unsigned char raw_mv_right_bits = 0;
    5 }3 o) A0 }) A: f1 w
  140. 7 k. y# I  U- u+ a
  141.     if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {) o' ?5 {( \2 D" h" B
  142.         isjam = 0;+ v$ c( x/ t6 ~& v0 `' I. T* V; U
  143.         memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));, f7 B" W5 Y2 y
  144.         tmp = raw_ready[0] & 0x03;
    6 p  m! o/ D2 h( z7 n
  145.         while((0 != tmp) && (3 != tmp)) {2 v1 `+ V1 R0 p: G
  146.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
    & _: T. s! _5 r! E$ B# Z7 Z8 F
  147.             raw_mv_right_bits ++;3 Y! V8 J: S; h6 V% U( C- J
  148.             tmp = raw_ready[0] & 0x03;& B7 _! @, Z: {
  149.         }
    # j/ m( e- ^; `

  150. 8 J- y' j% f( i: ^
  151.         for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {9 C' ?$ A% s" l7 a6 M% d
  152.             memset(ltc_code, 0 , sizeof(ltc_code));
    4 a& M- r$ a" S# G. _* G
  153.             parse_differential_manchester_code(raw_ready,  ltc_code, sizeof(ltc_code));
    1 a3 z8 t0 T2 O4 m: ~
  154.             //0xFCBF;
    & z% j) v& |* g) l- m' J0 w3 w
  155.             if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {) F; n+ s/ v! S- T/ Q: W5 W% C9 A
  156.                 linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;
    2 t* B+ `- H  c3 V5 X9 e' A
  157.                 offset_bits = raw_mv_right_bits;
    & p" W3 {/ ]9 Y6 j8 l
  158.                 break;
    $ N4 v- ?* R; T+ H, u$ [: d
  159.             }
    1 i; O% n5 _2 k. Y
  160.             move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);9 t6 @# @- J+ l; Y* C6 M4 f2 \
  161.             raw_mv_right_bits ++;3 G* t8 @& `) H" F' a8 Z' l5 s1 |
  162.         }3 f9 M$ W) y+ K% F- C1 b7 k" i$ f
  163. , p/ t7 T4 |: \* X
  164.         if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {2 B# ?" a/ s& D- `/ o* P/ B& b
  165.             LtcInput.tim_count = 0;     //reflesh tim2 period4 c. c3 u# y* a8 k
  166.         }" h8 q/ U3 f# C! }% W
  167. 6 V& c: O7 |3 J7 R* V2 C
  168.     } else {
    1 l. \$ A2 a3 l
  169.         isjam = 1;
    ) t5 j6 d  n: D, |* H7 J
  170.         memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));
    ! H+ A1 f. a2 |' n, `/ Q
  171.         parse_differential_manchester_code(ltc_code,  ltc_dst_code_cur, sizeof(ltc_dst_code_cur));6 ?+ ?' ~- f8 C. ]7 A
  172.         if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {
    $ f4 {7 ]  R6 Q  u% Q) Z
  173.             linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;
    + k% [/ v3 I1 x( M/ i( c* G: q
  174.             LtcInput.tim_count = 0;     //reflesh tim2 period
    / K" m/ d2 q+ M* X
  175.         } else {
    , {+ h6 y7 G/ I/ e8 ]
  176.             new_frame =1;
    0 z5 U  C5 R2 {, _( W( O3 x
  177.         }+ x0 X. X  z9 X5 G$ k' R
  178.     }" U6 g& q7 A5 \, w3 E
  179. }( K/ r1 R$ f! m4 Z
  180. </span></span>
复制代码

% O- X7 }1 t2 E
' d; a% V' |) w) X总结以及调试过程中发现的问题。, b- R- Y4 q2 P1 l- j1 B5 Z

, e4 ]6 k8 D6 H1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us- Y$ V+ `7 G# ?2 N

! [  ]; Y5 ~/ q0 P9 w8 A
20201127114629167.png
: s; \1 H8 r3 g9 s! Q9 z
2 d# q4 n% e: `' X* A9 b# @
2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形" w! F& d& F1 e1 V/ }

+ T1 f, w9 |  q3 e8 P异常1, 中断回调,里面调用HAL_TIM_xxx ,  导致反复进入定时器中断,- b! A- j. a$ T

  [, T5 ]& |6 ]1 v# @9 S3 p, g
20201127115308255.png

' K. D: l7 V; @3 h6 P5 g2 n
- w) P# @! u# ?. o. I7 ]: a' i; G异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行
+ n4 I2 g: n  e# f
( |9 S* k: B, X$ l# B% T
20201127115925296.png

5 H3 D9 Z) I2 A. u3 A' c- ~/ o7 p
2 I" D1 `* }1 E解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形6 w% |0 z6 B; R6 _: C' B/ l, _: P
  1. void TIM3_IRQHandler(void)
    , b6 t4 U$ g& V: ]+ w( _$ z
  2. {: k5 c+ m3 F" y; P3 R  W* r
  3.   /* USER CODE BEGIN TIM3_IRQn 0 */
    / Q/ H5 s! B; \% V

  4. 3 r0 ]% T& l0 f- j( s% g1 J
  5.   /* USER CODE END TIM3_IRQn 0 */: O& K. H0 \' I, X
  6.   HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);/ y" R8 F- K/ T( s2 Q' [. [3 w
  7.   htim3.Instance->SR = 0;& e, w" _6 {( ~) X
  8.   htim3.Instance->ARR = LtcInput.period;
    * z$ L, Y  ?3 D" r
  9.   htim3.Instance->CNT = 0;4 s* Y: m' {: `7 K/ Y  P
  10.   ltc_input_timer_callback();
    2 c. Y# d% l3 o% U& z8 h

  11.   E# {4 c6 X: k; i# R
  12.   /* USER CODE END TIM3_IRQn 1 */( X) m7 Q9 g% V
  13. }
复制代码
- L: b! |% I7 V8 T: K

3 [0 Q1 i+ N% w0 @  \
20201127120550172.png

- j0 g( e* x* \2 k( f
8 n1 M0 Z' b  Y; C9 }! Q
赞 收藏 评论0 发布时间:2021-11-14 23:04

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版