时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,
1 h3 @/ a7 V( F& I0 Y
4 P4 y1 [& T& Y8 ]% x* l
4 ~5 |' o3 i9 P" z: M7 I* i( e. K7 o; [+ n' }; F% u" h
, ]. C6 S* G6 i4 Y h4 U6 U0 t" x
实现原理,* i. C! F8 x( s& ]( q
! Q- F8 `% U; [5 t
1. EXTI Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period* I8 z. b- x* H7 Y1 ?
- z# N* c) a) _2. 继续用EXTI Rising/Falling 中断+定时器方式接收时间码0101值, EXTI Rising/Falling 中断时,修正定时器中断周期为Period/2。
3 C! j) g1 E" O' ]# a; E- G5 g0 x' t
产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period! s( P9 ~# K. B' I7 h
7 J+ Z" W% ~1 @! c2 Z2 j7 Y3. 解析差分曼切斯特编码,查找同步码
0 G4 Q) {5 m( L# L! b7 E1 k+ O/ j% N9 c( a- ?+ d/ l
流程图,
# I/ b. _* l& f! E' {! K; A
# [& p4 m7 Y3 _9 p) X7 H0 n, x- z8 q( R3 O0 q7 D) k
6 E& r( t6 V8 f- ~: E
- r* d+ a" O; {' R& [
关键过程代码,8 {3 [# N5 \& w( u* j5 K
) |4 Z/ ^1 ^; L1 D( z1. EXIT 中断处理( B$ F) l& p! i3 i z6 f
: [+ K! f- K- o9 v- struct LtcInput_s LtcInput = {
( `; S5 i. F/ @2 M) `" r - .tim = {0},& L5 O5 W$ \4 W. d" w: }5 U! q
- .tim_count = 0,) I$ l( }2 A& s3 \
- .period = 0xffff,8 O9 n$ Z5 f; `
- };- c y# R0 E, t- a. M) P
- ' T/ `. \0 y6 ]2 h& N9 C; J, n
- static uint16_t parse_tim_of_ltc_input_get_period(void)/ L" O0 x' q1 w0 }# Q/ Q
- {
& K2 z& d5 [- t% h, f/ w2 Y+ g - for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {
2 O5 A6 m( @" w; a& f- n6 a - for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {
) n1 c& K) U+ C* U - if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
. U8 E; a4 O% O' v+ X& q6 @; p. [ - <span style="font-style: italic;"> uint16_t tmp = LtcInput.tim;
+ @! [8 X; k4 F3 O! r/ m) T9 X - LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];0 w+ |, e6 u: D4 ]9 M
- LtcInput.tim[j] = tmp;/ b% s7 }+ w- O V0 h
- </i><span style="font-style: normal;">}
9 N1 E& e* H( z( y/ K - }. }2 N4 l8 [" |5 s8 ~6 e+ \, @! L
- }
! x% W& {/ K9 i5 ? - uint16_t period = LtcInput.tim[10];
7 V) Z6 {: t' k9 E* s1 [; t3 ~6 ^ - return period;6 _/ Q/ ^: @3 n; E( Q5 Q N
- }
% v$ T; l# ^+ O# C: n( L) ?6 H - E7 O0 J: ~' b" V' e$ m
- void ltc_input_timer_restart(int period)% i% ]2 e, N C0 W# k! D, r
- {; k1 c7 R% T2 _8 [7 t& t
- . S# K1 ?1 l9 P( m0 Q u! _7 i
- htim3.Instance->SR = 0;- A9 Z6 A" A; p8 E
- htim3.Instance->ARR = period;
5 Y! Z) m" e9 z; }- X - htim3.Instance->CNT = 0;
# t: b" y2 Z" M: r1 E" r
! c: I) b" o9 f- }
$ ?# z1 l/ @+ x3 F4 S V1 a. ~3 o7 r - % T0 f: P9 ^. F i1 n5 D' T
- void ltc_input_pin_callback(void)
; E# g) A& L( q - {; D' t$ ^* x5 Z, l7 q6 E6 {& ?
- // HAL_TIM_Base_Stop_IT(&htim3);
$ s; M" b1 h! M - if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
. Q0 Q+ k; k2 V$ `. w6 s! d2 D - ltc_input_timer_restart(LtcInput.period/2);$ n, a8 `( X, ?7 L5 [3 v
- } else {1 G* _6 ^1 c# ^# l
- LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;1 B( O6 B, B8 m, g4 j
- LtcInput.tim_count++;; V( s$ y" @6 C: m* k
- if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {- E# ]8 E/ \- a6 G5 a
- LtcInput.period = parse_tim_of_ltc_input_get_period(); Y- P7 M4 Y% l
- }$ i6 k& L0 S6 L5 w. W
- ltc_input_timer_restart(0xffff);; k z. s2 f9 T- `+ u" X
- }$ f5 Z: j8 w/ ~1 N. C% E
- }</span></span>
复制代码 # r% U" {, h( g4 h0 b3 r
2. 定时器处理
6 N9 |+ [( O" y# o7 J- /**
+ D5 D7 \) h6 L$ V - * @brief This function handles TIM3 global interrupt.
7 \1 Q4 _- E* |% [ - */. s5 P; l4 N4 m0 e; y6 ?# D
- void TIM3_IRQHandler(void)7 W8 b2 z% j) Q! l1 z; T& ?
- {
; V& q" G( U6 \. \" w - /* USER CODE BEGIN TIM3_IRQn 0 */
# v5 S3 w8 R8 v- L* Z" K7 y4 M - + R8 i! ]0 f2 F2 T; [' _6 `
- /* USER CODE END TIM3_IRQn 0 */; X' H; E4 N: g: W3 l& s
- HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
( x4 I5 y2 O+ R( ^ - htim3.Instance->SR = 0;+ \! H. Y' j& n
- htim3.Instance->ARR = LtcInput.period;
& M* o8 q( Z x( u4 D - htim3.Instance->CNT = 0;. f9 H% y( E- n& e$ U
- ltc_input_timer_callback();
* b2 H; z( X; T/ O* v - 9 R1 }" m5 E0 \4 `# n& V
- /* USER CODE END TIM3_IRQn 1 */
/ |4 R0 [3 l. Y - }
% c4 e* ?2 }8 V% m
. d1 R. `/ w) [) q1 F5 O- char ltc_input_timer_callback(void)
7 E& ~+ S8 y0 @: S% ?: ~5 p! |0 {7 [ - {% ^! X3 T' t& i$ l$ v
- GPIO_PinState status;- c3 X0 k; C! r/ e
- unsigned char x, y;7 L6 G7 i$ O/ H
: A8 l/ J! f0 x6 n# S4 J- status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);+ I' o0 C' |1 C7 s7 A1 u l) o- b
- //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);4 ^9 \% p6 a7 U8 }3 ^
- //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
& E' `. Z$ ?( X
s+ a2 I/ b& Z! D0 ]% u1 q) |' E, @% d1 @- //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);
% p. S+ p1 v. o4 v. p# E: _ - //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);5 S) |1 U% t1 n( e# m/ k3 v/ A
- //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));
6 `, a1 o; k1 _" s% G, S3 s. p
1 L6 r6 \' Q7 W- x = linear_timecode_count /8;
* H5 E3 q4 n/ a ~( Y. @ - y = linear_timecode_count %8;
! m4 U% h5 i+ x: h- y) o, F# N - # x3 v5 L$ G" T( v4 ^# f! h' U H
- //buf[linear_timecode_count] = status;. g: _0 B9 t" l
- linear_timecode_raw[x] &= ~(1 << y);$ ^ g0 D" `! e y" u* }, a. ~
- 7 ^/ J# J r6 g5 g: f0 C
- if(status != GPIO_PIN_RESET) {
% d I$ t! L* g3 Z k$ T1 S+ | - linear_timecode_raw[x] |= (1 << y);
3 d% s5 y/ h; ~5 N! D0 S; n - } S6 b" f# `2 |) J) r4 A( k5 R
- 7 P. H* @# i7 o2 G: C' `+ K
- linear_timecode_count ++;; R3 J8 m1 Q- b$ p5 M$ x5 S/ V' [
7 M1 ^, B! j6 Z& W( R- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {, M- a6 `6 Z/ Z' {! t+ J/ X3 ]
- if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {! B. n5 E! E& W' o. X( c1 T6 O2 S3 m
- linear_timecode_count =0;+ ~( N. k4 G. r8 f- i6 S
- memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));: X+ V/ H# k0 ]8 ?7 ? K
- linear_timecode_ready = 1;
{9 m s. o9 w: C - }3 C4 v- b# t" H5 }. {
- } else {/ m1 o: J+ ]: g
- if(offset_bits > 0) {! n+ J* h* ?' w' @; x) p& r
- //skip offset_bits
) k6 W K) U) J L7 c- n/ @9 y - //If offset < linear_timecode_count, adjust the offset to the next frame.3 \/ s/ \; t1 D2 D% O+ F- v
- //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.
8 A% w& [: P6 N" f! H/ ~( T - if(linear_timecode_count > offset_bits) {; D% c% `7 H3 u9 L' ^- U" s( v# {
- offset_bits += 160;4 Y: |& S+ I' n5 C: T) w
- } else if(linear_timecode_count == offset_bits) {" X& c8 |6 h& z, a
- offset_bits = 0;( P1 }# [2 U3 J* W: i
- linear_timecode_count = 0;3 f4 D; p0 }, B
- }
2 E) l, u7 R6 g4 k" T6 N - } else {
& j5 R# L8 n( D! |5 b - if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {$ t* r- T1 u8 M! G+ @
- linear_timecode_count =0;5 v3 C5 K+ r5 s6 v" e3 p
- memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);
* U6 j" Y- ~5 B0 R - linear_timecode_ready = 1;* ] ]' j- b+ A
- }
, _& C5 H- t8 m0 l4 E - }
- {9 O6 p( t1 [; m% d2 _ - }8 _0 W7 l6 x( d M$ A+ v' s$ r2 j
- return 0;% x# t+ {2 e# E% V
- }
复制代码
5 D& g( W5 J1 M C L3 R# W3 T6 y3. 差分曼切斯特码解码
+ E( j) J# P9 u, c" |3 |% S; T4 I
9 k5 P2 T( n- s! e* C% k- unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };; N3 g, T5 l' O3 B) }. I$ {
- unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
3 f3 o+ D9 K: e! a2 O! v
( t- Y7 T4 M) k3 C7 P9 T- static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
5 X3 n: }) ?5 Y5 d* } - {
; @7 N& J" ?3 g$ h) y' S9 `8 q - unsigned char i;. j/ K$ Q# P+ E0 u/ t& n. m
- unsigned char tmp;
/ g: U. Z9 [# ~ - ; I- v' {4 I# B3 i3 f5 y- X
- if((nbits < 1) || (nbits > 7)) {
8 H9 L" B0 K1 i, W, r, ^ - return;
5 j' ?1 r2 q) x# B9 R8 P) s1 Z. j - }- {2 S7 e! d8 y0 }, H3 P
2 P @5 q% Z+ o F8 h/ V1 G# z- for(i=0; i<nbytes - 1; i++) {: n6 O }) V* X9 v3 c0 f+ Z
- tmp = raw[i+1] & r_mask[nbits];
$ p& M) O% y& I7 U9 [% W+ k3 r - tmp <<= (8-nbits);
' b y3 H9 a* [" {1 j8 j# Q: q3 F0 ?7 g - raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;# p8 E) ]( u+ k% O) J8 F" Y% o4 P3 f
- raw</span><span style="font-style: normal;"> += tmp;, M' L& `& h8 c
- } G& U+ o5 }5 {. @: d6 r- L
- raw</span><span style="font-style: normal;"> >>= nbits;/ Y; J( I: m4 P, ^4 S
- }2 ?- P( L4 d' u- X5 a9 f
( F; f3 L9 [* C8 n- static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
4 O9 d" A9 o- {: E$ [; Z - {
4 M+ W% e2 c) i - unsigned char i;$ h g) ~1 ]% G: K" {9 [4 I
- unsigned char tmp;0 X3 {0 m3 d. y% Q4 a# ^) x4 ^3 A. l
- ) V% t( k% d8 @7 `# ]$ K
- if((nbits < 1) || (nbits > 7)) {( i1 P6 V9 S2 w
- return;8 J' H v) I2 K+ t8 q. r7 k
- }+ b) w! u+ ?& }3 o1 V, q
- * h& a) u( G# Z, ^* f3 V
- for(i=0; i<nbytes - 1; i++) {
0 q3 ~; N3 M9 f- X0 j" t - //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;
# @1 z- @3 e' ~% M - tmp = raw[nbytes - i - 2] & l_mask[nbits];* O+ N5 @$ N. v3 X# c
- raw[nbytes - i -1] <<= nbits;
, \8 D8 `. }2 s$ l( Y: ]. n - tmp >>= (8-nbits);5 X: y8 ?2 a& b4 Q( @7 R
- raw[nbytes - i -1] += tmp;7 z t$ u: a7 @) c# T$ F: g
- }
! X: A; c8 d$ N - raw[0] <<= nbits;
/ a& [7 t2 h" S - }
/ F, q8 c: J# {1 r
6 I# S* @) l+ @; _1 c6 ?( U- static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)# U3 C/ _4 N& R5 s5 `$ h
- {
: E! m+ ^. G9 Y - unsigned char x, y;& E6 q6 g) q% ^( ~5 `/ F9 `
- m+ M, k9 L( k+ ~9 I n5 U, |% O- x = nbits / 8;: u) H4 i Z" i
- y = nbits % 8;3 J* T6 _( r3 | f# t0 k
, U- P9 a% O! ^! x ^6 U- if(x > 0) {
4 p* v0 K2 N. a - for (int i = 0; i < nbytes ; i++) {
! `. c; u/ ?2 S - raw</span><span style="font-style: normal;"> = raw[x+i];
0 f* e& i& W3 `' I& L( `, W+ f - }
- b: T. D5 T. Y6 ~ - }
7 q6 V7 Q* o; P. D% e8 y1 | - move_right_linear_timecode_raw_7bits(raw, nbytes, y);
% Z& m0 I1 v5 `! {: m M0 T g - }; K0 O; E, A9 l% g3 b! S( ~# H
: d' d M1 i) ~2 ~/ f4 _- # G+ D7 T; Y7 p1 a1 |+ R8 U, U* o# S
- static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits) Z6 J" }- d* z; f0 n& H. N
- {
: p8 ^; m7 r5 R - unsigned char x, y;
- N1 D. r5 {8 Y - # ~: P$ m, t4 w1 C9 x2 ^
- x = nbits / 8;
* W6 M) a, S, ` - y = nbits % 8;* \4 {5 ^: q5 ~- @
- , Z6 v6 m( \, N) p
- if(x > 0) {
/ E. w9 G. J1 _/ x8 E' S - for (int i = 0; i < nbytes ; i++) {
0 a; Q: E, k! h7 j! g! M, O$ O - raw[nbytes-i-1] = raw[nbytes-i-1-x];
* J: W4 l3 ~1 o1 C! `" E# I - }
& W9 ?. O& r4 B9 `& v' { - }6 T0 T: G7 a/ _. h2 Z
- move_left_linear_timecode_raw_7bits(raw, nbytes, y);5 m& H' l; k$ x8 ?
- }* M7 J7 T1 K+ D3 a0 e$ ?( K
- # }/ z2 p. y+ B' j+ Q" ~. G% X
- unsigned char get_bit_linear_timecode_raw(unsigned char index)
6 U1 r; p( c& z9 v& C( j - {( S, f) I% m6 q' j! h
- unsigned char x = index/8;
2 a: m9 h% G( ^5 j# Y3 I# ] - unsigned char y = index%8; X* q5 X" O: d
- 1 p7 K& N \! r( U# C4 o+ I
- if(linear_timecode_raw[x] & (1 <<y)); f' y" K: \' ~% R. P
- return 1;
+ o$ N; B1 }# a0 J - else
0 [, a. U/ V0 \4 V; t. d - return 0;) m% H7 K& d7 f7 m
- }, }/ d- J, `9 i/ G1 I6 O
- 5 w- ~' E) y) q, t* t
- static void parse_differential_manchester_code(unsigned char *src, unsigned char *dst, unsigned char dst_size)
; W( m' m8 a) Z: T/ b - {
7 m! U7 L3 f8 H - unsigned char i, j;, m/ n/ A6 f. J2 `% T+ h; p
- unsigned short tmp, tmp2;
" {1 A3 D: K) p+ E9 I0 b
" c1 {! A; [; y1 p. z; |- for(i=0; i<dst_size; i++) {
' b' @: u4 k# N5 @7 x
9 }3 ?% R2 G/ X- l- tmp = (src[i*2 +1] << 8) + src[i*2];0 h0 }8 ^% L6 w4 ^; _
- dst</span><span style="font-style: normal;"> = 0;
: X" Y& d l, k/ L. n - for(j=0; j<8; j++) {
5 x: Q, t- i4 O9 f9 a - tmp2 = tmp & (3 << j*2);* k% o5 [, Z' D5 H# C
- tmp2 >>= j*2;+ p4 r$ f! S S: b- P# S
- if((0 != tmp2) && (3 != tmp2)) {
" ?9 ]; M2 {* A2 O3 x% H/ a ` - dst</span><span style="font-style: normal;"> |= (1<<j);7 A1 m4 O: W4 X8 B" z) @/ ~7 j
- }
7 S' t% T' \: T0 u8 p. Z3 E - }
2 i. B7 q! r J5 D4 q7 r2 h - }" h b: ~3 Q F+ A) }
- }
; o4 k- K2 b- u! _8 G" P - B, M. D) |( R$ D, }' b( a0 P% g
- static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)# F6 r' m2 b# |2 Q) W8 D% H& V" y
- {
3 Q% p: X5 e" \$ g - const unsigned short sync_code = 0xFCBF;( ~ \: @( V# ^1 A' b# V0 r
- unsigned char i;) h- F- ^4 T( h6 n$ j- g
- unsigned short tmp;
6 o$ }0 o. c \; P3 Z" w - char ret=-1;; p9 ]9 t, O( {9 K4 g( [, p
' T% T" \* }& B4 H5 w' F- for (i=0; i<len-8; i++) {( H& j# n9 L4 \$ U6 R& c; O3 e
- tmp = (src[i+8] << 8) + src[i+9];
$ ^1 b! |% ~; r& S" w3 r, b - if (tmp == sync_code) {
/ h+ e9 S) c4 a2 ~( F! P - ret =0;2 E6 n$ H' v# ` E F' @
- *valid_len = len - i;
2 z7 K2 X. Z( G q) j - memcpy(dst, &src</span><span style="font-style: normal;">, 10); //10Bytes equals 80bits e6 _6 J4 h5 \* [7 k- J
- break;
$ q; ~6 t) Y' z- N - }
- ?- T$ q! a4 w. f) T. l' }# u! Z - }- U. O2 g" Q0 U5 Q- z
- ) s8 a2 T6 x! V2 F3 r& n# b
- return ret;
$ M! h7 G6 H. t* ^3 R
; T- Q2 M! `& w$ H- }
: `0 s" x3 r% [1 r* L6 O$ r) J - , P0 R( h# T- ?, n" L7 A6 l3 A; ]
- unsigned char ltc_dst_code[40][10]= {0};
: [2 Y. x' b) I$ `( H5 | X - unsigned char ltc_dst_code_count = 0;
8 B- F0 e1 W% X+ d5 m - unsigned char ltc_code_valid_len=0;
1 _4 P* U# _/ {- O) _ - unsigned char ltc_code[20] = {0};
" d3 W: H' a* E. V - unsigned char raw_ready[60] = {0};7 e" F& g0 p( E# I% m
- unsigned short offset_bits = 0;
; G! @7 D0 f' r, l7 ^ - unsigned short ltc_remain_bits = 0;
$ t3 w; Q& w; s& M: p - unsigned char sec_ltc_code[20] = {0};
# A$ v- {' E. r+ o; v0 z - unsigned char ltc_dst_code_cur[10]= {0}; _7 F( x' M9 k8 U8 p7 ]
- unsigned char new_frame =0;
% ^+ y- p$ k" d$ }) k. Z - 5 b' f* _! k% K m- f5 _+ O
9 K# E, w' w0 t8 p- void parse_linear_timecode_raw()
2 w. g3 a) J( R" b4 B - {
+ u/ _8 a: l) S" K - unsigned char tmp;9 }6 d3 }" J+ O' V
- unsigned char raw_mv_right_bits = 0;" X4 S6 L/ J9 e7 x1 t+ n0 E2 Q# D4 p! s
- $ d) _" s, A% v2 E+ d: v2 h
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
9 ?4 e/ B5 W t% L. M. O- g, _' [ - isjam = 0;2 b& m8 y. @! O! }
- memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));
/ C# m( {9 W0 g - tmp = raw_ready[0] & 0x03;+ N" L0 ^# I( l4 W* n) z$ }
- while((0 != tmp) && (3 != tmp)) {
2 D# P( [$ A2 O+ h$ b0 K - move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
f# G( L: C4 E! [9 n; { - raw_mv_right_bits ++;
) e! F! G# F k0 w" v4 g - tmp = raw_ready[0] & 0x03;
2 u# ]7 g# c- c$ s* U% K! Q - }- T( j$ K) P/ D/ m4 h
- 9 x3 ?! s6 L( `8 a( w4 Z4 q
- for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {
) O5 u: ^" S& z% V+ \6 i) Z, | - memset(ltc_code, 0 , sizeof(ltc_code));1 F, m4 n( Q/ Z' h9 b
- parse_differential_manchester_code(raw_ready, ltc_code, sizeof(ltc_code));
8 x5 N- E/ P; W. Y& x - //0xFCBF;
9 \3 _5 q! o5 V) J: N9 r/ }0 T - if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {; L, g. n% |* S0 E. r7 y
- linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;3 R: q% w! {" n% z8 l Y/ Q
- offset_bits = raw_mv_right_bits;" `' b, L, v; W, E8 G) ^
- break;" p1 M* o( W' `# J# t
- }7 c- z2 _" `# A. V* D
- move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
* a( e/ N: {, L! f) v - raw_mv_right_bits ++;: B; m. F# _4 g8 `: S* l" b/ j
- }4 U4 n, n6 E/ h
. q8 V" |2 o* E3 c$ |- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {) S4 }- b1 Y; A0 l) }# F0 I# S
- LtcInput.tim_count = 0; //reflesh tim2 period: D3 \6 W; h, R- g
- }; J3 @% `- y+ i$ {6 J, k' C
- * G& r4 r5 \- h8 _3 N* I
- } else {* B( @ `5 N8 j% h. y1 J a i
- isjam = 1;
# Z' `5 I, F2 u1 |& E- s - memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));
7 ?( b0 D& p5 v! J7 t; n. a# E - parse_differential_manchester_code(ltc_code, ltc_dst_code_cur, sizeof(ltc_dst_code_cur));
9 s, M2 b$ a$ ?; H. P7 R2 U8 @ - if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {8 ~6 p) @: C2 A" j
- linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;
) U _3 x$ H& ^2 M ]* J( S6 l% x - LtcInput.tim_count = 0; //reflesh tim2 period% h; D& r+ C5 J9 ~! g! i
- } else {1 |+ F* o4 o8 c) N# ~
- new_frame =1;$ y7 [# H2 }: L# L
- }
0 n2 y- U ~0 d - }
$ B/ d3 j! W4 K. q - }1 F% q/ S# h9 c3 p. |8 w q
- </span></span>
复制代码 1 k A) ~) C4 ~, \- a
3 O2 K* T1 m. B: Y总结以及调试过程中发现的问题。8 _ F% s& I- w- w/ r: C
# I2 ]. [7 {% r9 x, B$ m: b1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us7 T" n0 L. Y& X/ J9 E# m
( O* N8 q" f+ \% q, t7 W9 p
/ a3 ^- U, {4 Z! T' H5 o3 E: H5 ?. I D. m* @
2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
5 J1 e5 _0 w+ \" M( u! ^0 |6 }% z2 m a! A9 Q( r
异常1, 中断回调,里面调用HAL_TIM_xxx , 导致反复进入定时器中断,' e2 Y$ }2 h* k' y0 r6 ~, r
: D4 z: d8 e5 R1 F& h) X" A9 F2 u) @# a+ d# z: a: W" |
: T+ v% s( X/ T2 {2 w& M异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行
+ \8 p. Q$ h5 r8 }0 Y0 X* Y' ~; H6 {- }2 U; K! D
, I n/ K# y8 \) S9 w
* Z% _5 j! K1 p1 y8 K" N `, `解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形
: R. o7 y. h0 e" w- void TIM3_IRQHandler(void)/ c9 @1 T9 Q& M6 g0 S) |9 Q) U
- {% w# r: q! C2 c x8 C
- /* USER CODE BEGIN TIM3_IRQn 0 */9 z" V6 T2 Q: x9 k6 t
- p* q. U8 P6 f8 S0 j
- /* USER CODE END TIM3_IRQn 0 */( K; [7 i" T4 n" }% q" g
- HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
- r- m* N" Y+ l- w - htim3.Instance->SR = 0;
. T) c. z8 N7 z# h: n! ` - htim3.Instance->ARR = LtcInput.period;
* q: P& F7 y3 D) G) ? - htim3.Instance->CNT = 0;8 a+ I( e/ g) Y
- ltc_input_timer_callback();
7 X+ J/ s, h3 E" C - ; t) v$ y1 U3 p$ y% Q* m% N
- /* USER CODE END TIM3_IRQn 1 */
$ R0 E8 p f0 ?$ b' m+ k' G - }
复制代码 ) r* i. F+ ^+ b
0 f, s9 L4 ?. m$ ?- l. v$ f8 U$ T5 N* h3 S# B
( |/ r2 n7 H/ S8 z |