时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,
( D p1 w U3 ^7 I: _3 |9 {% F3 Z" x2 k
* R( k) i% _% b- W. s) A' P# Y9 J8 o/ ]
0 A; N* o7 J. ^0 ?4 Y4 j实现原理,
! B9 K) `5 [# K9 v2 I$ G+ M, X! {6 k O* V, W) k
1. EXTI Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period4 m' L C: D, T" o( X2 ?& L
- c3 ?/ w$ \) \- G- S2. 继续用EXTI Rising/Falling 中断+定时器方式接收时间码0101值, EXTI Rising/Falling 中断时,修正定时器中断周期为Period/2。
2 d4 o, y2 Z2 {! X9 ]
) G: `% U6 I% M; l产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period& q! q# {/ G) ]' U% w0 L, a
& Y- k% ^8 o8 P# v9 v* v/ T3. 解析差分曼切斯特编码,查找同步码
* [$ w$ S/ y; I9 s U5 C* d
S/ N3 J" u& L ` I9 o流程图,
/ L& A% T( J) w/ u H. _% |
% u S/ p# `1 f$ m# o! l- L/ a! } e, Q6 z8 s+ L* u4 K
8 N% i8 M4 c5 S( O3 V" s# B: a! Q6 K- z6 x8 g8 m1 a2 R6 T
关键过程代码,, r. S& N S+ z% y* u& C
! n6 }& B9 G4 I8 y& q
1. EXIT 中断处理: {( x8 T- c8 y( o/ j
! g& J `- p( g& d' }6 C
- struct LtcInput_s LtcInput = {* z3 }1 Z1 W3 @# l; S! R3 S
- .tim = {0},5 I* S4 g. A# A9 r
- .tim_count = 0,2 d) M# a) ~$ ?$ u5 p
- .period = 0xffff,; k8 I+ R+ {- a% p2 D
- };
5 C+ H: b) B4 P' E
5 Q! j1 T+ N! B0 H7 f' c& b- static uint16_t parse_tim_of_ltc_input_get_period(void)# H/ k$ Z% j" \' ~5 P2 i" x
- {3 G5 V' ^2 s5 ^ T5 B U( D8 G, Y
- for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {
5 Y1 M6 F3 J+ a2 p2 p" w - for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {
" c8 ~: j8 g, X g - if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
) A+ G: ?% i' v9 {8 g - <span style="font-style: italic;"> uint16_t tmp = LtcInput.tim;
8 _$ s! p1 n% c" ~# V5 o/ f - LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];4 B8 L, I" C) n$ p0 u: z
- LtcInput.tim[j] = tmp;
) o9 A- O# G- f! d; f( f' | - </i><span style="font-style: normal;">}
2 p: b" Z9 @( ]+ b - }- b8 w) R* f& y0 p
- }9 ^9 X2 {; `) H8 Y, d! u8 p
- uint16_t period = LtcInput.tim[10];* v. r* h1 p! P2 u) L5 x9 }' h
- return period;5 |9 R/ M; x7 d0 t6 `& y
- }
; H( i* x) G3 b1 G6 O4 C - - D4 F' F+ m( ^) U/ ]
- void ltc_input_timer_restart(int period)
, ~0 ^$ O3 g2 A9 l; h& G: j - {
1 P+ C# u8 p- p* | - . ]( N( _% L2 w$ H+ w" g* u
- htim3.Instance->SR = 0; g+ G5 M$ U( p+ o3 Q) [3 M
- htim3.Instance->ARR = period;
8 y' ~! p x( [ - htim3.Instance->CNT = 0;# `8 j, s8 { ~1 A% e: j# w0 b
) ?/ P# U2 n) K9 x, i- }
9 l# ~; A8 k' Z# _( _
( X9 N& t( H. X7 N8 ?- void ltc_input_pin_callback(void): t$ i$ p7 F, w8 n. Y
- {
4 i5 ~8 l' m1 ?$ C: N( q - // HAL_TIM_Base_Stop_IT(&htim3);
& B, O# w1 f( {1 m6 G; q - if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {5 Q( ^3 t" w1 f; Y0 i9 S
- ltc_input_timer_restart(LtcInput.period/2);
; V4 i1 I1 F8 s5 W- r. z - } else {8 c" T% C, M8 `6 w) k) }# N
- LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;
/ |0 F) n! U( \ r - LtcInput.tim_count++;
( j+ B3 A, j) M - if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
$ Z- \" X# j3 ?0 R- C - LtcInput.period = parse_tim_of_ltc_input_get_period();
8 \* t) t. F3 S" Y( O6 Z) w - }
6 k: C5 P* T, C$ J - ltc_input_timer_restart(0xffff);/ D5 `! c9 `0 G! t6 e
- }
7 r! I& N" h O: E3 b - }</span></span>
复制代码 . G# P# U! w+ T) \6 z
2. 定时器处理" _7 c) k2 J/ t4 V+ g( J% k
- /**
6 r* S) W j4 L' m - * @brief This function handles TIM3 global interrupt.+ a9 b% c" V5 O3 U
- */* X$ I: V5 w4 C
- void TIM3_IRQHandler(void)
" d/ S8 g, @4 X: W3 m$ A - {
& `* f. S* ]1 |, X: @ v& O/ T - /* USER CODE BEGIN TIM3_IRQn 0 */+ ]* C- K5 x. ]
- ' K5 g; D4 J. `) @7 y c, D
- /* USER CODE END TIM3_IRQn 0 */
, p# N; d6 F: e7 I: F) l - HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
8 a- ~7 ~$ i2 t( W% A# S- o* V' P# C - htim3.Instance->SR = 0;
4 T7 X! Z7 I; m" t - htim3.Instance->ARR = LtcInput.period;8 \7 b0 \6 G. {4 a" d! `
- htim3.Instance->CNT = 0;
0 ] T3 w2 A+ Q# H( x+ B q - ltc_input_timer_callback();
5 K$ x4 l' |0 D0 W7 n - 3 e) E$ ~5 q* |) W7 t, @
- /* USER CODE END TIM3_IRQn 1 */
% b1 }: O' ~% {5 O; D - }, C) I7 S' A+ A; c( j5 h1 w5 p
! }9 P- A' T1 m) D- I( n' W! \- char ltc_input_timer_callback(void)
. b$ X6 x8 v2 u# E, \1 H - {
: [( z) B& z8 ? - GPIO_PinState status;
. ^. }9 @/ }( ?0 \4 R% u - unsigned char x, y;3 ^; B! F$ _; L- F8 ?! k! V2 o1 [
0 p3 ?1 O; @7 v& L- status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);) b5 b- b6 x9 f0 {1 R3 U
- //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);, O6 ^' v* D& n1 h* G( r) M q
- //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
# Q0 R% X& e1 J( w1 M, i - 6 j/ P2 W# o+ r
- //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);0 P2 l8 u% ]' ]9 a$ B7 |2 P
- //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);
) Y4 V% e- K4 \ - //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));) L+ O* @" D: k
- , C: q r4 |" N
- x = linear_timecode_count /8;
& x% Y2 y9 j. T6 X/ z" P9 s6 _ - y = linear_timecode_count %8;, H5 [2 g& R1 {3 A. }
- 2 ^5 C' ^ q1 W' p s5 V) l4 a" x
- //buf[linear_timecode_count] = status;2 A5 J% R b/ b0 Z/ e4 E2 z
- linear_timecode_raw[x] &= ~(1 << y);8 W+ V% {1 w7 r" g
- / Z0 |8 Z, k: T( M% w
- if(status != GPIO_PIN_RESET) {
0 {8 y( @" M8 x; H! [# o - linear_timecode_raw[x] |= (1 << y);
. |1 }: ^ ~/ ~1 V - }
# N u7 C: i0 H/ B: j - : M- _# @) W9 ~; k7 `
- linear_timecode_count ++;
3 p! U& [4 ^, _7 M Y# t - $ c; b" Z" d3 \+ ~0 V7 R, b5 U1 U
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
1 C$ {- @* i, w! }: { - if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {, P1 S% C- b6 e4 w+ ^4 o7 a3 f
- linear_timecode_count =0;
4 M( i% M* [0 |& N4 H; k* X8 r - memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));
& _) G1 y: T% r, ^( G6 |& C# l% S - linear_timecode_ready = 1;
E2 i1 \' J$ {5 m - }
( R. ?; {4 v- X - } else {
; w# q& d+ L6 ~* s9 E# `" U - if(offset_bits > 0) {' s) j5 c6 }! x0 e+ ^
- //skip offset_bits
* n$ P5 U$ |0 U- y6 m. E9 U - //If offset < linear_timecode_count, adjust the offset to the next frame., x) s) }( A" M) Q T" E/ N) w) X
- //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.2 k+ z+ v+ F7 s' V" U- f
- if(linear_timecode_count > offset_bits) {
+ w, h! o- G. [2 G& `" R! } - offset_bits += 160;
* h: n8 {/ [! K' P0 r" n# a - } else if(linear_timecode_count == offset_bits) {
. g( ~- D' [: C7 `& W- S, A - offset_bits = 0;/ Z- v: A9 S8 }2 w
- linear_timecode_count = 0;6 y9 x4 r) M/ T3 Z1 X
- }
% c" N1 }8 g2 M: ?' q/ V! n8 T - } else { p9 U) ?- E! z/ S+ F- l
- if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {. Q9 b5 E4 N9 h( q% j g" P
- linear_timecode_count =0;
+ Q6 E% o: ^0 T/ J( L: A8 m" m - memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);
- [ X$ \! b$ o9 A- a% m - linear_timecode_ready = 1;: |( I. Q- P4 p8 j) s
- }
8 A4 a1 {/ J, Z, `) B X - }
1 c _! w& @, w0 l4 w( w4 d8 e" k e - }
: z: P5 i4 R, A& D - return 0;2 n' {# u: D F# e2 E
- }
复制代码
( m: n$ V: ?* w: N7 _: B0 c3. 差分曼切斯特码解码
9 \$ G* T! S9 k T. ?1 y
- `2 ? U& G, r5 A5 t% C! j% |- unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
( }% n$ C- V3 f V/ ~! |2 v - unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
, p: ?2 e: G) y: z
/ J9 t+ \5 f1 Q: P" | |) e/ ?- static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)% i4 D; n. c5 _6 o+ Q
- {' e( o. r7 ~: H
- unsigned char i;
P' N- b' V+ v- e* K. ^ - unsigned char tmp;5 w6 _* q k# H4 `7 f
- ! U( ^; l4 G+ J6 `6 O& G
- if((nbits < 1) || (nbits > 7)) {
2 @2 b0 _% Z& D, C: K: [, z - return;
6 p% U! W S3 V/ a7 O - }
7 M U" {, ?, [2 b+ Q+ i- m! v1 H - 1 n y/ f2 S# I1 G* G h
- for(i=0; i<nbytes - 1; i++) {; ^5 i: W5 j7 d) \( T
- tmp = raw[i+1] & r_mask[nbits];5 L4 Y, ?7 b% B9 U8 N( u' I& @! _ u$ @
- tmp <<= (8-nbits);! ~4 q( ~- L3 z, f4 y% L
- raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits; ~6 e% o8 i k6 G
- raw</span><span style="font-style: normal;"> += tmp;
: B1 m- E! ^. p' ^7 F, i4 ^& G - }' Q0 u& p ?7 N- F# J, H
- raw</span><span style="font-style: normal;"> >>= nbits;; R$ n0 u" R5 a% ]9 `
- }
5 i$ z0 i5 W, z/ V+ g6 s C4 o - 3 k! y+ Y% {8 r" L! H9 X
- static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
/ d$ X9 a l1 V2 R6 y7 R - {
# G9 F! D+ S3 T$ M! W - unsigned char i;
3 @ i2 A$ J7 h# V4 [4 @* R, O4 P - unsigned char tmp;2 p' U# O2 P+ a/ y5 b+ S* b w
4 p+ ]# Q6 W7 x1 D- if((nbits < 1) || (nbits > 7)) {2 T9 }! s5 e0 z: @ t
- return;
3 A2 ^4 e3 U$ C% l; V - }
- Y$ |2 l; |" K. _" t, Q
8 l( o& P8 J3 y0 m i- for(i=0; i<nbytes - 1; i++) {
: |6 U- D7 k t7 }1 w9 { - //prev_bit = raw</span><span style="font-style: normal;"> & 0x80; p5 ?1 ?1 a/ k7 u0 C, M! x
- tmp = raw[nbytes - i - 2] & l_mask[nbits]; g, q& T! d/ L' m5 S
- raw[nbytes - i -1] <<= nbits;9 ~* Y) \9 j3 U7 B
- tmp >>= (8-nbits);, A9 Z y! K9 S) |
- raw[nbytes - i -1] += tmp;
8 `0 S. ^6 V' N9 p8 g+ @& r" C# u - }" i0 ~$ v$ |% R4 H
- raw[0] <<= nbits;" i( m2 @7 }: z7 |6 P
- }
, s# Y& L# N; R+ I - 9 g. e" j4 k, v* `2 S( y; z
- static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)! o- [- j! \" S7 t! W" g' [7 N
- {
- s* u" V0 V2 s3 }. G6 N1 H - unsigned char x, y;
" |8 P, f7 p, a3 \ - & e% U5 @ G2 C2 ^; H0 r3 Q
- x = nbits / 8;
' I' ~$ V0 K5 q) P+ {7 x- H5 v - y = nbits % 8;
: ], |4 \; g6 r. N+ d - $ ?6 K! C" w* s
- if(x > 0) {2 z! R, H& e3 ?& C1 G( F3 q
- for (int i = 0; i < nbytes ; i++) {, H9 l+ d% V& k
- raw</span><span style="font-style: normal;"> = raw[x+i];/ [* V+ G2 M/ c3 }# Q [& J
- }
! `& C3 N' _" H! S i" j; @& } - }2 W Y, R- ~4 P a
- move_right_linear_timecode_raw_7bits(raw, nbytes, y);
0 h. L0 O6 t. |; `# R4 _ - }7 H$ a! C' Q2 K9 [& l
- ) q# \. w' W/ Y! \
- # E, D$ O5 d W& F+ B
- static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)5 a8 x" r1 k( y1 [
- {6 j% t# K9 d4 @) v
- unsigned char x, y;6 h. c9 ~! b- c3 C) Y) I9 P
. w! k1 v8 s+ _. I: I- x = nbits / 8;
4 j/ \/ Y8 p" F' |; ^5 h - y = nbits % 8;
/ a* r8 t, f0 G( b4 d0 L - 6 y. m' q) a a
- if(x > 0) {7 F. X! J7 _, w. X
- for (int i = 0; i < nbytes ; i++) {) O. Q* g: [0 i: p
- raw[nbytes-i-1] = raw[nbytes-i-1-x];
# e" O3 ~4 y6 ^( I8 a. C! [' }3 \ - }4 q* ^$ B6 T/ R) X9 r& P1 j3 x
- } p2 F) k' ?: F- L3 t
- move_left_linear_timecode_raw_7bits(raw, nbytes, y);3 o8 ]6 p( y6 v. Z- [, x% O, s
- }
/ s3 d4 t" @% ^4 J. ~
1 p# h4 j4 }8 G1 n1 b0 A: ]* q- unsigned char get_bit_linear_timecode_raw(unsigned char index)
) E" D: p# K8 W0 z) a' a% N - {6 D D$ C6 b9 g4 m* ?4 Q
- unsigned char x = index/8;
& d$ m i4 s O6 b - unsigned char y = index%8;. R9 Q3 ?5 u# N
- 9 g K- n: ^8 u* R n1 G
- if(linear_timecode_raw[x] & (1 <<y))- o4 @0 ^+ `' n1 d N
- return 1;
" x0 R% `$ \1 ? - else
' Z) O; D2 ~" M: o4 y - return 0;6 ^: L: a/ p9 S8 y
- }
w: u! [* W+ \/ Q' Y% p; e( k; P - 4 a1 |: L G0 c x7 R: u8 `
- static void parse_differential_manchester_code(unsigned char *src, unsigned char *dst, unsigned char dst_size)- `5 S1 I0 R3 z/ M+ ~1 ^: @
- {4 u, `0 l& c7 v* B/ p) n
- unsigned char i, j;
# l1 l; f9 X# W$ S- u2 e- R - unsigned short tmp, tmp2;6 W6 ~3 ?8 s0 H B8 k$ e1 D4 O
/ ?3 R% @- T4 K, f4 O7 o: `- for(i=0; i<dst_size; i++) {
0 j) V, e8 Y' X1 o6 E
4 i8 F4 [( w1 V- tmp = (src[i*2 +1] << 8) + src[i*2];1 @5 |/ ~( u9 |% B( D$ a
- dst</span><span style="font-style: normal;"> = 0;
/ K) _4 @; c/ ^0 w( n - for(j=0; j<8; j++) {
r, D4 |/ w1 D6 W, ]+ s - tmp2 = tmp & (3 << j*2);
& r, K" Z9 ]& N, D5 o - tmp2 >>= j*2;
' M! ^( c' @3 t# `; t - if((0 != tmp2) && (3 != tmp2)) {8 u2 ^9 b, j. i' F8 z3 e9 u/ l# R
- dst</span><span style="font-style: normal;"> |= (1<<j);& v# v/ B) n9 i4 V! A+ e# v8 h
- }) @7 X; T( C9 [$ x1 j8 |
- }7 L6 g- C6 y4 S) }
- }$ e5 Q6 w* |% l) T9 C. g: }
- }* a1 B& Q; m' y7 J5 |% K; @
E4 O: P3 u/ j- static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)2 c9 V& E4 l1 Q3 @" b+ g0 ]
- {: _) I8 w7 M/ a8 C/ _
- const unsigned short sync_code = 0xFCBF;8 E( F4 T0 w. q; I
- unsigned char i;
m; V8 i6 ` ? - unsigned short tmp;
) F' i- D4 @+ Q; ]2 Y" U - char ret=-1;
$ L/ z. T( i c8 G
# p l2 Y B$ `" Z7 E0 o9 y7 f8 D- for (i=0; i<len-8; i++) {
: s6 N" s- K. j; _$ O - tmp = (src[i+8] << 8) + src[i+9];
2 z+ B7 }( [% n) M; @/ f - if (tmp == sync_code) {8 Q+ S: j8 F* e: Q
- ret =0;
8 Y* w3 Y4 J/ S8 z - *valid_len = len - i; M- F: I) }& H# L# E! \' J
- memcpy(dst, &src</span><span style="font-style: normal;">, 10); //10Bytes equals 80bits
% b& H2 l+ v0 L* |0 s4 } - break;
/ n! J9 Q; @% e2 b. Q! S0 }% ? - }
3 {* `8 U% ^5 ^7 ^7 L - }
! [! k3 {& `/ o0 _8 { - - H" D. R- `) q! J) R( X
- return ret;, I- {9 ~9 x9 Q6 Z
- 6 t! E S& z# M7 x: v
- }
; S) x2 |% |1 a6 ?* j. M( t$ J
% ~2 M, t3 f4 s! \. L: f- unsigned char ltc_dst_code[40][10]= {0}; u3 e s {9 k: d, q
- unsigned char ltc_dst_code_count = 0;
- I! g& b* ^, c* O& [3 o1 M - unsigned char ltc_code_valid_len=0;
: K* Q& p+ M' k6 F3 S0 G9 ] - unsigned char ltc_code[20] = {0};; X/ s- I7 d$ B
- unsigned char raw_ready[60] = {0};
4 k: k. [8 F) I3 M# s5 c- w - unsigned short offset_bits = 0;
& N% W0 a) H; R5 l/ p% X - unsigned short ltc_remain_bits = 0;
1 d" |5 i+ k" h6 D. K - unsigned char sec_ltc_code[20] = {0};/ j. f. Z! t& Z& u' e
- unsigned char ltc_dst_code_cur[10]= {0};! A, A. V4 i5 d8 e2 m/ O& A0 G
- unsigned char new_frame =0;
* Y( F+ Y7 ]( L1 R6 w
4 s: s' b/ k+ j
/ l3 _$ e' x6 S. D& ~- L! N3 ^# I% q- void parse_linear_timecode_raw()& |& w4 O. T4 f
- {6 k3 | {2 w" a% C6 h% ]$ _/ `
- unsigned char tmp;
' J5 v2 f$ V$ g4 z# C) Z5 ~) g* N - unsigned char raw_mv_right_bits = 0;5 H$ Q# o) V" E; r' d% e; m
- ' S% q' c' \3 u
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
% n; `8 M( ^5 I+ S/ j4 p. O - isjam = 0;6 J2 [9 @9 F& }& S( r% r6 e
- memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));3 h" U+ k6 F2 B. |5 ]3 n" E m
- tmp = raw_ready[0] & 0x03;
, a; m7 N: o: l4 H - while((0 != tmp) && (3 != tmp)) {# [# {1 y+ Q# w
- move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);: E: `$ _+ `7 G. P* e z# j; W( s
- raw_mv_right_bits ++;% _, T0 F' ~! f$ d
- tmp = raw_ready[0] & 0x03;
! L6 C3 |- _( l7 Y- T) T) o - }
3 T5 X5 E# C6 E! r/ x( @* i, O7 ~
$ E/ x) b9 @8 D( S! z- for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {2 ]& Y$ x2 P6 F$ j2 G8 z
- memset(ltc_code, 0 , sizeof(ltc_code));
7 g/ E. a, K8 R; l$ l! F - parse_differential_manchester_code(raw_ready, ltc_code, sizeof(ltc_code));1 P [# F: [6 w; K. y. l
- //0xFCBF;
5 j4 M8 P' W+ }0 x, I - if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {
+ f- u* @9 Z$ u: B - linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;/ N) v ~1 x" K
- offset_bits = raw_mv_right_bits;
7 U8 h& r( C: J+ f& g j7 a1 E - break;, M+ P1 \9 h: ]( Z+ p! M
- } `2 \+ i2 e9 e6 ]
- move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);6 x7 C+ Y5 T: J: v$ A1 f* _$ v
- raw_mv_right_bits ++;. V* j# w, D8 E2 e" K/ v! z0 K& u
- }0 c: y' Z( C8 X9 {
3 Q8 r$ \/ s" z4 H6 x* F0 a- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
7 _, {% X' l, U# Q: m# b/ Y3 f |. K - LtcInput.tim_count = 0; //reflesh tim2 period9 s! y% H/ {, f; `2 B
- }
. _8 f5 d% b& P# _. H u3 F _* {. ^
4 @1 M2 h7 ]1 R( P% ]6 K- } else {9 Z8 W# B: F) F
- isjam = 1;
7 D P4 H$ X1 W- U$ A7 A - memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));; G) B2 @; d, F8 \
- parse_differential_manchester_code(ltc_code, ltc_dst_code_cur, sizeof(ltc_dst_code_cur));* w& Z9 V1 g: F/ N* {
- if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {8 G, I) L9 D8 r: P, w# G
- linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;1 {; R# F( \9 s' [+ J/ W
- LtcInput.tim_count = 0; //reflesh tim2 period* X4 g6 H( G; K) z# J% D3 }
- } else {
. R2 G2 w" W# v7 q - new_frame =1;" a9 w( R8 f/ \$ [1 W
- }2 w0 D1 W- J1 U: O& e" D4 E) s' L
- }
6 Q" o& B7 ^* ]" r/ b& P3 W - }
* w0 i) l4 g; S5 W: i' j6 b - </span></span>
复制代码 * a, @7 J& b5 f
$ f' \: {8 E7 }( a, J8 b! P总结以及调试过程中发现的问题。
! X. u/ N! U% g6 ]% a& ]9 C
) G) K$ q7 l# Q6 D2 a4 t8 u% l Y1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us
0 P# @. `$ Z u& i, Y' `
3 R, ^3 t1 x# R- o# T
* [( E& C5 c, d0 ]. S) h. P2 b4 f+ ~8 X! k
2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
0 @9 y- V6 O2 U6 V h8 _! X2 C _9 q; ]4 O- I+ Q* \6 }9 i
异常1, 中断回调,里面调用HAL_TIM_xxx , 导致反复进入定时器中断,
4 ]: o& r/ s) E0 _6 h+ E! l- H; `6 u5 h% O6 Y
& P7 l* o1 |0 A. @4 ?
8 h$ H5 D9 B" p: x+ t6 x; T异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行# X2 i" y- _: I# C0 f
" s0 j3 m# U' Y- Z$ b t
. y# d" ^5 H& j0 x9 }& ~0 ]0 u% x/ _: D+ ~8 ^7 O8 K b
解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形7 f+ K- ^4 I3 A% v* I4 S
- void TIM3_IRQHandler(void)
6 {- I4 t! V4 `; L5 O7 l6 Y0 G - {
5 e, @+ c; i5 s; F0 i2 T. ~5 x+ ~& P- \2 N - /* USER CODE BEGIN TIM3_IRQn 0 */2 P0 o# v$ d5 ^$ P
- % [0 {' J& T& l# u! p0 }, g
- /* USER CODE END TIM3_IRQn 0 */; C, m2 n& s3 W5 P
- HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);4 @6 H; p# t3 \ p C7 {
- htim3.Instance->SR = 0;7 F7 g- e8 L1 C& |
- htim3.Instance->ARR = LtcInput.period;
3 x4 t5 p% w# ]: K - htim3.Instance->CNT = 0;
" F9 C: S3 J+ w+ S - ltc_input_timer_callback();
* S% o8 J1 C- h2 V I9 j/ X - 4 Z7 v) h! H9 R* o* k# }( p( @' Y
- /* USER CODE END TIM3_IRQn 1 */- Z' I8 e6 m% W k; v0 ?. t0 [
- }
复制代码
! a, ?4 A% S3 |, x* A) `, `$ Y# ^/ ^
$ s& @( {3 \. b$ e! z
; _$ y5 _; Q3 g! F9 [6 K7 Q. i7 _
|