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