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