普通IO口模拟串口通信- 串口通信协议
-
+ ~( t6 O7 T/ ?' X/ r! o
 - //IO模拟串口初始化 1 void IRrec_Init(){
; l* H [% H8 x" b - 2 + n; x# q$ G/ ^5 @9 I
- 3
7 L2 u( j0 e- y$ a0 O$ Y - 4 EXTI_InitTypeDef EXTI_InitStructure;6 D9 q9 f- S8 O. Y% Z4 A
- 5 NVIC_InitTypeDef NVIC_InitStructure;: s( R8 ~! J2 ~, M) x
- 6 GPIO_InitTypeDef GPIO_InitStructure;; N6 r# ?" Y- ?: R# n6 P8 s
- 7
( d. X* A/ n& |' r6 q2 C( ~ - 8 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //使能GPIOC时钟: P6 K Y0 o4 _, T* E% [
- 9
% j2 `" O+ v [" w5 w% R/ c& q - 10 % Z4 [, O4 H; O7 y
- 11 //IR TX C9 使能3 K' ]. K {1 t7 d" n
- 12 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
; Q, T- T) z l2 ]: z - 13 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; : |3 a [- Z, D0 q
- 14 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+ R9 L" I* p$ ]9 e( ?% t - 15 GPIO_Init(GPIOC, &GPIO_InitStructure);
% C7 V: c) F% r6 U8 ?; l; c J/ d* a" E - 16 GPIO_SetBits(GPIOC, GPIO_Pin_9);// 引脚拉高
# K% y' _* k3 x, C9 o+ q8 p - 17
: t" ?6 Z1 C8 j" {. X - 18 " ^% T! \0 F+ c5 F2 U I
- 19 //IR RX C80 G/ a" j A+ R
- 20 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
9 B% a7 P0 H1 J- w E - 21 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;. C; G! E5 k' \, z8 E/ I; |
- 22 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;0 Z" z) v" ^# v. ^) Q
- 23 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;. T; @/ ?! L$ V/ D- z5 }+ Y6 u* S- x
- 24 GPIO_Init(GPIOC, &GPIO_InitStructure);$ r+ k# Y& R# _
- 25 GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource8);
. k! @0 C. B. i, J! ]$ I, J - 26 " x- ^: C @1 N
- 27 EXTI_InitStructure.EXTI_Line=EXTI_Line8;
' u* {: A) }0 t. c$ Q: N - 28 EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
}3 M, [9 Q9 w- h8 q4 z0 e9 ~ ^ - 29 EXTI_InitStructure.EXTI_Trigger=
% e+ }$ a/ q( B) L - 30 EXTI_Trigger_Rising_Falling;6 `* L/ w+ ?! [1 I! [" B
- 31 EXTI_InitStructure.EXTI_LineCmd=ENABLE;2 N8 e7 Z* D4 J1 b- S) B% V
- 32 EXTI_Init(&EXTI_InitStructure);
9 Z1 I3 ?" l, Y- s! ^3 h u8 @ - 33 ) H+ K6 H) r7 H0 n1 e! g
- 34 NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;
* x, E" S1 h' L( u! X9 ~, m - 35 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
, e! \6 @, |: W- j - 36 NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
5 h* H- I8 w5 O& ?& f, {" m$ _: l - 37 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
: G: b0 b3 m1 ^! j3 V! i5 m% h0 n - 38 NVIC_Init(&NVIC_InitStructure);9 v5 q, \/ y' R( R. C- c
- 39 * N' Z$ L# H/ E9 \7 c# R, _
- 40 }
复制代码- void IR_SendByte(u8 val)//发送bit位( w4 U! T: a Y
- {. q( r* @7 u9 y
- u16 i;3 h6 S7 j8 O J9 k2 M
- ( t( \( U$ D" u2 O
- IRSEND=0;//拉低 开始传输5 e& P. b$ h* J- ]
- SysTick_Delay_Us(53);//波特率根据延时在设置 19200波特率
. t9 D- x( y3 v. B1 u5 s0 H
6 b% E* K! K& ?* T- for(i=0;i<8;i++)/ r' T/ {8 W% L
- {
" c$ c9 p+ @" p6 A5 ^ - if(val&0x1)
' u) b5 A ?! D% I - {
# e: @$ A) x3 a( P - IRSEND=1;6 S2 p) p f' C# q) X7 u5 S
- }
! f$ Q$ s1 h9 Q1 v, d - else0 @# t" t3 Q N% z2 z
- {: d8 l, x- Q# V% q$ a
- IRSEND=0;
8 k1 j+ k9 P$ J - }% ]0 y% M: a/ A$ O: V1 w; F% ^
- 7 @1 b3 j" S( I! A$ e
- val>>=1;
; R# r; n1 M( g+ e - SysTick_Delay_Us(53);" o5 N- O& v- r8 G0 W% `2 L$ \
- }
5 u8 `& @4 ^5 w! Z* ~, c F - / B: _& E; {0 M1 `- n# j2 L- K6 K
- IRSEND=1;0 o' w0 Z/ f4 g6 s Q) J, D
- SysTick_Delay_Us(53);
2 z, o# V7 f( N1 {$ Q - }
+ u$ G/ n- k' }: @& C$ ~/ x
! @# l/ ^, P& V- : f2 z9 W! h+ y9 |7 V
- void IR_SendStr(u8*st,u16 len){//在这填入16位数据即可' y4 _# Z9 d+ R5 E
- int i=0;
, ^4 m9 |/ ]- D - while ((len--)!=0)
: C# r" Z, P7 q! r7 J - {
\7 g1 f) X& \9 X7 `7 v - IR_SendByte(st[i]);, ~ B/ p- a: f4 K# s
- i++;0 Y$ M: m7 J* e, U/ ]0 l9 a
- }
0 v9 H' c; D- B& `
' @7 Z, y& x% @/ E- }
复制代码- u8 IRREC_RX_BUF[64]={0}; //接收缓冲,最大64个字节.. k: h4 U$ o% F, H5 g: w E
- //接收到的数据长度
5 |2 c8 Y; o$ k# I+ ^ - u8 IRREC_RX_CNT=0;" V. e d0 X$ \# v% o5 ]- A
! q- C7 X, N+ h: G/ ~( j; Y- char rebit=stopbit;//记录接收一个字节的二进制位所处何种位置
, \3 R6 d$ e1 G - u8 Recev[8]={0};//记录接收的一个字节的二进制流% V! F$ S5 w8 B8 [
R4 Z2 ~0 W; {- static volatile unsigned long long m_rx_previous_time = 0;//上一次进入中断时间3 G: x$ G1 |% j% z% |. G8 g( E8 a
- static volatile unsigned char m_rx_begin_f = 0;//开始一个字节的接收标志 0-无数据开始接收 1-有数据开始接收
/ H" d) Y4 ^4 \# k/ o - void EXTI9_5_IRQHandler(void){: }4 _) \8 l9 N. X2 B
3 E; Z$ j) O9 r; B* D- if(EXTI_GetITStatus(EXTI_Line8)!=RESET)1 L8 u- W. h: q- x3 n& I
- {& D3 D; c8 X, L! y
- unsigned char skip_index = 0;, K( { _* P- P x/ X1 W
- unsigned char i = 0;
7 W C+ P% g: A/ g$ _ - unsigned char temp_bin = 0;//用于记录二进制值2 S d# q# U4 s+ l: i8 Y
- unsigned long long current_time = sys_micros();//记下此刻时间, p6 b1 E7 V7 Z* z
- unsigned short interval_time = current_time - m_rx_previous_time;//计算一个状态持续的时长
) |5 e, l9 }+ Q" H" a - m_rx_previous_time = current_time;//为下次计算时长做准备# g/ R8 b ~( J5 E2 _; w) `0 o
7 w$ ^- r9 o' K, w% U- //当前未开始一个字节的接收且此时为下降沿
( F( K8 v7 ~" h- r - if(rebit == 10)//10 当数据不合法时或者结束传输时 rebit值设为104 r( o: ^. L5 N
- {0 l( e( ]! m Z S. X% |! M {0 K
- if(!PCin(8))//下降沿6 A- n6 `4 y# M) r# z% u% @
- {) D& j$ {; B1 R* K" U' K3 C
- rebit = 0;//记下开始接收9 |1 k6 `& ~, n% J9 `( l8 b
- m_rx_begin_f = 1;8 V! O- m- T( t1 q
- debug_led(1,LED_TOGGLE);! r2 Y# t7 d' Q- ^$ g, v% E
- }% i8 D$ W7 P ^4 x5 \
- }
& Z# F9 \* J- K6 A; ~2 B" N J - //已经开始接收! ^$ h* w5 I$ G$ l r
- else# ~# a8 ]% x u
- {/ ?$ _/ Q' i! |( U4 ^
- //上一状态为起始位
$ E0 C) R6 j, A6 u- B9 _ - if(!rebit)//起始位0- B+ m# P* ^, I% V" S5 s3 ~
- {# E" @8 l4 N3 D5 a
- //计算二进制数据的个数
- r( J( j2 H1 k3 m; H$ B6 } - skip_index = (interval_time/50)-1;1 B4 s- ]+ p+ \ ^5 N
- ! G% K H' Y/ p% m# F; X
- //个数合法4 \& A& t; T& S- j0 v, Q% d
- if(skip_index <= 9)# [6 Y" x0 U* k- l
- {/ a5 Z! H$ J1 A3 i
- //根据状态保持时间更新接收值0 x' P9 ^/ l! r. y$ F! x
- for(i = 0;i < skip_index;i++)
% ]0 ~! @& w: F: o1 C' B6 l - {
# L' ?+ _; s8 }6 V# ^$ [ - Recev[i] = 0;( _% W0 K& K, n% f
/ n; |3 ^- ~: g/ a) d- }, T& h; C& W6 K: O
/ X* d7 I2 a0 u& |# `- //更新接收二进制位的下标- i% l' R, B s+ ~* }# m5 v
- rebit = skip_index;( j( R# H$ e5 s
- & ]; _2 ~9 _7 R# d
- } a8 m+ T1 {! J, C0 }/ v
- //不合法-重新接收
" [) T3 W3 d! P0 X) T( o1 } - else/ P! ~1 k" i* A3 H$ {4 e( c: p
- {+ P7 ]) W0 |, F, N: Z" y
- rebit = 10;
& x7 T+ J/ C) n8 L6 E% J7 @* S - m_rx_begin_f = 0;. v9 U! P2 [" u" {; W( C: f. t
8 C/ d9 P( \- s8 g# Y0 t3 d
/ ~' o; I+ O+ G- }
. p' f2 q3 H C% ?$ U4 ~# ] - }% [, S* W p8 G8 h
- //上一状态为数据位8 O3 f0 T6 ?/ r/ T E
- else- m g9 g- x4 ^( o+ d- V' Z
- {
1 k5 i8 r4 z. p - //计算二进制数据的个数3 K9 b/ D3 Q, b8 g1 c3 l* j$ C) r; K
- skip_index = interval_time/50;/ h2 `4 y9 W& }9 P% t
2 v2 c0 z/ F; i8 X) m S; u0 b- //数据不合法-重新接收
+ \# d7 Z* A/ t+ i# | - if((skip_index+rebit) > 9)//所处位置+数据个数 判断数据是否超10 合法判断3 Y7 U& m. C. V8 [0 s9 F8 F
- {5 ~$ [6 e% c$ J! `$ ? }- p- M/ r
- //printf("skip_index %d rebit=%d \r\n",skip_index,rebit);
# k4 E1 T. v9 }, q - rebit = 10;
! p, [. U7 _% e - m_rx_begin_f = 0;: ?8 V8 d& R5 [1 Y
- debug_led(3,LED_TOGGLE);: z3 V3 ?5 a ?5 V) ~
- }, \% C. b- p \! l% _# s
- //数据合法
; \- X$ G5 k- F, Z8 \$ J - else
' ]8 O6 Y3 C' E' Q; W - {
2 k: @( D; P7 p$ }! K - //当前为高电平3 g4 O s; X( Y1 c9 A
- if(PCin(8))% Y& H& G9 b, {; `
- {
. l+ f+ P9 |" J0 d - temp_bin = 1;//0
$ r* y! d, `* |1 \% G, E; ] - }
0 _ _# C1 m% K* N - else
6 @% O5 B5 @1 v2 R d# z" w - {5 c! X2 P8 o5 i0 g- F3 y2 ?
- temp_bin = 0;//1 change
; {! n3 K* D) d/ m - }
4 _% n8 f: C {8 i - debug_led(2,LED_TOGGLE);$ L6 E( p% k1 w7 W7 X- o. n
- for(i = 0;i < skip_index ;i++)//根据几个数据 给予相应的位' `* ?9 k/ O" Y. Z7 i; d1 U
- {/ f5 q d; \, A5 {" y$ z
- Recev[rebit+i+1] = temp_bin;//change +1
- s3 N3 H% A9 ]. H) L% I% @ - rebit++;
) I: f6 J/ [, N
; G. I) ?' G3 N% Y* ^ h- }) f% H9 c0 ?" c3 z/ f
- }
n6 C$ j( q2 d1 o7 F" @' n: r, H
+ R, B2 [( A! q- //数据已接收至结束位
" d( Q, ~& m. p" T; O1 W - if(rebit >= 8 )//=8>?
6 r& z/ ?3 M9 J# I# b5 f - {
2 A/ z6 r6 Q. o5 b& j. O3 Q - if(IRREC_RX_CNT < 64)
/ r1 g0 U+ p7 ?! v - {
d* A8 [) U& J - IRREC_RX_BUF[IRREC_RX_CNT++] = (Recev[7] << 7) |(Recev[6] << 6)| (Recev[5] << 5)| (Recev[4] << 4)| (Recev[3] << 3) |(Recev[2] << 2) |(Recev[1] << 1) |Recev[0];
; t5 v$ w& C+ z3 B7 l0 d8 ]" g
& T+ y2 o) \8 f9 E. v( f- }- A) Y8 r" G! X& x
- rebit = 10;. M) `, s( d8 }2 K- g
- m_rx_begin_f = 0;0 T! }/ o1 T9 E3 n& b4 I/ y- _
- 3 {2 ~/ v( v) d2 U1 X3 p8 I" E
- # a9 v( f7 w. x# \
- }, F, ^, j) `* N1 a- [9 @; u
- ; I* c+ N+ s* Y' v
- }7 X: K. m' [6 ? I# u& A
- } t7 A9 Y! V* c6 E
- 7 ^1 E- {4 U- W) M: E$ j
- 2 f4 b; N1 i6 @* z' c: C8 A# z9 X' @
- #endif9 R4 f! g* w/ G/ V: F# o" D2 i5 v
- EXTI_ClearITPendingBit(EXTI_Line8);//清除中断挂起标志位! b! R' l) o; a) h' T) C
# x4 G* n3 K }* Z! }% R* D u- }0 c: ^$ C, U/ V8 z+ A8 K @
% v% n. T! s0 I% l4 d/ d- }
复制代码
/ |) V' H9 d5 @1 e- O6 i% q |