时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,9 J V! M5 T9 ^$ v( G
6 p% _" v8 V* C# e
' ?$ ~' U. Y2 L) x; ]# _. f
4 Z" h( w" p4 X, |) K2 L- \6 q# N
实现原理,
) H/ _9 U5 ?( s" k& X; t4 ~; W1 Y9 z G
1. EXTI Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period
% Y2 J' d+ P! ^8 S0 ]3 h6 n O: z* {8 B6 Q6 C& g# ]/ ~
2. 继续用EXTI Rising/Falling 中断+定时器方式接收时间码0101值, EXTI Rising/Falling 中断时,修正定时器中断周期为Period/2。
7 ]/ e9 ~: c/ m" F4 b" ~- q, w2 J. t3 \
产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period7 Z N& h/ J2 c
, `! h9 E( r& k' [
3. 解析差分曼切斯特编码,查找同步码, {" d( s; k4 v
+ l' V: B8 W* ?+ |. Y流程图,4 b% A, I1 R2 \# }, p
& q0 M5 F- q- n p! F* D
; e% Y% Z* T9 P7 P5 {
* e ~1 ?# x, y! f
% R) q# E! e9 ^8 S& A$ }关键过程代码,
8 o( k0 w% l$ }1 J1 \: e( e+ A
. x" h$ r$ Z% }' R' t1. EXIT 中断处理5 O& j& c/ a' J* W& y) v3 X% J
) o+ t( I/ p! L, }" V) _8 H
- struct LtcInput_s LtcInput = {
" D ?8 }2 L' B' `) p! n0 K& r - .tim = {0},
# g& A8 d* u8 y- h - .tim_count = 0,
* ~. W. k* d8 c8 e% F: A' ?# X - .period = 0xffff,
8 T6 a i- M+ _! M6 u! ] - };5 r% q2 p0 a) u8 }: w
- 4 S0 I% M6 P3 {+ |
- static uint16_t parse_tim_of_ltc_input_get_period(void)- k; Y0 o6 t8 f5 ^
- {3 V; q" W2 d% Y4 u+ q4 P+ a
- for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {- [% E" G1 @4 J
- for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {
1 W& z9 S" b3 h - if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>4 N* s; e- I# _# }6 P7 I8 M& ~# Y
- <span style="font-style: italic;"> uint16_t tmp = LtcInput.tim;
) S* H" F( N1 F - LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];, K( \' P. _, O" J; R( y2 m
- LtcInput.tim[j] = tmp;2 O' H, p( K# ^& I9 g) h' n% P
- </i><span style="font-style: normal;">} V5 p8 D6 C6 \9 S/ ?9 W
- }* R7 P- r' ]& ]. b
- }$ z* _5 b1 _! D. v
- uint16_t period = LtcInput.tim[10];
9 J% O. Q. v1 n6 F! R* H0 I+ u - return period;
7 B2 H! ] P) M, m% D - }
, K" e* {4 l- X; `/ n0 h# R, J: @4 o - 8 v7 _# {1 Z( r% Q3 V$ R4 M
- void ltc_input_timer_restart(int period)
- S# x: R! z: `5 l% F0 \5 @9 m - {
$ f9 l0 Y' ^' |5 f3 W- a% H
, u: y1 `9 v% L6 E3 t5 e1 j- htim3.Instance->SR = 0;8 `0 @3 S: [" }
- htim3.Instance->ARR = period;
6 m3 z6 q% n& a8 g - htim3.Instance->CNT = 0;1 o4 R9 `3 ~) R' _
- ! h$ q0 i; k5 c1 {2 g1 o6 }
- }6 D: n: V5 ~9 O. X
- & f* H; ^% `8 w2 H$ |3 [
- void ltc_input_pin_callback(void)
c- P4 R; w3 G; l& [ - {* k# g+ y' t# s
- // HAL_TIM_Base_Stop_IT(&htim3);
. e9 |; g% i0 g% J/ ?3 K9 m' {3 E - if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
1 U* p8 m' T- D7 e% L& |2 \8 s - ltc_input_timer_restart(LtcInput.period/2);+ p+ s4 I# u+ x- R
- } else { W8 F9 x$ u" `
- LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;1 ^5 I$ t, g) b7 k ^) Z
- LtcInput.tim_count++;
0 f7 @8 j! J) ?/ C - if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
- B9 `* p! J+ u& V' H! u - LtcInput.period = parse_tim_of_ltc_input_get_period();
' Q! O- M. c! n6 @2 D - }
) c h3 I" G3 V3 C - ltc_input_timer_restart(0xffff);
# o* f' v( v5 O* A; w - }3 |5 I2 C! {1 c- B3 s0 Y
- }</span></span>
复制代码
2 J9 Z+ v; L Z2. 定时器处理& _) u6 ]2 c1 k6 T( }' u
- /**
* S$ B) _, u' F2 b+ i: y% M - * @brief This function handles TIM3 global interrupt.' e6 V9 W; x2 M+ ~5 u4 p
- */( K, r3 h& r" W- e: \
- void TIM3_IRQHandler(void)
T- h% O, r% D7 ~4 {( J - {1 z0 a/ k$ c9 I. \! c7 G
- /* USER CODE BEGIN TIM3_IRQn 0 */) y1 U7 w' n& Z
- : s% V7 ?0 M7 A4 O0 q8 ]! d( f1 ^
- /* USER CODE END TIM3_IRQn 0 */3 f( M& f" U% j2 C- L3 O4 y
- HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);8 d9 m6 Y3 f2 a7 |. p4 @4 \9 {" m4 h
- htim3.Instance->SR = 0;8 D, `& g" h! b# U% r+ ~
- htim3.Instance->ARR = LtcInput.period;
8 z, d5 [% k- k) z- d' }: s - htim3.Instance->CNT = 0;7 q/ Y' A+ F! v' r
- ltc_input_timer_callback();/ R* \ I- j5 K
- 8 w3 {. g3 ~& z4 I4 Z+ j
- /* USER CODE END TIM3_IRQn 1 */
0 A, {: e' R9 }2 _4 d - }) j4 x/ a# B' L$ s- s; a2 [
. y; T9 n: n4 q+ ^- O- char ltc_input_timer_callback(void)
. d& K6 t1 M& \& I; D2 ^ - {
$ ^" p; X) _% Y" |% G% T- N- d6 D) d - GPIO_PinState status;; T( }7 N% v! x$ b9 M3 t# w' b: ?
- unsigned char x, y;( K7 k7 T+ x) z; X, c1 J4 J2 U
- % y6 X8 K* g0 ^& I, ]$ g
- status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);3 y# J; p/ j: n* c
- //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);
( f7 A" I1 \1 g! q/ W - //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);" D$ q# g( u' x- l$ a- i. M8 A
7 D7 Y5 T$ F% c4 P0 ? o- //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);7 p3 b0 I& A5 ~7 o7 _( m3 [/ s" j' x
- //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);8 k7 Q( q ] m: p9 G. G( a- P7 u/ R
- //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));& ~* I0 G1 B( ~% r X) |5 ^
- 1 s5 f D6 {+ m+ b
- x = linear_timecode_count /8;
* G2 i- A; f# x4 p( y8 n - y = linear_timecode_count %8;4 @# ]1 n% p3 ?- ]
, ]* @; m3 U% q- l- X' F% V- //buf[linear_timecode_count] = status;2 N3 A0 ]2 H( f* P% S$ ]
- linear_timecode_raw[x] &= ~(1 << y);
) d4 p# d- t1 o, K - * G% R" F( y+ `$ V4 g7 Q/ m; U2 ^$ U
- if(status != GPIO_PIN_RESET) {
( U0 W/ a% \) S! | - linear_timecode_raw[x] |= (1 << y);5 J( `4 h, V) r; k0 K7 q& j
- }
1 P/ s& J h& i6 k* | - $ _2 S5 O, a( R3 O: ]
- linear_timecode_count ++;! S! S( R$ }6 `" ~
- 5 J- o3 @( D9 ^9 i# g' q: h: M
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {$ I# O. P. v' x# V+ }+ \
- if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {
$ j: X/ @4 ?. E; P: N0 S - linear_timecode_count =0;
7 _& I5 F1 i1 |2 f; G1 F. | - memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));* D1 n- e6 _' s3 M/ v* f( ?5 w
- linear_timecode_ready = 1;- Z* ?8 m( S; F- B/ j
- }4 Q; j5 h" Q& t" I
- } else {! H: D- s/ u6 ?5 |' ~8 N: T
- if(offset_bits > 0) {. y) H' O: K$ E# u2 ~# N! ]6 ?# q% f
- //skip offset_bits4 s" T) {8 \2 z$ j# V) ]
- //If offset < linear_timecode_count, adjust the offset to the next frame.1 M [0 e! V! G3 R- X3 Z( i
- //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.6 k! R5 I& v& v) F5 W
- if(linear_timecode_count > offset_bits) {
9 i: y8 M t' g) ` - offset_bits += 160;: n+ _' h% x) {" J
- } else if(linear_timecode_count == offset_bits) {- @6 v9 D' L, k% n$ w& |6 h
- offset_bits = 0;4 T) v: I8 a7 Q
- linear_timecode_count = 0;
7 ^* B: E' p3 O; g - }
; y7 M4 ]3 @. S1 P/ u$ a/ b0 C* q - } else {
- R6 J$ ^( ?+ s1 U! ~0 l - if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {0 I" F: t' o$ z: B/ x
- linear_timecode_count =0;
, O/ Q9 J8 `- B+ O! Q - memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);
3 n- s# h$ t+ E' T9 [& B. p7 F9 g - linear_timecode_ready = 1;# t2 }# E- Y6 q8 j; Q0 k. D
- }
# z6 B3 \( F8 R6 n - }
" }% o: V C- E% [ - }
: V! N+ x2 N. d - return 0;% \# i" L, y# X3 ~0 z- f) h& v7 M
- }
复制代码
* U* G2 `1 j- Z3. 差分曼切斯特码解码
6 S# [3 e6 s( }) u: u- 6 m+ j! R+ N) r8 s( Q: F3 U
- unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
7 k& z2 u$ F0 t6 J$ x y7 X4 W - unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };! E. R" K. U4 e! L( v. w, U5 B: k9 d
/ _% z7 z) S1 D" |- static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
3 g! A0 Z+ a Q - {
; O* y: d; \+ H! l2 F9 X - unsigned char i;3 v5 c8 J/ N1 J9 I
- unsigned char tmp;9 P( w6 N1 t' m. w# r* j
- : H4 ^4 k0 H$ {, o
- if((nbits < 1) || (nbits > 7)) {$ B( R. A" n0 Z9 I
- return;
, i6 |1 n( n1 O6 k - }
+ Y# N9 f: ^' f+ F4 ]! J: v7 r; V( o" X - * t6 x3 K5 [+ [+ d9 n/ ]8 g4 f
- for(i=0; i<nbytes - 1; i++) {8 x4 z) b, P: ]$ r
- tmp = raw[i+1] & r_mask[nbits];; P! b& V0 L6 J2 E8 [; @! S
- tmp <<= (8-nbits);
* M8 M8 Q% i" u# c - raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;
+ Z5 N/ ~5 D4 I' G4 v+ x - raw</span><span style="font-style: normal;"> += tmp;
7 V2 X0 d1 k C2 d5 z - }
+ b0 X! P+ l% D! v8 _: H* A5 c$ G" q - raw</span><span style="font-style: normal;"> >>= nbits;6 l6 \6 A# U/ m8 E
- }
. k/ M4 ?6 ]' d; p1 h( Q2 t( Y% A% O
5 e" u6 V, A# }9 Q: G- static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
* F3 Z- p2 P! x1 _6 i - {
+ G* J1 s- ^; C# m - unsigned char i;. m6 x2 s( c) r8 n
- unsigned char tmp;5 T A: w5 }) l! K: W
) G0 k a' }5 H. W+ X% b- if((nbits < 1) || (nbits > 7)) {
E! u0 c, f, \: h0 j4 ~3 L/ m* a - return;
4 ~; O$ A- j# v5 U% E- B- @2 Y1 \ - }" r# F+ s1 h, w U; }
- % Q7 @* q: i5 g" i# K
- for(i=0; i<nbytes - 1; i++) {
1 m6 f$ a1 @ _( {( P - //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;
' J, A2 v/ z% [1 J - tmp = raw[nbytes - i - 2] & l_mask[nbits];
. d- {4 ?/ L' b# t; P0 W - raw[nbytes - i -1] <<= nbits;: ?# F/ q( ^9 ^6 |3 A2 F
- tmp >>= (8-nbits);: p1 @. D8 w7 K+ L% {' B, P
- raw[nbytes - i -1] += tmp;3 ~& l7 b& U( z8 `+ K" Q
- }. {4 l# @+ X' t
- raw[0] <<= nbits;( H6 c- Q! |0 h7 L* E
- }- A6 X( {5 C' M9 y
0 m6 _# Q9 o8 o0 ]( D: P/ X- static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)4 A3 }+ a5 P ]/ C) z! T
- {* c+ ?% z! }. f7 r4 v4 s5 J5 k
- unsigned char x, y;
/ ^+ j% b4 |3 b: q4 P8 q - & @. P1 d0 n" Q# ^# G% Q
- x = nbits / 8;
) {/ o7 m9 w6 m - y = nbits % 8;
& G0 ^- B( i+ Q. |+ x
) o+ T* h0 F3 w* I# h6 K7 ?- if(x > 0) {! Q( ^# F$ b! R( ]9 }% |
- for (int i = 0; i < nbytes ; i++) {0 j- R1 S& w- G9 s0 J( r
- raw</span><span style="font-style: normal;"> = raw[x+i];; {5 z5 M) G; D" d. ~& X* ^9 R4 I
- }
7 X; G/ ]! K4 b+ X' h* C) e - }
, a$ l$ s; E# b5 |2 D& a - move_right_linear_timecode_raw_7bits(raw, nbytes, y);
7 _9 _6 f% B! l) E. t - }
1 k, n8 h: Z i6 ?0 J/ Z - & u- `4 w7 A" T) E) m! M
: V5 C% S H! m2 D: P# E2 @% z- static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits), t# L% u* h$ T1 E4 [
- {( \& W& f, L4 o0 G+ N, m, G k
- unsigned char x, y;
3 `1 _& ?; p0 a( u% w& i& H
9 K9 p) {) Y6 p; K( Q) h# i- x = nbits / 8;& k" U/ S& a( i
- y = nbits % 8;
5 H" H6 t) g) C% R - ; ^! x7 G; ~ [% L
- if(x > 0) {2 Z1 J4 L* _* Z) E7 l' w5 U
- for (int i = 0; i < nbytes ; i++) {
0 i# d- X% j8 I" t# S - raw[nbytes-i-1] = raw[nbytes-i-1-x];4 U& X* c c+ n, u, {" p: B
- }
7 A( X) u* \$ s - }2 e0 ]2 P- d( X- [$ N+ t. J
- move_left_linear_timecode_raw_7bits(raw, nbytes, y);# b6 B, ~) H' L) E9 `5 a/ @; I
- }
; {. c1 N% Z. K, F4 H$ X) ^
; e1 O; ^9 I$ Q' t- unsigned char get_bit_linear_timecode_raw(unsigned char index)4 m5 S* t, ^3 A6 Y" s. @
- {
b! _/ u D+ a9 l E - unsigned char x = index/8;
2 [8 x5 F \* |% J3 u; L0 ]3 C - unsigned char y = index%8;
. P& }' e& X B6 ]
# ^# [1 A5 O8 T7 I* F: F- if(linear_timecode_raw[x] & (1 <<y))+ I4 ?4 f6 n8 h/ y M" e
- return 1;6 f( N2 E: g. k7 H" R( T7 x* z
- else
, f$ c' K' f! F2 |% K9 o - return 0;
9 q+ ~' r( m4 Y1 s - }
1 ?9 V r) T3 R. w! _ O3 | - , s! Z) v% f# `" G
- static void parse_differential_manchester_code(unsigned char *src, unsigned char *dst, unsigned char dst_size)* Y% E. Z4 {: \
- {, d3 f! P$ d4 b& [8 B
- unsigned char i, j;3 k( V" M* J1 b( ~7 Z$ F
- unsigned short tmp, tmp2;
# Y& k' S3 I( T6 v+ A) @7 b6 a: i/ h - + j5 }: G$ ^, {( Q
- for(i=0; i<dst_size; i++) {% x4 ?5 g/ H* d# p
6 `8 \9 V* C! x% M8 d- ]' S- tmp = (src[i*2 +1] << 8) + src[i*2];3 D- v2 ^) N5 |. x: Y
- dst</span><span style="font-style: normal;"> = 0;' W2 R5 H o8 J; `" b* P
- for(j=0; j<8; j++) {8 [6 {3 L/ T/ S# W" {
- tmp2 = tmp & (3 << j*2);0 ` l8 _* B) G" z* G
- tmp2 >>= j*2;+ q- g7 R3 k) V1 c/ H
- if((0 != tmp2) && (3 != tmp2)) {
% j5 ^' N7 V8 z5 ] K- ] - dst</span><span style="font-style: normal;"> |= (1<<j);, C- n9 q6 ]# M8 q7 w) v) ]4 o
- }
, c/ _8 z, I" b) Y' H - }
, C- K4 z7 }3 I+ {; f, { - } B" s& r9 K2 |1 e
- }" j) N9 f% C3 f( z6 L9 M& j
- % S4 X& X( W3 u
- static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)
$ B) \ p# V* i% X - {
m: E1 {4 f% p- E. C - const unsigned short sync_code = 0xFCBF;
|. ^* o' e' D0 N - unsigned char i;1 _; ?8 I' a, A2 d0 T3 N' |, u. q9 P0 N, E
- unsigned short tmp;) F J8 x5 L& e3 [9 ^3 v
- char ret=-1;- L" A7 T. X- T1 M9 {3 K& H
& q7 O# E# T$ W* q- for (i=0; i<len-8; i++) {2 s5 D8 _$ j, x- N# |9 U9 t9 x) R9 `7 b
- tmp = (src[i+8] << 8) + src[i+9];
1 j X. @8 j t7 H - if (tmp == sync_code) {
1 y+ I4 T0 N( B - ret =0;
; r; }8 |0 [( F# F% O; v - *valid_len = len - i;+ [- d; r4 u3 u* G4 r' ]
- memcpy(dst, &src</span><span style="font-style: normal;">, 10); //10Bytes equals 80bits
s0 [; E; A, M6 X- f8 K! a1 }" O - break;
0 v/ }; n3 B9 L' q' {: C- A1 G - }( m3 h5 w, |0 y6 q5 @
- }
# \4 I$ [! c" R - ! R. e6 B) Q- r, B5 E
- return ret;# w, r# a& `) ^
- I4 _3 p: [0 M9 e: c2 h1 Q- }
7 W4 C' f" K1 T9 v/ \+ R
- N- D! z& I: w" Q# n; N- unsigned char ltc_dst_code[40][10]= {0};: B+ c+ f% k+ X, v. L* O
- unsigned char ltc_dst_code_count = 0;
, I; A6 w2 b d/ f, L: s% q - unsigned char ltc_code_valid_len=0;
! q1 j2 e" i- C8 A- z1 N - unsigned char ltc_code[20] = {0};
' y/ n. \& [! T& a - unsigned char raw_ready[60] = {0};
( e4 h0 K: @! }2 R - unsigned short offset_bits = 0;
0 Y; j. E* l+ C/ h9 e- ? - unsigned short ltc_remain_bits = 0;" a: V& @7 R+ L6 S# [: _0 {: t4 f W
- unsigned char sec_ltc_code[20] = {0};0 r) p3 r' j2 z$ A3 u! H( O
- unsigned char ltc_dst_code_cur[10]= {0};
( r6 N- T9 n. G1 ^5 j - unsigned char new_frame =0;
# `' t; q6 W/ }" w( P* ~% | - 5 g7 K8 A1 A$ r1 m2 _, W
- # L- z. U8 l2 T$ H5 s+ ]- u J
- void parse_linear_timecode_raw() O( Y8 M8 |# l% |% h5 L6 d& t
- {1 v/ }' ^- x9 c$ u' s
- unsigned char tmp;1 q0 M; P2 f. C4 a$ Q% J
- unsigned char raw_mv_right_bits = 0;! `7 s# w* j0 h/ R) W
% E0 A5 S4 W. c( K- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {# I/ @2 z- y5 f. S- t" J
- isjam = 0;
; E& Y0 D$ m/ O5 F: ] - memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));
+ w- }: r3 L& B* f" H" t; Z3 l: }: P - tmp = raw_ready[0] & 0x03;
4 B2 k2 p" [ {5 L - while((0 != tmp) && (3 != tmp)) {2 E3 l8 a4 L* C( W6 Q9 w
- move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
% C2 K" u4 T' L: K - raw_mv_right_bits ++;
/ z& G3 P3 t+ w, Z; _+ z4 S - tmp = raw_ready[0] & 0x03;
: [2 ?' z3 `4 @ r8 p - }- \- e3 d" u7 x! U3 o+ b# P
- 1 O# F8 L! A5 @8 Q6 @- g
- for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {7 O, s8 p% U' V, ^0 i! O
- memset(ltc_code, 0 , sizeof(ltc_code));1 [. y! m, O/ l3 J5 l3 j# j# G
- parse_differential_manchester_code(raw_ready, ltc_code, sizeof(ltc_code));, f" h5 ^+ Q- I& n
- //0xFCBF;
/ y, N: o M0 n2 v/ F - if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {
6 C f V" o, u+ u- X - linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;
+ j4 i4 L' b$ M - offset_bits = raw_mv_right_bits;
6 D5 X' B6 n* |, [6 U4 [ - break;
5 s8 n- ~ ~7 v1 e! Z, ^: L$ B Q - }5 A; l1 d# ~ T3 r
- move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
1 f9 J0 T: y) o! L+ J% r - raw_mv_right_bits ++;
$ x1 o; k3 M9 _! D( ]6 I& k - }/ }) F9 H' k3 Y+ s& P
- 1 I( s) Y, |7 F" \: j. q! ?
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
4 V" G9 |- l/ m. v - LtcInput.tim_count = 0; //reflesh tim2 period
' K/ V" f3 C J. w, s - }3 s: }! @2 } i8 O, I7 [: @- I
! Z; a, @# H p1 |- } else {
2 m6 K' ^, O: s0 o9 Q# R2 }- ?$ h - isjam = 1;
% z/ {& S& P2 k) k3 X4 o) g- d - memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));4 v- E7 W4 W1 P* f* [% A
- parse_differential_manchester_code(ltc_code, ltc_dst_code_cur, sizeof(ltc_dst_code_cur));
6 y; c; S- E8 Q9 f - if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {
" y8 [9 j5 l% s7 E9 u% C - linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;
8 Q+ |1 B' p# H- X% J - LtcInput.tim_count = 0; //reflesh tim2 period% s, k3 w! Z U" X
- } else {
! ]* r3 L+ b$ v5 X2 A5 M - new_frame =1;
4 C2 K. m2 b- a ~ - }2 s, _$ _! Y5 p* C) u
- }/ i( n! m# I1 s' K' N
- }( F/ \; v/ |8 P' \9 e+ H0 p& D
- </span></span>
复制代码 6 G, R; w4 |6 F; [
5 g5 a- T; ]) v! Q5 p* L( K
总结以及调试过程中发现的问题。
9 `" p- S& t* a9 d' w, v; ]# K. j/ E Y: p4 u5 P
1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us
d+ g/ A' g# x7 \/ D5 ]9 z
( W$ c0 `+ W( C" P; j0 T l3 S# b- z8 D$ m) u6 J
; K" I7 n! S4 `( W0 D2 Q
2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形$ T; F# e1 d( G+ j( x' b
* e4 R& @/ K' Q; f4 Y
异常1, 中断回调,里面调用HAL_TIM_xxx , 导致反复进入定时器中断,9 A9 d) R; i' V& Y+ U
- }$ V0 p* }$ f1 t
7 u0 N/ K0 h3 f* B+ n* y* X+ {) b4 _; @7 c& T5 U7 n% w
异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行; ?( G1 n' V9 n' ?: [* t: ^; A/ u* [
3 E; Y4 T7 o, N9 V* e2 g# N
1 J+ D% Y. p6 g( M0 L2 b
4 F8 m' d/ B0 K解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形. v I1 {3 b# M6 n* r2 T
- void TIM3_IRQHandler(void)
3 d( l3 I# O$ C. Z" J2 i6 f1 [ - {% k0 y/ n4 q7 o5 ~. t
- /* USER CODE BEGIN TIM3_IRQn 0 */
( v4 K }+ B2 a2 l9 o: O - 7 Y- N9 f- H6 Y) y1 ~4 [) Y
- /* USER CODE END TIM3_IRQn 0 *// \5 U, I' {1 D, S- N
- HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);5 w. p5 l. t% w# I8 x
- htim3.Instance->SR = 0;4 |0 w5 `+ C2 P/ E5 J% _
- htim3.Instance->ARR = LtcInput.period;
' T1 j$ s1 z% J: g/ \ - htim3.Instance->CNT = 0; K) \* F5 l( m3 J- a
- ltc_input_timer_callback();4 Q' ?* x- n3 x. ? `
' m g2 q, S5 r$ i6 z V$ l; ~/ t, }- /* USER CODE END TIM3_IRQn 1 */
' C# o: W8 F$ K8 C - }
复制代码 ( R+ A- W! O, \# N4 G* y
/ }! q0 G% z/ Q N) s
/ Q' \" p" J' p1 ^, t$ T ^8 b5 Q
7 d- F2 j: u n' L& i: J |