时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,
: X5 a6 l, N+ c1 \) G" U. ~& \& [2 m6 o! G0 i7 e
; d; s( }. m! t& y3 l( w
2 R9 R1 L' l/ q+ O2 R) h3 O
- [$ N5 d5 u' d, |3 y2 k实现原理,7 Q( O) I0 b4 k$ V$ o
% D8 a& R7 `6 k/ J+ `4 D1. EXTI Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period4 S: D o. g {0 U; }
& f. l0 n7 F2 E) F2. 继续用EXTI Rising/Falling 中断+定时器方式接收时间码0101值, EXTI Rising/Falling 中断时,修正定时器中断周期为Period/2。! Y4 k1 {, Q; R
: b4 }. N0 A$ o9 ?- S产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period
* m* \7 @1 j+ {; L" R7 A. I0 k, _
3. 解析差分曼切斯特编码,查找同步码6 ?( O" r; _1 u2 `1 w
* o+ U" X0 M+ P6 }5 a' x流程图,
5 a Y' Q& g2 V" G0 h+ n2 j+ e& K/ {2 i9 p0 H9 Y
/ V2 j: R" V* H) V3 N
' j( l5 u. R. r
+ t' i4 @7 j, g/ g8 z! p7 t; ?
关键过程代码,+ r0 x6 N2 K3 V4 G8 L6 \: |
6 X+ L& t) ^0 M2 b3 C
1. EXIT 中断处理" T0 w! F9 b+ a* @' F
9 P( k# x; F2 N/ G8 F7 p) |
- struct LtcInput_s LtcInput = { M: l% l) a# V, x+ e
- .tim = {0},
3 z1 q7 Z6 I9 V- {1 C+ b4 i - .tim_count = 0,& r8 U2 e# F( v5 w5 A9 U$ V
- .period = 0xffff,; M; u! Y$ a$ s* r6 I- I' h3 m6 ^& h
- };
9 t# C& A# o; [! ~( m' c8 k0 ^4 P
7 ?8 a. u3 J2 V0 ]6 _- static uint16_t parse_tim_of_ltc_input_get_period(void)
# G! I/ W) B0 j7 ^4 h3 z# z - { K. L# v! b" F
- for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {/ _+ i, I5 [6 z' r3 z* n
- for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {( J, r- ^+ \$ @: Q- P: M
- if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
1 f7 P- O- ~( Y$ l! d6 S - <span style="font-style: italic;"> uint16_t tmp = LtcInput.tim;
7 q' ]4 Z9 F: A8 t* q - LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];* Q. k2 @1 K4 V M
- LtcInput.tim[j] = tmp;
. K+ I# z S) i7 _8 n0 M$ q+ g - </i><span style="font-style: normal;">}
3 `& |0 n, F4 a7 ]" _6 Z9 | - }7 N; q* }# I7 t7 |1 a
- }
. I' k2 G3 M, I$ a: w$ _8 w% R - uint16_t period = LtcInput.tim[10];- Z& z/ V) O! a F# C) Z* C6 i
- return period;! z1 u$ T9 ~, L# c
- }7 t, \1 H$ }/ G, X( D& H& ~& t0 m& M* `
5 ^) m, W! m' R4 x* u# R- void ltc_input_timer_restart(int period)
5 R5 ~" }$ ~+ Y8 G2 b1 Z0 X - {
: j- x( V, o$ O& ?3 D - 9 ]! K+ R4 m5 M% ^" \5 P5 m4 Q
- htim3.Instance->SR = 0;
8 e$ E6 U5 u. d6 q) J - htim3.Instance->ARR = period;$ M4 `, \: @; b4 W& k- Q' @/ q- p
- htim3.Instance->CNT = 0;. h/ h% ?, w# a% m4 d* s
% Z, o4 i+ b) I- }
8 {9 f$ Q7 v& y) h
. _2 O6 j+ n% n- void ltc_input_pin_callback(void)
/ H% }7 Z- S" O2 J" _7 m - {) ~7 C! C2 o* [
- // HAL_TIM_Base_Stop_IT(&htim3);* S, [ r0 V7 q
- if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
5 @7 ~' q: G/ t& c& m+ F/ T" w - ltc_input_timer_restart(LtcInput.period/2);. _5 L/ [" r x, l! }7 N
- } else {& k* g# t6 l) U6 j4 Y5 P
- LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;
6 O+ X- p- d X - LtcInput.tim_count++;
5 Z0 D: f8 v1 X. \) G, l# V - if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {; V' ~# w: S4 m T2 S s8 u
- LtcInput.period = parse_tim_of_ltc_input_get_period();( J- z) v1 }' I% P2 {- e
- }$ R: g5 a( S; c. n) C' B B, n
- ltc_input_timer_restart(0xffff);
z" v& [: y3 S ?3 M, Y - }" h( L" O5 [& V; P* D( B
- }</span></span>
复制代码
1 `! k. F) K. y1 \2. 定时器处理" H }1 G4 X3 u7 ?( K
- /**
$ t8 U- z$ o( e' }1 w0 @/ ] - * @brief This function handles TIM3 global interrupt.; s( k+ G& l5 Y1 G* K3 h4 ]" g4 P
- *// U8 \1 f1 K( T# x
- void TIM3_IRQHandler(void)
O0 W3 X5 i$ K- v$ J) Q - {( ~, F5 R- ?! i
- /* USER CODE BEGIN TIM3_IRQn 0 */
i! z; J" x' E' s& B3 M$ Z7 y
" {8 b9 E3 j2 U/ b% D, W- /* USER CODE END TIM3_IRQn 0 */
$ I; [5 M7 M( N" ^" p2 d: T6 w- ]1 l - HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);8 c o& D) z2 @
- htim3.Instance->SR = 0;
' U* e$ _* T/ N* v- f% S8 N5 b - htim3.Instance->ARR = LtcInput.period;* z H z q9 y. Y2 B( R
- htim3.Instance->CNT = 0;5 h( `; v; n2 U+ ?& e8 G% u2 B
- ltc_input_timer_callback();
" ~" F4 B9 N) c! b9 c - ' C8 e( C+ ?+ ?) c
- /* USER CODE END TIM3_IRQn 1 */$ B; P) L8 i0 k* @
- }
% X; v$ T2 h5 R# b" }! O0 D; X - 2 X# A' ]( [ y) p& X; c% _9 z
- char ltc_input_timer_callback(void)
+ Q# P# d+ d' ^$ N - { ^* c; v3 [+ D$ m% C" o# d
- GPIO_PinState status;
$ Q+ t, L/ q9 C" o- ^/ R$ A - unsigned char x, y;1 o! u* j4 V4 Q: A
! U$ J3 G9 y3 N- status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);) Q9 R ?; z) f' G, ]" G
- //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);
6 L2 ^! ]6 V& _0 t - //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);$ u Y& p3 v1 i r
- + N% U8 N) O* H) ^6 S
- //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);; `4 i3 I; A6 ^: z5 r. U
- //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);
( a7 M* W6 |4 S H - //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));
4 L I" Q( w8 _$ b( E - $ s3 Y1 w+ L% L( I- ?, b. p: V
- x = linear_timecode_count /8;
, U+ r0 Q( w- ^3 I/ Z - y = linear_timecode_count %8;
+ y, [+ |+ x9 O$ a5 K8 y - 4 W$ {8 P8 r3 V+ `* l
- //buf[linear_timecode_count] = status;# d# M, v. ~1 i
- linear_timecode_raw[x] &= ~(1 << y);. v* P+ E0 k* Q1 {* R8 h
- 8 s2 T; s# D8 s$ ~7 s3 `
- if(status != GPIO_PIN_RESET) {
7 Q: F# P- x- b6 {( D - linear_timecode_raw[x] |= (1 << y);
$ Z6 M7 }4 x& r( ^ - }
) h* G% |) Z$ R6 o% Q - " ? E+ L3 @8 X ^* o5 \
- linear_timecode_count ++;
$ {2 ^! ]0 e! q% x! F* |1 Z7 X - 0 X4 Y* I7 G: Q
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
" {- x+ B7 d0 E# {. i* n9 { - if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {4 @+ V4 N8 H p* X- d- P
- linear_timecode_count =0;1 s; Y" G' a; l; f0 ]& C5 L
- memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));
) {9 A7 W! B# h4 p - linear_timecode_ready = 1;0 }+ f* R9 h, { Z
- }
7 g6 T+ T6 o# G) {) A S - } else {1 o$ r2 w! Q( M% w% E7 y$ ~! X
- if(offset_bits > 0) {
0 Y8 v$ R5 ^9 N; e# K - //skip offset_bits
. q+ |' B, z/ B* Z2 H }3 L - //If offset < linear_timecode_count, adjust the offset to the next frame." R5 o/ E6 w' h7 N" ?/ X
- //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.
& Q k( ^! u& ^$ |9 G* }- L& G7 I - if(linear_timecode_count > offset_bits) {8 M2 @& H8 }3 X8 {/ `0 K
- offset_bits += 160;4 U" Q3 O* I. I& F! h% K6 y
- } else if(linear_timecode_count == offset_bits) {9 o+ _2 q' I5 Y+ b
- offset_bits = 0;
, q8 b% A9 q. u6 B) R' L - linear_timecode_count = 0;2 V2 ~6 g. u+ S* r7 m
- }
4 E0 L+ A2 n5 C; B - } else {) ]4 F7 G; A+ i' |$ z
- if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {
! Q, ]( a: [0 u* `2 M% {+ s3 I' ^6 ~ - linear_timecode_count =0;
* H, P5 [, P* u- z - memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);' i) O$ f: L- e% M: F) \2 D
- linear_timecode_ready = 1;. Y9 x6 y& J+ s6 e8 Q
- }
! q. Y' a9 l7 X* X3 j& i4 d - }
- t4 X4 l8 A- b/ U! ? - }
6 a7 Y5 w0 z: I+ I4 U" s8 B/ U- p - return 0;+ |% x. D2 z% A9 z5 O* w
- }
复制代码 8 |; l, \& g& [7 \ d* \: `. S
3. 差分曼切斯特码解码# ?2 ]: T8 B1 \9 Q7 L% H) w
) ^- U1 A2 E- U1 Q8 E/ t) |: l- unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };0 X' S% B2 R, T& K% i
- unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };- ?4 a' Y5 S# i' ~ n$ {. Q1 U
- + b, X% R0 S, @$ M0 p! Q
- static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)# n( F3 n. N0 p1 z/ V) v/ V- M' ^
- {
; V8 r" F( V+ {- P - unsigned char i;5 {" p7 @1 E J L. @) O5 d5 [5 @
- unsigned char tmp;6 P. u3 e+ a- r
& G2 U! z( D2 V, d- if((nbits < 1) || (nbits > 7)) {+ D! u) q; i6 v) r5 U' q
- return;
4 H' x7 ?& h5 r' X* @. v - }
( @9 M( e, t N. F% l3 Y - $ E5 F/ t" A0 q: J" z T
- for(i=0; i<nbytes - 1; i++) {
! B( o- E" g$ i6 s - tmp = raw[i+1] & r_mask[nbits];! d/ V, W, P& G$ i Z, ~8 y
- tmp <<= (8-nbits);. z7 M. k d8 d3 l: R
- raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;6 f5 k+ u' l/ v. Y* Z0 d6 D8 b
- raw</span><span style="font-style: normal;"> += tmp;
7 [, V% l% L0 { u: E1 Q- a - }( |& {& \! w0 N0 V' i" N8 U
- raw</span><span style="font-style: normal;"> >>= nbits;
8 H$ O8 x( \( h+ n8 \ - }
) a4 e/ g# x {% ]) Y; o2 r5 g - ) L% ^8 U" l* r& k
- static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)6 [- ]. F6 }6 K4 `3 U
- {6 o1 ~& }0 y( h4 ]
- unsigned char i;
5 w4 R |3 T( R/ N; r8 }$ X - unsigned char tmp;
5 Y; T: M1 ]9 ~% k+ W' @
& p% d j1 ^4 p- if((nbits < 1) || (nbits > 7)) {
! e9 u) ]7 G, p/ `% ~ - return;
5 r# P, Q: ^- n% O8 h1 ~ - }
3 t2 F$ L$ A; h# s) O6 r# M; Z# { - , B) O% j* E4 v' R& @( F9 J
- for(i=0; i<nbytes - 1; i++) {
" k. k$ \5 {9 ]. h - //prev_bit = raw</span><span style="font-style: normal;"> & 0x80; ?/ D/ ^# h9 i+ e0 [, ?
- tmp = raw[nbytes - i - 2] & l_mask[nbits];
: n4 E; r/ ]! P1 o - raw[nbytes - i -1] <<= nbits;5 ?) C1 e) {6 p* ?) T& @4 I
- tmp >>= (8-nbits); p5 f Q" Y: c; \
- raw[nbytes - i -1] += tmp;
9 q7 C. V; D p0 [4 u - }
$ ]' r* R! {! c, G5 N, d/ H7 j - raw[0] <<= nbits;5 l9 x4 p' ?3 p4 _8 i
- }3 _- e9 {/ o6 Z' M/ o- {( K- u2 S L
& S$ i5 P& X( \) Y4 A5 }* t F- static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)- U0 ~* l* l) y O/ v9 d
- {
" _1 z' x1 B$ e* @5 e5 W8 T9 b - unsigned char x, y;
2 |6 b* J. d$ w& n% Q( x - / {& |- E; e# c' t
- x = nbits / 8;
, S9 @. d0 o' t7 h8 p - y = nbits % 8;% ]; O6 r! H% q
/ v a' @, S5 b1 [3 g- if(x > 0) {* S( Y, j0 O: ?0 v5 \
- for (int i = 0; i < nbytes ; i++) {
1 v) Y3 h* ^( s& @1 \0 \. H - raw</span><span style="font-style: normal;"> = raw[x+i];. [% Y' G6 t6 F, C4 a4 M
- }7 H3 A# b {, @6 L4 k
- }
0 x6 O! _# t6 i2 R6 {! I0 ? - move_right_linear_timecode_raw_7bits(raw, nbytes, y);4 a+ H# ?; d( \2 P, E
- }7 u8 j$ q ]: U1 [' u, I
7 Q% N3 z) O0 c+ R% D
3 |: Y. K4 G+ ]- static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)
" o; ?* U, s% u5 J3 ^6 N) S! L- m# v - {$ g8 f" G" l) c8 b* ~7 }1 _
- unsigned char x, y;
! e$ G* T, p. x2 Y9 n/ t6 O; Z8 C8 n
1 f5 z; ?4 l g; g: ~' x7 q# p- x = nbits / 8;
( ^8 n: T8 x' F: l1 ?8 x - y = nbits % 8;& Q @" A8 s' @0 l$ E" n
- # a0 f! _4 O& z a$ t0 b
- if(x > 0) {
) B7 _! F6 }! l5 }* B$ K: Y; S - for (int i = 0; i < nbytes ; i++) {
6 B# d% @- k5 l* L) R$ ] - raw[nbytes-i-1] = raw[nbytes-i-1-x];% Q# V( P/ t/ h
- }
1 Y3 G! I) G2 } - }
4 h5 ], _! L8 U& g. A" A# \ - move_left_linear_timecode_raw_7bits(raw, nbytes, y);8 W- f# h1 W: q3 p; G6 H
- }
. j D8 q$ q; i6 I4 ]
6 @7 H- b) X9 k7 o- unsigned char get_bit_linear_timecode_raw(unsigned char index)
7 l, D4 A& @& [3 ` - {
% `1 T2 o1 ]" g1 ]% E - unsigned char x = index/8;/ I7 \1 {) O4 s; K8 D; n: @( x
- unsigned char y = index%8;$ w' ?) |, H- k5 ]
! D; y9 R0 E2 \' g6 y: w. ?, E# @- if(linear_timecode_raw[x] & (1 <<y))
; L! g6 n! R$ \; R# k! J: ~7 j - return 1;
$ k9 d; ]6 i$ W* N9 l" s* ], Y/ i - else
( H5 ^4 W8 ^' A; C6 B - return 0;
9 B. e" h) e6 j b1 i' Y - }
: x2 B2 I- m. W% P: Q
8 h. P! D1 U) r1 s8 l- static void parse_differential_manchester_code(unsigned char *src, unsigned char *dst, unsigned char dst_size)) [" C0 q; w6 P; b
- {
" z' p3 K7 q& w0 n - unsigned char i, j;
- W7 X5 Y/ |. i) j) M; [" r - unsigned short tmp, tmp2;; b4 v) ?8 [ F
- / ^9 ]3 V7 A. C1 D
- for(i=0; i<dst_size; i++) {& h8 ~ \- z9 ^4 @; q R7 a
- & ^1 }: \& w* C9 B1 B. E% e
- tmp = (src[i*2 +1] << 8) + src[i*2];1 u' X. i* J6 E* V! H
- dst</span><span style="font-style: normal;"> = 0;
B4 o4 y: i7 }: @& h% r3 B- t. I - for(j=0; j<8; j++) {
& W( _- Q# p- X( r! Z4 m - tmp2 = tmp & (3 << j*2);6 U( V3 q8 O! @
- tmp2 >>= j*2;2 b. G/ j I4 E* y# I. m1 c
- if((0 != tmp2) && (3 != tmp2)) {$ Q$ H/ l0 @& \6 q+ x' o
- dst</span><span style="font-style: normal;"> |= (1<<j);
0 T' t6 E# b: z - }: E. E8 W' K8 }$ y, P# `
- }
' I* ?2 Q* Q& F$ ?& f9 F - }
4 ]) W+ J% j& T" q7 A - }
6 O7 e. q4 c+ ?; M# D4 x# [ - ! ?" l2 d+ _" m7 @
- static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)
- r; Z& u% r2 ]; j, f+ H6 ~ - {
/ T0 e8 v y. O; ]* Y - const unsigned short sync_code = 0xFCBF;
7 @9 K4 N6 U) x3 m; n, e" f - unsigned char i;, x( ]& I! u/ y+ _& j S# o& [
- unsigned short tmp;' ^+ D" G& s X6 b' G) L
- char ret=-1;
; y4 l( m4 H( u+ j
) Z2 x- m- Q* C- for (i=0; i<len-8; i++) {
F1 l9 d e* f9 P - tmp = (src[i+8] << 8) + src[i+9];
3 q6 o2 G" i. c1 m6 Z( p - if (tmp == sync_code) {
' X' J! g4 f8 U& n" w - ret =0;% f0 M6 g4 \& r' ?, k) | }
- *valid_len = len - i;
: d% \2 t/ d! ~. W0 p - memcpy(dst, &src</span><span style="font-style: normal;">, 10); //10Bytes equals 80bits
' q) o$ a. H+ h/ W6 w2 n - break;. W2 s; ]" M5 Q2 q
- }0 v9 C3 ^: k% o8 I% \$ M6 ?
- }7 e( N; z1 M- o6 c$ U8 k. l; [; X
- . P( y' h Y- s2 z, U+ [' o/ H8 \
- return ret;! k I0 V3 Y- T2 f7 s: n
- 5 Z; M! {4 z O* R8 y+ j0 f
- }
5 `% V$ U6 `% D5 ]! \
+ G+ K" W( q8 h' m, D; r- unsigned char ltc_dst_code[40][10]= {0};0 x+ j+ ^- {; L, y' x3 _1 a
- unsigned char ltc_dst_code_count = 0;4 Z8 d8 s+ p6 p+ w
- unsigned char ltc_code_valid_len=0;
A, M$ ^) E: q - unsigned char ltc_code[20] = {0};
" \) ?" n+ I" ]' d: }, a - unsigned char raw_ready[60] = {0};
- K- c6 {$ \8 p7 c3 W$ z. } - unsigned short offset_bits = 0;
: \' ^5 Q2 u- C9 b Y# m1 ?% g, y - unsigned short ltc_remain_bits = 0;/ [7 Q8 P" k3 X" F! [
- unsigned char sec_ltc_code[20] = {0};
* c* }( G' \. U, n - unsigned char ltc_dst_code_cur[10]= {0};
; _ m0 k9 r. a# @; |+ m* P - unsigned char new_frame =0;& C; n' {1 c# Q# x; p. q
- $ L; \. s# Y$ n8 P9 ?: q2 X
! A9 j$ E1 S0 D8 T1 V- void parse_linear_timecode_raw()
( E6 L7 l# g# _' O' C+ l - {4 r7 e, J) ~& Q2 _4 j" ~8 T" C) l
- unsigned char tmp;+ r; r; Q* I0 H& }3 z; y
- unsigned char raw_mv_right_bits = 0;% {+ `2 o T" ~# q6 z1 C6 G( m
z" k9 P( X# h; d9 Q6 Q- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
5 \' c4 ^( `2 m) [, R+ U1 @" Q% l& y - isjam = 0;
6 \, k3 W# C; V6 ]9 j0 v: `6 }; h - memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));
4 @& i9 y/ L+ g% ] - tmp = raw_ready[0] & 0x03;* Z5 M) d* m& Z/ d3 A1 h& _
- while((0 != tmp) && (3 != tmp)) {5 i' M4 K1 x: l: `
- move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);+ u* q! e. d& ~1 F- F- }. U
- raw_mv_right_bits ++;
X, p. Q. @6 ?: } - tmp = raw_ready[0] & 0x03;
. x6 @6 l0 w$ e8 R- B - }; ?" x1 h. x i8 m% N/ G" { W* v, C
8 v! B4 w' ]% m1 ~% V# U; z- for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {9 p$ D% y" N6 U
- memset(ltc_code, 0 , sizeof(ltc_code));4 x0 A2 [) v0 z+ ^
- parse_differential_manchester_code(raw_ready, ltc_code, sizeof(ltc_code));
! w: I9 V$ @0 \ z8 H9 d8 j - //0xFCBF;) X* K( z! D) J; a6 b7 C/ X, w
- if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {
* g0 K+ m/ G7 f - linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;
0 ~' T: C4 g. w" F# A - offset_bits = raw_mv_right_bits;* | v i; T6 j k+ w; i* I
- break;
( E6 b0 X6 P: h - }, B6 \5 W) M9 N9 y
- move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);" l. c( R& \; {- ]* L! V
- raw_mv_right_bits ++;6 Y. x, }$ n- L1 u5 ^8 K
- }
) H8 C& Y1 E8 H" O4 `5 Y - % M; E, |# N p: \# Z( B
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
4 B+ K W/ g6 e - LtcInput.tim_count = 0; //reflesh tim2 period
* W2 D$ ^- Z* q& F/ R- P - }. w- r' V' n! \" t6 |6 W0 X. h3 D8 Q
7 W1 h& u- {. Z& m& d) {! b: u/ b( F* Z- } else {
% H7 W: T6 X+ D) ?1 \* a+ g/ _" N - isjam = 1;
@( S; P* A, i$ e - memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));
7 I8 R, H+ o8 y - parse_differential_manchester_code(ltc_code, ltc_dst_code_cur, sizeof(ltc_dst_code_cur));
& h. j/ A6 s, I! D+ V7 C, r - if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {- \2 o6 I& s3 t, D& i9 H8 h
- linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;9 x+ n' `5 |3 u+ Z' O
- LtcInput.tim_count = 0; //reflesh tim2 period- {; y. R; h9 Z0 X, z. ]
- } else {
5 f6 y! f& A. l% l | - new_frame =1;
7 S! q% c( \, z! \. K/ _7 ? - }
% E5 v. z H$ J* t3 f - }
7 a# i) {; p( h. @! H9 H - }
( K! e$ Z+ S& v- R+ T5 U, q" Z - </span></span>
复制代码 2 W' t9 D& o' `; O
) Y) b ^6 A8 R# {8 X总结以及调试过程中发现的问题。
) [- h; L& I7 b! i+ X& h" v0 K3 r4 v; Y( }* y# m6 z: [; f% k
1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us
9 p% m# F' ], y8 B s( R7 y
) V& Q _0 u: K9 @) g( X6 A2 P) ]8 \/ `
3 k X: ~. ]4 Z2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
* v: v& S, A; h5 M+ A- t- T: `! ]) t& H4 p% J/ R1 P& v5 E
异常1, 中断回调,里面调用HAL_TIM_xxx , 导致反复进入定时器中断,3 A1 g3 x* I4 `: j( _" h2 u
! N q# D) m4 d, k% F
* D- W+ E: z, c0 V& k! R, x; I/ Z
异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行
4 Q2 J8 Q. o( y9 [# C% ~
5 H# i. b0 ]3 f {" d: q4 R" F" x% X! V4 y. A! W, H+ o
7 Z3 W, k& i% N0 s9 a3 W& z解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形
8 K; D1 Y* B# D, `% u- void TIM3_IRQHandler(void)
5 [* {+ h5 @0 e" Y% p - {# I- c- ~9 w# U3 h3 k" ~& \
- /* USER CODE BEGIN TIM3_IRQn 0 */8 @/ { p6 k. T- A
- & C5 O) n0 q# y: H; _" c
- /* USER CODE END TIM3_IRQn 0 */
# r# a5 g2 {! a6 R3 @" A: ^ - HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
8 z5 h: @6 a' ~# n8 s, k - htim3.Instance->SR = 0;
, I/ @0 l. X/ a. k' _# K - htim3.Instance->ARR = LtcInput.period;
e9 ?, j1 k* I5 J) H( G& m - htim3.Instance->CNT = 0;
& q* r) O3 K) Z; O h# q, ~ - ltc_input_timer_callback();
5 V$ m: J) |/ ]! N4 N% |
; m; I$ [+ p& L. R1 v. { D- /* USER CODE END TIM3_IRQn 1 */4 i* i) Q9 n9 c( G! L5 G
- }
复制代码
4 A$ p( B _0 j% ]& ?; |2 T( Q: V$ |
4 N/ ^1 W# `8 m) r# {- t
. N& j8 O" k Q0 P, B |