时间码发生器通过两条线与MCU相连,一条是地,一条是信号线用于传输数据。信号传输使用差分曼彻斯特编码。电平±1.5V, 信号传输的速率960Hz 到 2400Hz 变化,需要软件自动适配。 时间码固定为80bit数据(bit0~bit79), 其中bit64~bit79 为同步码,固定为0011 1111 1111 1101。 部分波形如下图,* V6 X4 @; k& l# ?! s$ E
& c' Y. T4 `# q. B: h
) R4 G) g6 w" C1 p
* c1 K+ Q+ K$ g2 L, J. M4 G( ]$ ]8 h8 i1 x) [! \; |$ y
实现原理,0 w; _% w& e# ?# E* Q+ D
& r5 r/ {) [- a" x" |; T% n
1. EXTI Rising/Falling 中断+定时器方式测量100次波形脉冲宽度,通过排序算法找到合适的值确定为定时器周期值Period
/ F* E$ i( u$ w% u. k: Q& f0 F" M8 J3 M+ R. m" H
2. 继续用EXTI Rising/Falling 中断+定时器方式接收时间码0101值, EXTI Rising/Falling 中断时,修正定时器中断周期为Period/2。
8 n. I4 R7 H% q% o2 ^: E3 @$ i% }
0 {" a9 A; G( Q& \4 U$ g2 t1 _" _2 [产生定时器中断之后,取Pin 值保存,修正定时器中断周期为Period9 V( J% W9 ^! F, K9 l6 K B. C& g
0 e- B6 ~ o# `0 |+ X7 N% D1 I: Z3. 解析差分曼切斯特编码,查找同步码5 i. H9 |) i; o6 w! L* U
0 c$ ^8 w d: j5 |% B! c. E% u流程图,
% {8 A+ \: i9 H; J1 ?6 v3 f9 e* g/ M% N
; M3 ^: r( V0 ~3 h- u9 W
/ l$ A; ^) |! T* S! ^; v d1 w% K! U; k4 j( c0 [
关键过程代码,0 |+ e8 |% y. a6 ?2 g/ n% K: y
: a( M# s" l5 d6 t Q5 k# E
1. EXIT 中断处理$ Q: _ V9 i6 e& X+ ?, m7 u
; D4 s+ ]7 N& W8 j% L3 D
- struct LtcInput_s LtcInput = {
( h+ f$ T" K; x7 u" s - .tim = {0},4 y" s h* M, v9 X& E6 ]4 F) J6 ~
- .tim_count = 0,7 e+ p" P |( h |# l7 j K
- .period = 0xffff,
R. O7 `3 R" B! k/ S - };
* j; \" v4 n# s7 ?3 j
& y0 a8 F* N& T- g* I- static uint16_t parse_tim_of_ltc_input_get_period(void)0 K& i/ q8 z3 a: `/ Z7 F$ `
- {6 q: U5 e8 e" M) J, h1 m+ G( I: U
- for (int i = 0; i < LTC_INPUT_BUF_SIZE; ++i) {2 s r2 N% K4 Z) f: `% q) n
- for (int j = i; j < LTC_INPUT_BUF_SIZE; ++j) {. q9 T8 q; j. \" V
- if(LtcInput.tim<i> > LtcInput.tim[j]) {</i>
. s+ U- y7 y; a2 H - <span style="font-style: italic;"> uint16_t tmp = LtcInput.tim;
# L7 @+ m h1 h& E - LtcInput.tim<i style="font-style: italic;"> = LtcInput.tim[j];
0 l9 O) w o+ B4 C. _8 g( @ - LtcInput.tim[j] = tmp;
5 `7 S: @4 F; m& `7 `/ w$ W$ B - </i><span style="font-style: normal;">}. e% F; D' M6 M1 ^7 c0 c
- }
+ s6 w- I. ?3 G! O% U4 z5 ~, @" D4 a0 y/ T - }# X; U8 \4 _. a% S' s' t
- uint16_t period = LtcInput.tim[10];
$ j: z- i5 j% O1 T$ x2 c - return period;* F5 ]! {) i- P* {$ K( A" L9 J
- }" Z/ k9 V2 M8 l0 f
& N. Q M ~5 b- void ltc_input_timer_restart(int period)
2 p4 W6 v1 N& f/ U' ] - { s& Q, _0 n+ l4 g' {1 _
- 6 T8 E! S$ I* ?- k: F5 x& u
- htim3.Instance->SR = 0;" D9 ^5 d5 ?/ |5 |
- htim3.Instance->ARR = period;
7 X2 C H* p7 W0 z3 T, M - htim3.Instance->CNT = 0;( |2 [# j \3 j) U; m
- ; K$ R; @6 E$ ], F! W! n" s$ h5 N% l; Y
- }$ l. u9 U- S0 O X% Y# q
1 M* b* \: Z+ s) Z9 s- void ltc_input_pin_callback(void)- _ p! c b1 f4 P- J& B
- {2 Z3 f0 C$ V$ s- a0 i: m
- // HAL_TIM_Base_Stop_IT(&htim3);
0 N9 q3 h$ U8 R) ]* z) p6 K1 b0 h - if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {
, g* j7 b2 p, N" r7 z - ltc_input_timer_restart(LtcInput.period/2);
( S/ C2 M+ K& v - } else {
4 `4 I" }- g5 c+ x - LtcInput.tim[LtcInput.tim_count] = htim3.Instance->CNT;# S, H, V# v5 s7 Y, M
- LtcInput.tim_count++;( O% ?% ]7 U! C6 A8 J
- if(LtcInput.tim_count >= LTC_INPUT_BUF_SIZE) {$ e% N. V% h0 ^; n2 B5 t- Q- [
- LtcInput.period = parse_tim_of_ltc_input_get_period();
4 b' V1 ?/ J: B8 M# t$ T - }
- c& p2 y" W: ~# c# I - ltc_input_timer_restart(0xffff);3 U6 ^9 v4 q" r
- }
1 z% O* S% A& v - }</span></span>
复制代码
9 _' N7 w. l# K8 s( y9 e2. 定时器处理6 T3 H, n$ S7 p+ X5 ]* G! m0 s
- /**. V+ g+ B) |/ }8 J
- * @brief This function handles TIM3 global interrupt.7 P1 [4 D" w! ~
- */
6 E) `$ v! Y5 f2 Y - void TIM3_IRQHandler(void)& Q/ q# D, m1 G% y$ S! g
- {
8 g. w1 R+ w& G. O( h - /* USER CODE BEGIN TIM3_IRQn 0 */, _; {' |" f" c! j+ [
- , L. N' [0 @) r8 H8 p: b. a) ~' [
- /* USER CODE END TIM3_IRQn 0 */6 T" k) p# [+ W! D! _
- HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
9 x6 D# W$ M0 N% h - htim3.Instance->SR = 0;
# b- S+ f5 h! j1 I. V4 w0 H - htim3.Instance->ARR = LtcInput.period; ^- [$ ], G3 w
- htim3.Instance->CNT = 0;0 I# q$ K) [# d% v6 N+ g6 ?6 |
- ltc_input_timer_callback();
% r/ w, G/ w) Q7 b7 a - 4 l* c/ A4 ]# {* J9 ?* C% `' m
- /* USER CODE END TIM3_IRQn 1 */
5 Z% }% x: q& v4 y: `" L - }
3 O/ [5 N' J( t0 v/ ]. j, _/ s
* N! G; C9 A+ ^* K2 r7 m4 V- char ltc_input_timer_callback(void)
5 t* Q& ?) ]) z6 i! F+ Y' L - {* _9 Y0 ~7 _+ B0 H4 _. t
- GPIO_PinState status;- }( y3 ?3 Q1 w2 Q$ o
- unsigned char x, y;( s: v* F6 {$ J. w
- , u/ i; L$ m0 U$ I. h+ [6 X
- status = HAL_GPIO_ReadPin(LTC_INPUT_GPIO_Port, LTC_INPUT_Pin);
5 r" f+ p# V T" o2 D+ H - //status = GPIO_ReadInputDataBit(LTC_PORT, LTC_PIN);0 S$ _- |/ T0 a$ c3 {8 n) ~$ V* A
- //HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
! \6 O. T8 C Q
6 p9 |+ ^/ A. {3 R" ` W- //GPIO_WriteBit(TEST_PORT, TEST_PIN, status);, \8 K+ E- G5 @) l- X3 u, U7 x
- //GPIO_WriteBit(TEST_PORT, TEST_PIN, SET);
. l: Q9 e- m; D* o5 B& h - //move_right_linear_timecode_raw(linear_timecode_raw, sizeof(linear_timecode_raw));
: L& L3 M/ C3 u
% F6 Y; o8 J5 u5 K, `- x = linear_timecode_count /8;
! V' U$ I% b( ^) |5 C+ Z9 u$ O. u - y = linear_timecode_count %8;7 |2 d* ]" p" ?# Z* S, L. y
- 8 K- y! h0 \6 }4 ^8 L3 f& M- j
- //buf[linear_timecode_count] = status;" n& d" e3 M. o& i9 f
- linear_timecode_raw[x] &= ~(1 << y);. Z' g! w) O' ] e- O
- 9 k0 {/ K& X9 W& L
- if(status != GPIO_PIN_RESET) {7 ]8 y2 J6 a$ n" y# ~) s
- linear_timecode_raw[x] |= (1 << y);
4 `7 H1 e4 J* ? d* R% ?3 n - }0 g/ _' S3 u; D2 Y1 \( Q; N9 A
+ |" d# U# I3 P- linear_timecode_count ++;
/ S& N. h4 K1 h% g - - ^# s+ \: _; P1 D1 v% d {+ H' ^, j
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
3 ]& u' N: L; ~: p) L/ w - if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8) {
: A$ e) I8 L( f8 N0 [. @% H - linear_timecode_count =0;: m' U* o) \6 `8 Z7 _$ ]/ M
- memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw));
2 j+ ~- I ]3 \1 ?" a3 _; _; \( a- ~ - linear_timecode_ready = 1;
( r' i! @& f& F- y v. N - }, B" _' d: c- N" e: G+ m; {
- } else {
& M1 ^5 `2 b$ l. ^* Z2 y n+ E - if(offset_bits > 0) {
: M2 A8 t! a- v - //skip offset_bits2 K# y& k, B1 B! F5 g
- //If offset < linear_timecode_count, adjust the offset to the next frame.5 D5 d" i1 j: A- n
- //Next time, when count = offset, the counter is cleared. From then on, each frame starts from scratch.7 L' r, W% Q6 z( H' e4 I
- if(linear_timecode_count > offset_bits) {
! ?9 T8 v% d1 O7 A3 N6 \ - offset_bits += 160;
7 e7 l! `7 i& I3 t4 |) H( F - } else if(linear_timecode_count == offset_bits) {* [4 T& C; R" k+ d' z
- offset_bits = 0;
* T% ?& p7 {; i6 P1 G3 k2 }1 w m - linear_timecode_count = 0;
( n5 A$ p0 _: J/ J" u8 K5 p& L - }
8 H4 s9 @+ }; G7 o4 j0 Q- l$ i - } else {/ k- G, d2 l4 s( W' y' y
- if(linear_timecode_count >= sizeof(linear_timecode_raw) * 8 / 2) {
2 T& w$ y# n% v+ o - linear_timecode_count =0;9 T9 R% E& [' Z! D
- memcpy(linear_timecode_raw_ready, linear_timecode_raw, sizeof(linear_timecode_raw) / 2);
, z3 k# L% Q) E7 D; D - linear_timecode_ready = 1;+ V! C, g6 b" @8 R6 q( u# Q8 d6 B
- }2 j+ l' u9 A2 f" Z( ^" A* A# D
- }% y# \6 N9 s( C+ o$ t$ F& |
- }
* y& Y/ [/ p; f" q - return 0; A7 ^& s( l) i- S8 T* N
- }
复制代码
1 t8 J3 t4 n# ?9 A1 o. P3. 差分曼切斯特码解码
: M& P& Q8 P1 c3 k! U- |8 I
* b5 |4 C8 t5 X/ E' j- unsigned char r_mask[] = {0x0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
( q# E% @# T$ x C3 O8 { - unsigned char l_mask[] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };) m7 ^7 z6 Q7 R% m& d* d
- 7 Y& U& B& T) d' x7 }$ s. N
- static void move_right_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
! e8 H4 k; j$ X7 R6 g$ `. B c - {
, R% M n+ w. Q# y+ w/ ]2 f - unsigned char i;& S) J( X6 f* v3 z$ x4 G
- unsigned char tmp;
7 k b9 \, y' g% ` - 8 E6 A. |' ? b$ f
- if((nbits < 1) || (nbits > 7)) {2 Q8 b' \. S3 U! k
- return;
! T4 d1 _4 y* M9 ]3 h- T) {2 P - }
6 V1 _+ I5 o' ], P" M% X - + u6 M* T" |! a+ G# [( {4 N
- for(i=0; i<nbytes - 1; i++) {
. F) s/ b6 y! l3 K - tmp = raw[i+1] & r_mask[nbits]; W; }) b2 S9 j% d$ G
- tmp <<= (8-nbits);
9 U0 E- `; e: u& @0 e7 \: K - raw<span style="font-style: italic;"><span style="font-style: normal;"> >>= nbits;
' D+ A/ N* _4 k, n8 Q3 ~. m - raw</span><span style="font-style: normal;"> += tmp;) h5 K& V" Y$ L# J3 B$ Z
- }9 N8 |; h+ k0 J2 K
- raw</span><span style="font-style: normal;"> >>= nbits;% n C, f2 n1 ]2 M, V( h1 ]
- }% K/ H4 `! b5 [
Z+ B# z. E u- static void move_left_linear_timecode_raw_7bits(unsigned char *raw, unsigned char nbytes, unsigned char nbits)
, g/ v* Z$ S' y/ K - {& x: @# R; h1 W8 ^1 l
- unsigned char i;
7 u; g {. h8 l9 w; N, `; O4 E0 ^ - unsigned char tmp;* P. g6 k- B( B7 \0 \/ Q
0 L$ G. v3 p! d+ J; y. M/ e4 ~% m! \- if((nbits < 1) || (nbits > 7)) {& A2 l& D6 u j8 d% @# z P
- return;
/ F. C2 C& p5 W( ]4 T1 t0 u: b - }
' j3 `; Q1 b& l, F
" Z2 S: K- g u) K7 b$ v& G- for(i=0; i<nbytes - 1; i++) {
6 I% U" L) S/ y+ e - //prev_bit = raw</span><span style="font-style: normal;"> & 0x80;
9 j- r0 T7 c* }( |: W& E - tmp = raw[nbytes - i - 2] & l_mask[nbits];! I6 x3 |+ p, C7 i
- raw[nbytes - i -1] <<= nbits;
1 K9 N# e3 d h# M - tmp >>= (8-nbits);- @* |7 c5 S# ^8 e3 D( x
- raw[nbytes - i -1] += tmp;5 P. r' e# ^ V/ s5 T+ g
- }
$ g& o" J# W& i$ c - raw[0] <<= nbits;3 r0 ~* i# L/ l2 ^4 U, U2 R
- }
8 k% Y4 v C; M
! V! p" }- g$ {& W/ c* S$ {8 Q- static void move_right_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)
3 @% i8 D( E3 x - {
% {1 R! i: ]. z7 k+ m - unsigned char x, y;: ?5 m/ _! H+ `( o4 t1 ^7 }
- 4 f* ~) ]9 B1 `
- x = nbits / 8;
) h3 A+ B. I8 j) J. `, B - y = nbits % 8;$ c* ~+ T1 q5 k; Y) [
- 7 I- v" @" ~- C# C3 c1 P6 p
- if(x > 0) {5 }4 W% m8 {4 f8 L8 c
- for (int i = 0; i < nbytes ; i++) {
5 w% k( ~% N' @# Y! T1 I - raw</span><span style="font-style: normal;"> = raw[x+i];- t2 Q: ?) z, _! k: ~
- }
% R2 t) v+ x: H, M+ a7 _; m* X - }
7 P4 C; b, {4 n# _ - move_right_linear_timecode_raw_7bits(raw, nbytes, y);/ Y% ^; Y* x# K0 M9 K" F5 K
- }
! ~2 }$ B" k8 ]8 U. P - 6 M9 g' B" w8 X
8 P: G y& l* ^8 H) s- static void move_left_linear_timecode_raw_nbits(unsigned char *raw, unsigned char nbytes, unsigned short nbits)
1 R$ U. [) s/ u - {
! T7 m3 V$ t$ W/ S6 l - unsigned char x, y;
& r- [3 c$ B c2 T" q - / Y2 z# m* z8 \% |3 G
- x = nbits / 8;
, p' C! f0 l. f1 t: v - y = nbits % 8;3 ?+ J; {+ e, |2 U0 V) f5 x
- 8 w6 t+ `5 ~* z4 p. E$ _' p1 U
- if(x > 0) {' P+ g; v( U% d( A
- for (int i = 0; i < nbytes ; i++) {
* O- D. l! f% I. [0 J - raw[nbytes-i-1] = raw[nbytes-i-1-x];
4 R" D7 O6 b3 o. P& a - }2 d! O& c6 c G: W
- }
; e- B- a& l, c N) M, c/ U - move_left_linear_timecode_raw_7bits(raw, nbytes, y);: ? _/ G9 t5 u: `. ~; O, S4 F) `
- } t _7 S, ^( U; _
6 g, u W4 k# K# w" v/ {$ G- unsigned char get_bit_linear_timecode_raw(unsigned char index)
7 g$ [" I! p" \ x; C: C6 {0 {9 x - {4 H, V5 e% V! m( o
- unsigned char x = index/8;' K2 R9 ?; S/ F4 ^
- unsigned char y = index%8;! l( F9 Z0 E! x. k7 T7 A& K
- 7 ]( A' D" @0 i0 ?6 L* ~
- if(linear_timecode_raw[x] & (1 <<y))
6 b6 H/ u! I- c - return 1;
# G( p* |, h0 ~% W& a: o& r# a - else
) T D0 k4 [3 ]6 e, h) t - return 0;+ t' g/ \; h# f9 e$ g
- }7 D6 Q0 K3 T) E( W' `- ]! o
- 9 b; k2 L$ ?8 l' s
- static void parse_differential_manchester_code(unsigned char *src, unsigned char *dst, unsigned char dst_size)/ |8 d* {8 A' |- x& S
- {
% D) F, c' u) z4 h, |) v - unsigned char i, j;
2 P3 ?9 o* A f1 l - unsigned short tmp, tmp2;
7 b1 }; V4 g) p; U' t% D4 e
/ P& ]* @. T" ~# V, S* |* J- for(i=0; i<dst_size; i++) {7 _% i+ S2 Z+ W) t; x g
- 9 Z1 L+ U& t7 `' J; B: ?# A' s* h
- tmp = (src[i*2 +1] << 8) + src[i*2];
! }8 {4 m6 Y( C9 Z: `9 ~" T' u - dst</span><span style="font-style: normal;"> = 0;
/ p" {9 i8 h; r$ J8 K1 o - for(j=0; j<8; j++) {' m% m6 {0 V6 n9 n, t
- tmp2 = tmp & (3 << j*2);
4 `- S" s: r; S1 d { - tmp2 >>= j*2;
( G% W6 E1 C" ?5 l# G) ~ - if((0 != tmp2) && (3 != tmp2)) {5 x9 r1 a9 a( s- y7 d
- dst</span><span style="font-style: normal;"> |= (1<<j);
4 x- }6 x& @8 l - }
. R9 h9 k6 q! }+ o6 U9 Z/ M4 P4 B - } r9 ~" a0 a2 n1 U+ s1 X
- }
/ g2 p; R4 W& z5 {( e( | - }
5 s: b& |- t$ y- {! c( @ - ; D# Z z: j8 m, g+ P' N
- static char find_sync_code(unsigned char *src, unsigned char len, unsigned char *dst, unsigned char *valid_len)
+ p5 U5 P( M/ K9 ]& n4 C& G1 j8 \; z - {
3 w1 L2 i7 J; @* _; k' r - const unsigned short sync_code = 0xFCBF;! z# r7 \# j2 G) u3 l
- unsigned char i;) Q3 J. J( C t' b9 m7 W2 t: j
- unsigned short tmp;- |; `9 ]& T" a" J) A
- char ret=-1;9 n/ o& r/ ]: l
5 U8 x3 F2 j' s6 W4 k2 _- for (i=0; i<len-8; i++) {0 L5 D& k! s- S/ s, I* X
- tmp = (src[i+8] << 8) + src[i+9];
/ I2 _" P8 [5 }! \" f - if (tmp == sync_code) { Y1 A, H/ i+ a& P( ~# x1 s
- ret =0;
3 |2 G- a W$ J" _4 m( [ - *valid_len = len - i;3 g6 i: p0 p% z& E$ A3 @6 _
- memcpy(dst, &src</span><span style="font-style: normal;">, 10); //10Bytes equals 80bits
4 C; c4 A% ]0 W0 u: n - break;
9 \, X) @7 R" c9 m- F - }
d4 Y8 n5 [* R* _7 T - }
2 c7 \8 u( f' R, U6 c
! L3 K; w8 p+ r* g- return ret;2 i% p5 r7 N$ v
: d/ H2 {$ `+ o: i- }
; U, Q9 s+ J% ?2 o8 B5 E
8 |3 C Q/ b* h$ H- unsigned char ltc_dst_code[40][10]= {0};: l3 z) V' G- H8 z+ ?
- unsigned char ltc_dst_code_count = 0;
y! ?+ n& r4 ~5 @ - unsigned char ltc_code_valid_len=0;6 J0 B2 _. C+ I- O8 L! I
- unsigned char ltc_code[20] = {0};. O3 U$ H7 w* l
- unsigned char raw_ready[60] = {0};2 k( N+ ^8 f4 u/ i, b7 m3 M
- unsigned short offset_bits = 0;
. R2 S' ]2 Y5 ?( g& d# M" Q - unsigned short ltc_remain_bits = 0;
9 n, F c8 z' [! P0 A, v7 W- x - unsigned char sec_ltc_code[20] = {0};( j. S( g: q1 S
- unsigned char ltc_dst_code_cur[10]= {0};
4 H, y' }" Y. B# B, a: s - unsigned char new_frame =0;
2 y6 `, ]$ D4 r* l7 f5 `, F9 D
+ i& f: r) J& t$ o k% e- 5 K |+ P5 S0 j* D% L- K
- void parse_linear_timecode_raw()
6 J' U9 T0 b! q - {
$ ~" e& H: f2 x' [" T - unsigned char tmp;2 l! x- [( J' J0 v% F3 B
- unsigned char raw_mv_right_bits = 0;) S& v; b; o* L( p* j
- 0 H2 I: o9 g* _
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
t# C8 n6 E* I" K& ^0 `5 Z- E - isjam = 0;
3 E/ I, b* ~2 s - memcpy(raw_ready, linear_timecode_raw_ready, sizeof(linear_timecode_raw_ready));
! n% V7 w0 W# r - tmp = raw_ready[0] & 0x03;, B. n. T! _2 c0 Y1 F
- while((0 != tmp) && (3 != tmp)) {
) v6 Q3 V" D. l2 x( B4 l/ L: R2 | - move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);
; B( [8 X) X- e# _4 C p. W/ a - raw_mv_right_bits ++;% M8 @+ f9 t T9 s* `2 k( o
- tmp = raw_ready[0] & 0x03;8 g4 ]/ z# Y& r7 V U
- }1 N% `6 T* a- L; \: i7 P# _
- 7 G4 Y& d! q- M
- for (int i = 0; i < sizeof(linear_timecode_raw_ready)*8; ++i) {$ r' o% @! O& P" i
- memset(ltc_code, 0 , sizeof(ltc_code));! a( b& y" |- w9 H$ g& c
- parse_differential_manchester_code(raw_ready, ltc_code, sizeof(ltc_code));
; z2 }% ?. u; W - //0xFCBF;- X# i% ~8 z7 m3 a
- if((ltc_code[8] == 0xFC)&&(ltc_code[9]==0xBF)) {6 \% _5 o |8 M7 k. M$ D, x
- linear_timecode_status = !LTC_STATUS_NEED_FIND_SYNC;
6 Q. j/ W1 I' k9 J, s - offset_bits = raw_mv_right_bits;
9 u1 A8 k, \1 I/ ^2 i - break;8 x3 d, t* r7 j
- }% m$ M& E! c$ v" ]8 O1 v5 C3 S
- move_right_linear_timecode_raw_nbits(raw_ready, sizeof(raw_ready), 1);, c [# I. u$ c9 \0 e
- raw_mv_right_bits ++;: X. ]' g- O2 u
- }( A! N* M* p9 z
- 2 W {9 X; w; ~) [" i
- if(linear_timecode_status == LTC_STATUS_NEED_FIND_SYNC) {
$ M9 R$ d, |' W+ H- S - LtcInput.tim_count = 0; //reflesh tim2 period
2 p3 O) i/ v# o* A T - }4 r' G/ k$ V% r9 ~0 o# O
2 E% Y0 C2 t- w3 n, g" u" C: b8 y- } else {' t/ y# v e; A% r9 j
- isjam = 1;
+ t& J! F) I; a( H+ ~& A- R - memcpy(ltc_code, linear_timecode_raw_ready, sizeof(ltc_code));4 g; H3 E" o4 Y
- parse_differential_manchester_code(ltc_code, ltc_dst_code_cur, sizeof(ltc_dst_code_cur));
. ~% o; d) \1 ^" y - if((ltc_dst_code_cur[8] != 0xFC)||(ltc_dst_code_cur[9]!=0xBF)) {
; \% o: N* o0 F3 M, h" W9 P - linear_timecode_status = LTC_STATUS_NEED_FIND_SYNC;
, a7 c; r, p* E( U# h - LtcInput.tim_count = 0; //reflesh tim2 period8 C8 v8 _. G, i K+ p. e
- } else {
Y5 c5 h+ u, ]0 x* H; A - new_frame =1;% ]7 ]) G+ H" w5 \& F' p3 Z; ~
- }* ?' z/ [: `. D
- }
0 r1 R/ v6 }7 A, ^" Y$ t+ F6 w - }$ o8 B/ A( P+ ~" N
- </span></span>
复制代码 8 W8 E! ?2 E, H( U, g0 g
+ v& s, K/ m" G0 D: h2 F
总结以及调试过程中发现的问题。
! L4 z% }% @6 e- l; T; `4 v* T
' R5 E$ K* @1 B b# j0 F+ b1. 测量周期,比较顺利, 56MHz , 测量出脉冲周期202 us; C* L `' u# M) P
0 @4 _ u, X# _; E, s6 a
6 Z. _! n, }: y' i/ ^) C
- o6 _5 E2 b; N, q; B3 w( p6 R$ I$ k2. 采样过程中,发现定时器中断,在修正过程中, 出现中断异常,增加调试口翻转看波形
. y$ x7 k! S+ J8 H( Z: }9 L( w. |' C. r& b I! i% a" U y
异常1, 中断回调,里面调用HAL_TIM_xxx , 导致反复进入定时器中断,
) V' t: @+ Q8 g/ j c- v/ [. v4 G: |2 V& q- b; [1 l
5 A5 ]2 }% C$ A# V# v7 H; [. M
* d, u7 P6 k: |/ ?6 d异常2, 定时器停止-> 修改周期 -> 定时器启动,每次启动都会中断一下,启动前清中断标志也不行
5 ~/ j8 v S. s! C! C. S& [; Q3 O% N# Y* f0 v
8 i* D* A' d& T- I) B8 J
3 |' }& q0 ~+ H5 p T* z解决办法,通修改 TIM中断处理程序,直接修改寄存器。 中间不停止,最终得到正确的波形) r5 F. b3 z2 K5 |; t8 ~
- void TIM3_IRQHandler(void): y( ^/ l2 U8 w U
- {- A% ]4 d8 l: ]# C* h1 b
- /* USER CODE BEGIN TIM3_IRQn 0 */
+ h8 ^8 T: D# h# O$ V0 V4 P+ j
& E9 i+ B7 h* {/ b* C1 Z- /* USER CODE END TIM3_IRQn 0 */
8 \7 v2 E# X2 t/ q - HAL_GPIO_TogglePin(TEST1_GPIO_Port, TEST1_Pin);
/ d/ M, i: g7 q5 J! R; q) K - htim3.Instance->SR = 0;
2 M& |. ?5 T+ l+ l - htim3.Instance->ARR = LtcInput.period;
, Z! S+ Z, K( @ m) [ - htim3.Instance->CNT = 0;
8 p) F0 J B% Y' U& B1 E - ltc_input_timer_callback();
2 j4 _ ?6 z& r7 T7 a - * V* H; V3 ?5 T8 K" @
- /* USER CODE END TIM3_IRQn 1 */7 X# k+ S* B3 v& [" M" q
- }
复制代码 $ P: o% T. o" r( {. Z; J
9 w8 i* S3 ]1 V. r
- i3 G. J8 H& x( q
4 F% q. u+ S$ q7 E5 _7 R+ [ |