普通IO口模拟串口通信- 串口通信协议
-
5 ^8 _# a9 t2 R
 - //IO模拟串口初始化 1 void IRrec_Init(){
, g, X# }/ n/ [! Z6 h! |) `1 C - 2 " L$ H7 H% a2 o- Q6 g$ d
- 3 " @ ]/ l( }( \& o7 S
- 4 EXTI_InitTypeDef EXTI_InitStructure;
" @0 \9 x3 I8 f' X% v( u" n - 5 NVIC_InitTypeDef NVIC_InitStructure;
1 h) r$ w( \: R/ U- v" V - 6 GPIO_InitTypeDef GPIO_InitStructure;+ I0 m2 I4 g1 `
- 7 & V/ m) Z* y$ ?/ U$ l3 r2 f( D
- 8 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //使能GPIOC时钟
; _# K, e+ T. a. k/ f( a - 9 # }; s+ L4 g5 {1 j" ?3 l& z c
- 10
) @6 d1 x; k; m - 11 //IR TX C9 使能
& _' z# X# S- z - 12 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;' Y. n2 A' {' T- v) n- N A2 S' ^
- 13 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- j: S/ J, v, a- e, S - 14 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 9 s5 B8 B: \9 U
- 15 GPIO_Init(GPIOC, &GPIO_InitStructure);. G" Q7 f( o' y# y r. @
- 16 GPIO_SetBits(GPIOC, GPIO_Pin_9);// 引脚拉高& p# N$ R6 W) C: H y
- 17
' m1 ]- s! \. P0 ]" ^* l - 18 . ]; K' e2 R+ C6 }4 |* D
- 19 //IR RX C8
' K2 C. h/ `1 M& F& h6 @ - 20 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
- n! P8 E# p$ [ - 21 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
& T$ h5 y; y; w. } - 22 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
2 N1 P" C) @1 d$ ~. @: x4 |" l - 23 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;1 k ~4 H9 ~1 S
- 24 GPIO_Init(GPIOC, &GPIO_InitStructure);' p; Z6 |4 i' Q9 K+ Q
- 25 GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource8);
4 g* d2 D$ n7 J9 D4 _. O. o - 26
- Z. q/ j1 N6 V p- W: `* k, r - 27 EXTI_InitStructure.EXTI_Line=EXTI_Line8;, s$ A/ L1 Y! _! O0 s8 r# L
- 28 EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
, s9 Y# G1 f1 g8 E/ A - 29 EXTI_InitStructure.EXTI_Trigger= 5 m# X7 J' p# r8 |4 C! \
- 30 EXTI_Trigger_Rising_Falling;* {- h1 T8 f% T. U! T( U
- 31 EXTI_InitStructure.EXTI_LineCmd=ENABLE;7 _$ s! [6 b& t7 W
- 32 EXTI_Init(&EXTI_InitStructure);1 [2 A8 Q! |' {4 O4 h! G( m
- 33 0 f: c2 i3 X* Z( t3 f, p' O' |% x
- 34 NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;
7 k. _' a- p+ T3 G) B) V/ V! K- T8 D - 35 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;9 Q7 r2 {; V2 }. J( ]5 S1 b
- 36 NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;, y5 y% L& n1 v9 { \7 F
- 37 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
% m9 a6 H: g d% L: X! p/ U - 38 NVIC_Init(&NVIC_InitStructure);- G9 ]* K# T0 b2 p
- 39 g# M1 j6 O' A/ \
- 40 }
复制代码- void IR_SendByte(u8 val)//发送bit位
- {; O5 S1 {1 Y7 k - {* q$ Y* A: ^" f- `4 u- f9 ?
- u16 i;
4 q, ]6 o& D& ^1 i+ L7 [. H
1 ~7 ~9 ^- q0 c [7 f- IRSEND=0;//拉低 开始传输6 B* J' z0 x7 U4 [
- SysTick_Delay_Us(53);//波特率根据延时在设置 19200波特率7 Y, g& J+ q3 _
% R1 y5 [! ~+ ~6 s) v) E( Q- for(i=0;i<8;i++)
" m# A/ ~! L0 k [) }& w J - {
0 |' c/ R! a3 {9 Q - if(val&0x1): K$ } @- G; g! u* U4 y6 f, ^
- {
! F/ N7 g0 [: W - IRSEND=1;, k& K U# K( F' h4 J6 S7 i; i
- }
! V) u, g( m6 i% V" L7 ]; D - else
; [8 J( I% ?# [* v5 Q8 c- r - {8 x5 R+ |8 @" u+ Z& G( E
- IRSEND=0;# r- j) v7 M, W3 E( l
- }
% P1 M- H* Q4 L& o. ?
* p1 g5 L, f- r6 f- val>>=1;
' g. K, t- A" v3 ^( x' Y - SysTick_Delay_Us(53);, r5 p* g0 f F5 x1 e; k _
- }
# j" a( a$ `2 d4 E
/ S4 |# K; X0 W4 z3 K/ X- IRSEND=1;
* e2 C9 i$ ^5 F+ ^; N3 I, o - SysTick_Delay_Us(53);
& n3 W5 N2 x# o+ d9 O - }+ S! S% t g6 f1 b3 f2 G
- : ^6 I% B4 D$ f' {/ l2 P% E" k4 _2 {
3 ^9 [2 J! y+ Z- void IR_SendStr(u8*st,u16 len){//在这填入16位数据即可5 t% P6 q4 K' w* D, e6 `
- int i=0;' X( K. ?7 o" ?! K
- while ((len--)!=0)6 r1 ~& c9 X- B7 K
- {
# Q" h) L$ U; g& V( \4 ^! _" Q - IR_SendByte(st[i]);% `, _- a4 N) P k8 ^$ r1 f$ d
- i++;6 H6 _$ i& }( ~7 v5 y+ B8 M
- }2 W; `4 O. a' [8 _% n- }
- . b7 O5 N5 ]" c( b+ e* M# y' c
- }
复制代码- u8 IRREC_RX_BUF[64]={0}; //接收缓冲,最大64个字节.; t2 r6 `+ h U- ^9 i
- //接收到的数据长度; I, l ~- i( N4 I6 d. V+ P
- u8 IRREC_RX_CNT=0;9 G1 S7 b9 `' L+ c$ Q4 u
- 3 i+ N2 Z( n" [2 y$ W i
- char rebit=stopbit;//记录接收一个字节的二进制位所处何种位置
1 k& G5 b( _0 r& e9 T- b - u8 Recev[8]={0};//记录接收的一个字节的二进制流3 i- D. j* b+ }0 ^5 S; J
- 6 J$ k& o) U2 ^7 M# z" J
- static volatile unsigned long long m_rx_previous_time = 0;//上一次进入中断时间
5 I' g1 K8 `2 U( Y" c& u - static volatile unsigned char m_rx_begin_f = 0;//开始一个字节的接收标志 0-无数据开始接收 1-有数据开始接收# |& H4 A. p* D5 B" K7 I
- void EXTI9_5_IRQHandler(void){" |5 r/ g/ }+ G% Z
- : W4 x3 ^& h" I4 x8 p, I
- if(EXTI_GetITStatus(EXTI_Line8)!=RESET)
! j" v1 ]' u! B- k1 M- q" M - {
- o& s* k; W/ { [( E2 V/ [, Y - unsigned char skip_index = 0;$ D2 Z4 h5 q7 B, r+ s3 l
- unsigned char i = 0;0 W3 h5 e1 ?! b- g
- unsigned char temp_bin = 0;//用于记录二进制值4 o2 I1 ~1 x& i6 l; d
- unsigned long long current_time = sys_micros();//记下此刻时间
, P2 e; k. j0 S8 x7 l+ s/ X - unsigned short interval_time = current_time - m_rx_previous_time;//计算一个状态持续的时长
0 l, B/ b7 S3 ^: e; W - m_rx_previous_time = current_time;//为下次计算时长做准备% p& c1 P4 V7 x! ~ z" J q
- ' X' f. [1 n- a; z ]6 ^
- //当前未开始一个字节的接收且此时为下降沿 \7 f" @* v7 N" I
- if(rebit == 10)//10 当数据不合法时或者结束传输时 rebit值设为10! e7 I) }1 K* M9 p3 C5 Z
- {, c' W! E8 c, @! p# U
- if(!PCin(8))//下降沿, x& Z, f7 n, `# {
- {
# e: \0 m0 k& R. v5 K$ v - rebit = 0;//记下开始接收
1 D% l }+ w# |" @ - m_rx_begin_f = 1;1 G& s" C& r( ^ T/ i
- debug_led(1,LED_TOGGLE);8 {6 k$ g1 f! L3 U
- }
$ [; w* Y$ y7 O6 J* E) F7 \ - }
1 ~, _) Z' r+ S. o - //已经开始接收
1 z, h; }5 p1 L5 T - else" {' K# ~$ @3 m# B/ {6 a
- {+ S) S# u* m6 k# p3 H3 e! w0 |4 p0 \
- //上一状态为起始位# E& m3 g* H' ]( P$ n
- if(!rebit)//起始位0
- V- k* X: v9 R5 n9 B2 r - {7 ^8 y& I& _- h" f' K
- //计算二进制数据的个数
1 b. M9 @- u" d s) A - skip_index = (interval_time/50)-1;
! @! h7 B# O$ V$ p4 C+ q; `5 p+ p
5 A- D; \9 w% w4 P! z5 X+ j- //个数合法5 O# B1 T- W' Y8 V, w! t0 R
- if(skip_index <= 9). [6 |4 }/ s0 E' b- V% d3 n2 ~
- {& s/ r! X3 j7 `8 s+ O3 J
- //根据状态保持时间更新接收值
( b' |" G3 B( w' o" w" s" [! n5 j - for(i = 0;i < skip_index;i++)1 j$ M' w! T' X1 R* @" C# f: ^
- {
) {5 j( H# Q0 R! Z0 p: ?/ i/ I - Recev[i] = 0;
$ a( ~# h- K% l$ n6 t - . M9 `/ ] U/ x* J4 n, K
- }
2 ~8 H# h r5 ]+ Y# n' x
. u: w5 p, `. o) J- //更新接收二进制位的下标/ ~' \6 {" d8 r. _) w. K0 O
- rebit = skip_index;
; q( n8 x/ ]! }: z, W. H
/ o$ d* P5 e- @ S- }
7 G+ O6 \3 [# x6 d) ` - //不合法-重新接收
& L4 Q" |$ `; D$ r# L - else
5 ]+ c2 s, ~; @ J. o* d& d - {1 u0 D) w& g0 `- O9 @- j
- rebit = 10;1 G w; T. j( |8 v: x
- m_rx_begin_f = 0;1 Q, W- k2 o! o2 C, x, V. y! }
- : h( @- X+ K8 S
8 ^' u3 q, \: r- }3 r% M" _! I5 ^/ {/ @* d7 |
- }
/ a! r) a7 Q( o. }- N0 [' V; `. W - //上一状态为数据位
+ j1 e, D$ C/ p - else% {& Q; [! @! K. y5 E D
- {, P+ M; y2 {5 ^4 c" `
- //计算二进制数据的个数
* M7 n% h7 O+ d5 d6 L0 V - skip_index = interval_time/50;; n7 N% U9 {' ]; \! f/ A) j
9 E' q1 O4 I; b$ K6 T* }9 l- //数据不合法-重新接收
3 n* |# K& W% n/ E' F: d2 x - if((skip_index+rebit) > 9)//所处位置+数据个数 判断数据是否超10 合法判断9 r5 F2 B, f7 w- H) R
- {7 n' j3 C# S6 Q1 I
- //printf("skip_index %d rebit=%d \r\n",skip_index,rebit);2 ^: ?# O# Z" Z* x4 e# d
- rebit = 10;" ]6 c1 p$ C, T8 E: r- e
- m_rx_begin_f = 0;' i& u { t! S& l6 s
- debug_led(3,LED_TOGGLE);5 k! f& ]0 w4 {+ | C' P3 q+ o. c# ~
- }
2 G) @1 y; e# p4 T! W' h - //数据合法 g" j+ u) s3 T. u0 b9 z
- else G) u; f* ?7 B7 D
- {) k" P: r( e% ~; F3 W6 D/ H% V6 u5 D
- //当前为高电平
: Q2 N0 `( W3 M4 _ - if(PCin(8))
) a( \8 O0 O: I; y- o - {. q5 d6 ]+ y( ^$ L/ K
- temp_bin = 1;//0
, }; K: A8 C" f - }0 `# B9 U8 b1 g, ^! s) Z
- else: E) i' Q; i: ~) |
- {
" f0 r0 Z3 M' E+ V& y8 p - temp_bin = 0;//1 change
) \9 _( b0 ]% Y - }5 [$ K# w! U) W; J) T7 w3 M
- debug_led(2,LED_TOGGLE);
2 d1 F, r' h! j# a& V! B& {8 O - for(i = 0;i < skip_index ;i++)//根据几个数据 给予相应的位" {2 X- Y- ]7 F
- {
/ q! W: x. A+ g8 J s- J - Recev[rebit+i+1] = temp_bin;//change +1
% N) e2 |/ d% |# @ H - rebit++;! _" n u$ K( F" ~
- * Q) [; d \3 N8 g* _3 a; p
- }0 u0 S7 k$ I* e' T) M
- }0 z# t3 u% d# B P6 f9 R
- : g/ f0 i/ @# K& _ g8 l
- //数据已接收至结束位% O, Q) B- w$ H/ `1 s: w4 l% {! Z
- if(rebit >= 8 )//=8>?
- `! I+ M- s9 }' A - {9 N# h: D; ?6 k8 I! R9 J6 r
- if(IRREC_RX_CNT < 64)
7 v, O) V. h/ |5 { - {6 a5 ^/ Y( r% o/ ^9 k
- 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];4 A* H: d1 D1 u- `" t; \& }6 `. r' U
- . _, ~$ j1 f) }! A6 B
- }! A. y: ^: ]7 U- z2 [
- rebit = 10;6 D8 A* G7 h) X. X5 ]; l& A
- m_rx_begin_f = 0;$ j( X d$ q8 S, X9 S! }
- I% B/ m5 R1 Q, x. S: m$ V" ]4 g
( X1 T& _& y/ u/ v& F- }
( X" ^3 [: n1 \2 H. T" w6 ] - * v" q% A4 r8 r$ } m- M& F
- }4 Z' u9 t( d/ C _+ l- \" U
- }7 }6 |3 U I+ N8 q8 v3 @
0 W# T# C" l$ \7 m+ i4 K( ^; d, D- d) C- ; n p% W/ M6 L7 {/ |3 P
- #endif
1 W1 U8 {2 s8 B& s; a1 E - EXTI_ClearITPendingBit(EXTI_Line8);//清除中断挂起标志位
2 M( V& o6 ?) H% A
- G9 R8 ?8 e( a! Q# U& O5 J; _/ P; f- }
( V/ `1 ~# g6 N* u' A# ] ?1 P - ; U3 v4 b# y# V2 o6 k1 R4 h
- }
复制代码 ; P4 v/ `0 W Q/ w# F; c
|