时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,: S N8 |# Z+ W- y6 n
# ]. j3 h/ t5 z8 d
8 o3 ^" I; L5 U; p
+ B5 r, o! _3 i4 v- _
8 b: ]' b6 K" c6 }" P& x) f实现原理,+ L! F8 E" } T* A
3 S/ r) ]0 z8 z1. EXTI Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period
% n+ ^' ^9 y/ S
# ^4 I8 h- O1 u2. 继续用EXTI Rising/Falling 中断+定时器方式接收时间码0101值, EXTI Rising/Falling 中断时,修正定时器中断周期为Period/2。
) u. F! e3 C' b' }2 ~7 }8 G4 X% S6 L0 V8 h1 i! `1 p! u
产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period
4 j) {/ e% S) `8 a# z+ c8 L6 Z0 A
3. 解析差分曼切斯特编码,查找同步码% f& N; K6 ?5 ]. p" ?( F) h$ h2 S/ Z9 j0 [
/ v& r) \0 p" `; V
流程图,: n8 g* O# Q0 f9 s& E! p
# {! \6 N- a( o, m. M1 |- c$ q
/ u' q9 D2 Z J6 G( U5 P2 b
7 O0 `6 A0 h) p5 o4 X: ]6 P
# ~! j; r& d/ M( e0 E$ c
关键过程代码,
8 C2 l3 }+ U2 s/ D: A0 z, x6 h h& _5 @
1. EXIT 中断处理1 D) M# m6 \7 X$ q) F" Q+ @/ u) \3 i
/ z* S. q5 J: p; v. a0 P! i1 q
- struct LtcInput_s LtcInput = {
2 H' g y. u- `, x - .tim = {0},
# G' N# Y/ c9 h& K0 j - .tim_count = 0,4 R8 n0 v8 P( u; Z3 q
- .period = 0xffff,* y1 x1 z. U: n8 c2 h, G0 g
- };. F! q1 h" w* W
4 q: n: U2 F: ]- w2 g8 A, o- static uint16_t parse_tim_of_ltc_input_get_period(void)
* r8 }. S* ~7 i - {
6 r; c9 ~) ]$ ?9 ? F5 ]: k0 s - for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {
9 f5 Q" V( p( s! h: R. B5 } - for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {
4 O% \" _ p2 t. _( ^ - if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
4 M5 h0 u/ G# _+ A - <span style="font-style: italic;"> uint16_t tmp = LtcInput.tim;3 {* P* w* Z/ y( _2 p& R" R' t
- LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];, u3 P% x# V$ n1 h' @. D* p% C. Z
- LtcInput.tim[j] = tmp;: A5 T: H) L# s3 C4 b
- </i><span style="font-style: normal;">}6 q5 y9 u8 c3 O% [- [2 L
- }
. r2 `+ Q5 P" u8 |: m! g) o - }
# `7 ]6 y7 L$ Y3 w1 a - uint16_t period = LtcInput.tim[10];9 b% N# @6 h2 m7 V4 d
- return period;
4 W% y% Y2 k1 F - }3 ~( y* N% ~; Z' G
- ) a# r0 [& A( _6 ?! X& l
- void ltc_input_timer_restart(int period)& I" e* u6 s1 g" O: s: C
- {
6 H7 E s9 Q5 v
0 b$ t' [* u) _7 h9 Z0 |- htim3.Instance->SR = 0;
9 W) C, ~* k. I' T# K$ L1 O" Q - htim3.Instance->ARR = period;
! f |+ A5 l; B - htim3.Instance->CNT = 0;
v1 H! f" i; x w
% q- S& v2 {: q" i0 z5 {9 x- }
6 h& k( m$ Z3 K
! _* K( Q/ ?8 D9 e- void ltc_input_pin_callback(void)* E! I" w) _2 e `4 L
- {
. u) {+ Q) ]9 }% T - // HAL_TIM_Base_Stop_IT(&htim3);
& M; Z+ ~ x U+ g/ K/ ^3 M - if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
- |8 e1 ?- r j/ w) r - ltc_input_timer_restart(LtcInput.period/2);
# W/ n7 `* P7 y* o - } else {) s. f- O$ ?+ ]% C5 P7 B- Y8 v
- LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;
9 N$ e8 `/ m9 }( f7 J - LtcInput.tim_count++;1 Z X5 R+ B+ v7 ~
- if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {3 ^4 {& M8 r5 Z2 G/ E* M
- LtcInput.period = parse_tim_of_ltc_input_get_period();- ?5 x8 |6 I* g* E& @
- }
2 _. q2 j$ T2 k, x# w" `& r/ ` - ltc_input_timer_restart(0xffff); g) i7 ]$ W3 j u; h& U
- }: a5 l' U7 n( g. T( E0 Q- L
- }</span></span>
复制代码 # c/ V. t- i) P' j# H0 L
2. 定时器处理
) z+ |( C Z" f. d- /**1 p. Z! h6 B4 |2 F1 R4 [
- * @brief This function handles TIM3 global interrupt.1 L" t* |' H$ h5 ^. \' C* \
- */& `/ S p R5 r+ H
- void TIM3_IRQHandler(void): _4 @5 _- h5 V* Q
- {
; H7 f5 T4 q @& g# B3 ^$ r, V - /* USER CODE BEGIN TIM3_IRQn 0 */' `: ]' B e+ S
' i1 \7 q0 |0 i0 E- /* USER CODE END TIM3_IRQn 0 */
6 u( o# _' g/ Y6 c5 [/ G - HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);" [- e8 D: H' H) s1 O! F+ Q! Y
- htim3.Instance->SR = 0;0 A/ y. S1 Z Y2 P! h2 ?3 A$ J* N
- htim3.Instance->ARR = LtcInput.period;
- U7 d) ~! T f" r - htim3.Instance->CNT = 0;6 _7 [! o/ u' _9 J i( V6 e
- ltc_input_timer_callback();9 a1 V( b' o/ D! G5 t) W
) b8 ~1 y' U& y- N' O! n- /* USER CODE END TIM3_IRQn 1 */
- R" v* V7 d" Y - }
3 w8 t1 x* n8 _4 y; D - % G) o4 J) E& N+ X: m0 v' z
- char ltc_input_timer_callback(void)
r# }1 w1 r& X2 j' G - {
$ U4 Y7 |* g; n# a5 c% i - GPIO_PinState status;0 U+ }4 z( s- g* q% P
- unsigned char x, y;
. K' c( h! _. w; W t/ h; | - ! Y9 D/ F2 y6 f
- status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);" Z; H1 I8 D. ~1 U
- //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);+ r6 ?5 x, k% d5 f# z: w1 k
- //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
& }4 y' Y: v0 ]: ~4 p { - 3 v* P9 [' S; w. w0 d" X6 i
- //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);
d- J6 N8 M0 A* N4 z4 ?2 i+ n& ?* T - //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);
- ]" N5 B; [1 \' t - //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));; ^# K/ p- \# O+ f
" K! X$ ]' o* J- G" h- x = linear_timecode_count /8;5 g, V: v7 g3 A# _& P
- y = linear_timecode_count %8;
5 a' I6 k9 R3 |# a K; q/ S - & I! B" a) N1 G% V) P1 Z# A
- //buf[linear_timecode_count] = status;
, p4 r, Y' ~0 Y5 z7 e1 ?" G% } - linear_timecode_raw[x] &= ~(1 << y);
1 d7 T m- L& v - + X6 O2 h/ K$ m& T
- if(status != GPIO_PIN_RESET) {, n. i( Z5 L/ Q0 u+ b6 b. Z' | z
- linear_timecode_raw[x] |= (1 << y);
W8 ?# ?3 n# j7 g9 _1 L - }
8 c+ e1 U2 N4 M8 u8 a
9 d* {6 J8 [) G- linear_timecode_count ++;
( I7 W9 x7 |8 r1 R8 V, g - / R+ p+ Y' t2 k" U, V. C- K4 ?7 u5 u3 |
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {$ m! q7 R1 c/ M6 z1 E$ Z
- if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {
: z6 K: K( a6 s' v& E7 }1 `- j2 h - linear_timecode_count =0;) f3 c- U7 O* N" d( { {6 D3 G
- memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));6 S9 _6 u. \, q2 g! ^$ L
- linear_timecode_ready = 1;
) y4 i, h& `2 p, l, o - }# m X/ o, x' H3 T$ k
- } else {
5 B% R4 U' {: Z9 u0 _' y# w - if(offset_bits > 0) {1 _5 t' @* s& y
- //skip offset_bits
$ l- P% u/ E& `1 [$ ]9 u - //If offset < linear_timecode_count, adjust the offset to the next frame.
5 U! d1 }8 Y$ m$ K - //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.6 c: V* T* ^2 K3 v, W' z9 v; [
- if(linear_timecode_count > offset_bits) {5 q v7 y- `3 U9 ?5 R* l
- offset_bits += 160;
# H' q9 l3 _& o$ a0 a - } else if(linear_timecode_count == offset_bits) {6 S9 T6 y! Q. Y( b( J8 ~
- offset_bits = 0;) b% [$ @& [7 |- `
- linear_timecode_count = 0;- j! R0 O1 ^2 `
- }
" ^8 j+ e9 o% l! F - } else {
! x" r! ~7 S/ P8 y& \. A+ R5 I) M - if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {
; d. M7 `! q- _5 ]( V+ _4 k: B4 p - linear_timecode_count =0;
2 [! N1 ~5 L0 q7 o0 C! j' { - memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);0 v8 F$ I" `5 }$ ?- m+ i1 N
- linear_timecode_ready = 1;9 j+ U( p! l( D9 o* _7 z8 u
- }1 n3 F/ M, ]8 H: M q8 ?
- }$ v0 A, G7 |6 P
- }: q% z* o" A% ~/ Q7 i& S4 d
- return 0;
& d0 p5 ~& L) p M - }
复制代码
4 Q7 \# s5 n9 b' p6 h; g3. 差分曼切斯特码解码
1 f8 B" g' y; G. `1 ]; k0 }
' K* X- [( P. {$ {$ {- unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
- U) } H. _- M' X* Y - unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };' o3 y1 {; F- U, o- v! e
- * m+ M0 e$ @; t& |5 i! J
- static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
% |4 q6 q# J# j' {" C - {
( B% u! v: b# }4 N& ` - unsigned char i;
+ F9 S. _1 _( o) a7 v - unsigned char tmp;4 z7 W$ v% Z8 ]2 H7 U4 a" x
- - k9 A* S `/ o' E: w" p
- if((nbits < 1) || (nbits > 7)) {
7 l N2 g$ F8 J, w - return;
0 o- a1 ]5 h: g1 E! [, i6 v( Q) ~ - }
) t( _& j& h: a" {# g# ^+ o - 0 _; m2 b- }: M$ S! R* F0 B, B
- for(i=0; i<nbytes - 1; i++) {/ h7 Y% Q F5 d: V! X( i# b
- tmp = raw[i+1] & r_mask[nbits];
7 w+ u! l; ]% ]' _* R+ L - tmp <<= (8-nbits);
. D- L( q- n4 u/ I+ Z* m - raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;
. O$ Q0 ~6 ~" G' [/ Y - raw</span><span style="font-style: normal;"> += tmp;
2 Q4 Q1 ]0 n6 b, G- J. \1 i1 n A - }
' R% H$ d' Z' @0 n& g. M z, Q - raw</span><span style="font-style: normal;"> >>= nbits;
$ e( Q, h! D9 u1 p& W/ K4 ~9 O* z - }- q1 D3 `& Q/ W5 P" l, l
/ n4 p/ a/ U. Y3 J- static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
! t& m; w) y$ `6 k! V" \ [ - {
+ x4 K: B: g. N$ r6 Y5 K - unsigned char i;% g5 E- C T! K' s+ o
- unsigned char tmp;
4 Z- o* P9 q b3 s$ ?3 B* X6 W - - F3 y$ D/ N2 C
- if((nbits < 1) || (nbits > 7)) {5 y9 L! k5 Z' A k8 \0 d7 m
- return;
: t4 a# i/ @9 J: J - }' k( \# v, J5 h& m7 d% l6 |! U
- ) {; ]2 B- h+ R, } E3 ?
- for(i=0; i<nbytes - 1; i++) {) \9 E' d' T L) k7 p6 @: q
- //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;( t, j9 a7 Y/ Q5 p# ]" o6 e) { e
- tmp = raw[nbytes - i - 2] & l_mask[nbits];6 }7 n6 N) I4 \, I$ r" f" }
- raw[nbytes - i -1] <<= nbits;
, R; Z8 p5 X! {1 K4 w - tmp >>= (8-nbits);9 m" |$ E0 J9 @: {
- raw[nbytes - i -1] += tmp;1 }% S4 k$ F3 ?9 T$ Q! ?
- }
; d: \1 H# Y+ b- K+ L! g - raw[0] <<= nbits;
/ C( K5 U2 U$ n9 Z( `9 K - }; @/ O9 R# J R- D) s+ O& v! f
- 5 f# ~9 x* ~6 w4 L+ b* R
- static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)5 g+ J. x1 R$ ]4 ^
- {2 P/ H; O8 ]. x X w7 b& F: F( y
- unsigned char x, y;6 P/ ^! x0 p' f( r7 R
- / l* y" f3 g7 l7 T$ d
- x = nbits / 8;
& q) k) Y9 m8 W& ?: G( K% I - y = nbits % 8;2 C- ?+ A& |7 `7 D0 W
, f" n5 _+ r% d$ L: N- if(x > 0) {
: V. E2 q& L2 o; m/ [ - for (int i = 0; i < nbytes ; i++) {
, I) |. h; B0 K - raw</span><span style="font-style: normal;"> = raw[x+i];' ^4 p* R1 L% F/ J+ h+ V7 L
- }
$ ?7 @4 L# N# w/ w9 k9 { - }
, @0 F0 D. L- L. q8 X4 O - move_right_linear_timecode_raw_7bits(raw, nbytes, y);
' b7 k% k b' C( P- h - }
* @2 g6 ~3 D ]# r2 {, G - 4 G5 z" p7 M. q4 f
- 8 L$ c3 f' M8 t
- static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)
$ `$ F5 D" e- ? - {
" C( L* o( y9 S' ?$ ^& P) O - unsigned char x, y;- t2 Q3 k) s- _, u& ]6 b4 W
- 8 ~( P# ~$ _9 K% y5 m
- x = nbits / 8;
) v9 k6 p" e/ A6 e - y = nbits % 8;
7 E! F$ B9 L& R# }7 H- d - $ G: A. u& U. \& _$ z
- if(x > 0) {1 @0 J* O! V5 \3 M
- for (int i = 0; i < nbytes ; i++) {
- ~. Z4 \4 u% ?/ B" H/ d, R8 M1 { - raw[nbytes-i-1] = raw[nbytes-i-1-x];
' A# X% v, e h/ N- c - }4 L3 E L/ `6 l9 l
- }% I! n8 `- e0 O" t4 ~$ m
- move_left_linear_timecode_raw_7bits(raw, nbytes, y);1 s/ o5 d# r0 w: }/ b! v( ^4 ]
- }+ } M" r6 V# [ t
0 }5 I$ Z% ?$ F- unsigned char get_bit_linear_timecode_raw(unsigned char index)
/ K( I4 @8 v7 R - {- g( G9 {) @. O- @. s$ z9 N% u, z
- unsigned char x = index/8;2 T- Z+ g! ^% O1 [# ]" u
- unsigned char y = index%8;
0 Z% v" Q0 W3 H( k0 X& j& W" }
! h. c% ^: ~/ v ]# m- if(linear_timecode_raw[x] & (1 <<y))
' o3 C! N# ^ s% P6 T$ T& S3 z - return 1;
: _. Q& S: h+ l% h! I+ ? - else
& @% M6 P; T1 v* n! ^, s: @ - return 0;
5 L+ r9 i5 n& m- k' R, O3 H - }* ^6 J$ u# J3 W9 l
- m5 d- W/ [) u' I2 g- static void parse_differential_manchester_code(unsigned char *src, unsigned char *dst, unsigned char dst_size): u3 y7 H5 s5 D- v, q
- {3 b: G7 S2 g: W5 a9 v3 P+ U
- unsigned char i, j;
- R2 I' G0 U: a: d - unsigned short tmp, tmp2;) Y) h% M. B9 a
- ( F8 l3 g5 X8 J+ J, C/ B! z9 s" h
- for(i=0; i<dst_size; i++) {
7 y. G/ }" \# K0 K - 3 A) r0 h4 \' _1 O! ?6 x
- tmp = (src[i*2 +1] << 8) + src[i*2];/ z5 U, ^6 p' S5 {' h* z% @
- dst</span><span style="font-style: normal;"> = 0;- S. [; {& t9 }& c) c' p' G; S( l: O( D
- for(j=0; j<8; j++) {4 h+ ]5 ~: W) y
- tmp2 = tmp & (3 << j*2);
0 }+ M' Y* u% w$ C7 e* I8 Y1 s; J - tmp2 >>= j*2;
* }' d" V- N1 _! X0 A: }7 @ - if((0 != tmp2) && (3 != tmp2)) {
3 n0 s5 `% D8 \# u - dst</span><span style="font-style: normal;"> |= (1<<j);
. Z& H2 K' J! z2 s# e, }- Q% { - }
1 g! ]8 A5 k% G - }
- ?, i: K" W* ? - }& O! Q. L, h3 v
- }9 }: Z2 n% A$ w+ Z: A& @9 `
- 6 f! d# r6 L8 i
- static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)4 N4 B' p$ N e4 b2 f- T8 K# ]
- {0 p9 v, b, V( E/ v3 j
- const unsigned short sync_code = 0xFCBF;) \ c1 ?0 Z5 d; {0 R2 _. l5 D
- unsigned char i;
X+ r( z9 c2 T, W - unsigned short tmp;. T8 {# B v+ a# L3 v
- char ret=-1;% ]+ e+ [5 x. [) s" w
6 F5 c, T4 m/ c- for (i=0; i<len-8; i++) {3 J* s4 n( W, @! ^5 G
- tmp = (src[i+8] << 8) + src[i+9];5 I/ v7 ^! x. V" P8 J! w0 ]; U5 z+ |
- if (tmp == sync_code) {+ @% U( q5 Z$ \) Q
- ret =0;. P A+ }3 L1 e1 t8 |' o# Q
- *valid_len = len - i;
* b/ u0 i. a$ J6 G h: @9 \ - memcpy(dst, &src</span><span style="font-style: normal;">, 10); //10Bytes equals 80bits
2 ]* d9 k0 U, z1 X0 ~ - break;! U9 ~7 R! K$ x: z3 U1 I+ P i
- }
+ Y" v3 Y, h0 `& ?+ U - }8 |& L( U. Y' N) E9 `* U
K; ?; |8 K4 A3 `# w/ q& g- return ret;; _4 Q$ D. O8 m0 _
- $ A8 ?; a' D/ j
- }
8 m3 B6 q" Y" B5 \9 R( i! _* o - + n6 r/ y* F+ x
- unsigned char ltc_dst_code[40][10]= {0};$ y, D5 R ^" a H! T
- unsigned char ltc_dst_code_count = 0;# P. i. {; u% j/ t# ~7 `
- unsigned char ltc_code_valid_len=0;6 L) Y# y9 ]8 C* ]
- unsigned char ltc_code[20] = {0};! x8 a1 K1 O& _6 ]/ U) q; K
- unsigned char raw_ready[60] = {0};
1 l+ v- {7 p# a! @* | - unsigned short offset_bits = 0;
% F! b% s' y( y, f2 W# W/ p2 T - unsigned short ltc_remain_bits = 0;
. V6 ~. d1 J; d* a - unsigned char sec_ltc_code[20] = {0};
2 d: X/ U: Q& `! x" L: N - unsigned char ltc_dst_code_cur[10]= {0};
& u! q* u: g& |0 j - unsigned char new_frame =0;! x0 N; J4 Z2 _: u# z7 A4 u
- 7 @4 D) u0 z$ k
- 3 k D( F: X# Q1 j3 ^( ~$ |
- void parse_linear_timecode_raw()3 i) s6 _" I) N6 t2 L
- {1 `8 L- n4 t3 P7 Q; S3 `+ N8 U1 m
- unsigned char tmp;9 D! ^1 u, a/ f% J' s- c8 v
- unsigned char raw_mv_right_bits = 0;
+ r2 ?3 R7 q( X9 y5 g/ Y3 H
! J+ z! H" `) K- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {& d0 o9 ~& l, l1 e3 F& v7 I
- isjam = 0;
8 Y7 E1 Y$ { n - memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));2 ^! a$ h8 d& v$ @9 l3 Y
- tmp = raw_ready[0] & 0x03;0 s1 q5 v- f% E( e* M
- while((0 != tmp) && (3 != tmp)) {& m( T* y# }; H7 n. J, u) I# L
- move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
6 i& [5 l- z0 F, {5 [ B - raw_mv_right_bits ++;
2 K( G& Q- n! U/ ], x9 A2 J& s - tmp = raw_ready[0] & 0x03; o- V: a) l j: S% r/ e: F, N
- }, g8 i0 X4 ?- l6 \% ?/ Q' x' i9 T; D
4 {6 }* n/ D, U( T# S- A- R- for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {
& \1 v" w+ a: a - memset(ltc_code, 0 , sizeof(ltc_code));; N! F" D3 L: F+ ~9 F; {
- parse_differential_manchester_code(raw_ready, ltc_code, sizeof(ltc_code));
/ P0 p( R2 p# y - //0xFCBF;/ I2 X1 _! z' k4 a* d6 x/ { {
- if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {
: a9 z7 `. o4 M7 |& A! W* A - linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;
8 h$ T+ K4 _: C5 A( n) P* s$ E - offset_bits = raw_mv_right_bits;
. H2 l+ W7 T( N2 A; n - break;1 M4 O) T4 `1 |* N3 r) W
- }0 @5 f% B: Q$ y' c7 z+ B* ?- Z
- move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
8 O- ^/ T3 a6 Z- i0 e4 n& X3 u9 z - raw_mv_right_bits ++;9 ^; h/ f0 s/ v; p) X0 C# h; H7 R6 g
- }
, h4 N6 V( I$ W8 v [ - 5 b7 z- S' z' v
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {) ?& N: i9 o$ n/ B; r/ v
- LtcInput.tim_count = 0; //reflesh tim2 period0 S2 ~5 t0 a+ V- V+ I% T/ z; e. U
- }$ r8 C' \( T" |& _/ F6 Z$ D& x
- " m5 @( M& H, ]5 `7 _
- } else {
7 F: G! u; n$ @+ u6 N$ G- @ - isjam = 1;$ }- e+ E6 g1 r0 T* V; D8 ^$ v
- memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));
( N' D/ k* ~5 ^, y7 X - parse_differential_manchester_code(ltc_code, ltc_dst_code_cur, sizeof(ltc_dst_code_cur));. `7 g$ @1 i$ q3 f+ Z- P
- if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {
) A M# s; z; s0 ^+ ~ - linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;1 P; r9 @3 b7 W% Z+ Y2 Z
- LtcInput.tim_count = 0; //reflesh tim2 period
' m( f5 K/ F6 v' s! v; k v - } else {1 z: {6 }) q) U j/ w: f
- new_frame =1;
- e4 E1 @( J; U9 S/ h- J1 \ - }* D$ e+ l/ y$ ^
- }
. I3 F \5 @2 ]5 D& M _ - }
! k5 B* G7 v% F! o0 E - </span></span>
复制代码 + O2 J/ x# U) i5 a( H# A: _
4 T/ [8 W, `( X; k0 R% r; s
总结以及调试过程中发现的问题。
- W9 b& w# q' ^
# s. a6 m5 q# I, Q1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us
* `' Z/ ?2 }/ R& Q! ~, O& R$ K' n
" v- q# K6 l2 F9 [1 d; @3 V7 J* y8 R3 U4 |' i V$ w4 z5 S1 @2 } Z
A0 k% u1 N% M& y4 Z
2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
8 O6 ~5 R/ ~% }, l3 g3 |+ {4 J" M3 H/ h* U+ G
异常1, 中断回调,里面调用HAL_TIM_xxx , 导致反复进入定时器中断,! w3 U- Q8 V0 v1 v- s* _" F
) ^' [# ]' K, @7 G2 ^" F
; v# W. z6 T2 H0 R0 a5 T) H! g7 r
% N% o6 x1 E+ ~, t异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行8 l& F) U1 ~9 P/ S4 ]7 X. P+ U
5 d& |# `3 t! w; L5 C4 h! z/ }- Q5 v: `1 a6 R* C
' J/ s$ g' }# _
解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形
# O$ y- O6 h) J) q& B- void TIM3_IRQHandler(void)" I8 J4 X) v) F7 b9 M; y- V, C
- {+ d1 q8 F2 K! i* c0 o( E
- /* USER CODE BEGIN TIM3_IRQn 0 */7 U: Z8 O% l3 R7 d
1 z& o/ v$ _* r. E, q% c, X( j) p- /* USER CODE END TIM3_IRQn 0 */
6 L# J2 z) q0 Y9 ~. t; N - HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);& g1 H, |& d! d4 k
- htim3.Instance->SR = 0;) y' {4 l* c$ n
- htim3.Instance->ARR = LtcInput.period;
$ l* q. [$ J6 a6 v' r& R; ] - htim3.Instance->CNT = 0;
" I! N5 I$ @- O! ~ - ltc_input_timer_callback();7 ?. n+ t' b9 E' r' l$ H
1 {, w" M8 {, h4 Z5 M. A- /* USER CODE END TIM3_IRQn 1 */* e! {3 d3 h3 |& _3 r
- }
复制代码 , m1 e- Z7 @* z( ?0 g
: g6 p1 P9 |+ L+ R! x
9 e1 g; {- d# q# ] \6 L C. w5 G' [0 y. Q2 b
|