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