Side Menu
查看: 39757|回复: 1
收起左侧

[Atmos] 单片机数据通信怎么学?这个工具要用好:串口通信

[复制链接]

2万

积分

4

听众

-1655

音贝

音频应用初级会员

Rank: 6Rank: 6

积分
27131
发表于 2006-6-30 03:51:00 | 显示全部楼层 |阅读模式
单片机数据通信怎么学?这个工具要用好:串口通信" [' b5 \! a; ?) b" ?) U

; E9 p5 v5 j  C# L9 r. b刚开始学单片机的你,是不是会因用程序把LED点亮而感到高兴,会因用程序把数码管点亮而感到高兴。这是好事,这也是想继续学习下去的动力。$ z- J/ P: F5 d% A: `
2 E" A# @4 ~; e  _
( L9 L9 _1 \+ d! e
( u4 @& z7 u1 {' W
但是到了与数据相关的实验时,却感觉很难有所进步。有时候,把驱动写好了,下载到单片机后,一点反应都没有,可是又不知道问题出在哪里,数据通信又不像LED那样可以用万用表测出到底有没有电。
8 |4 K$ [$ `+ d0 h9 U3 Z1 m. {, h( e0 d# n! g# x1 G/ |

4 W  q5 H7 q4 ~. h
5 L3 @- R3 M& |. g( ~: n9 C) D这是学习单片机和STM32的一道坎。又或者说,这是一条河,阻拦着你的去路的河,有一条河你会怎么办?过去的方法很多,但是笔者觉得较快的方法就是借助原有工具渡过去。过去之后你会发现河的那边是一个不一样的世界。
$ S1 Y& u( V/ Q
6 D$ P' {1 g; ^$ d4 Y+ O+ D5 M' j8 l: ^3 S# L9 P) L+ \$ b
8 {) _" b: v' m3 r! G4 G
那这个原有的工具是什么呢?那就是"串口通信"。. N7 I7 V% Q% F

% Q0 U# W% ~/ i% s' t+ b
4 i* p6 q( ?! m7 r- i7 K5 E  W/ f- V+ Q- p# g3 g* B2 |/ R# q
- F' N6 F$ x( p5 i2 ]) G
串口通信介绍
1 ^' c% ^8 Z& ^) I/ Z) U4 Z) ~& G+ k8 x1 L* k
; d/ g/ s  l. j
/ J( Y4 a: y  F+ J, z
' R4 Z7 a8 `$ V
串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式......这种太过理论了,看似懂了,但又不懂。还是用我笔者自己的话来说吧。6 S& i  o# h8 U- A8 r8 d" P# c1 t

! }( y9 z3 ]' ~* t: m% @; o8 |% q; N" C; J% d

5 A2 G6 j) d1 k. H; ~0 H& Z7 K串口通信就是可以把程序在单片机或者STM32芯片中运行的结果发送到电脑的一种通信方式。如何使用串口通讯,你需要知道的几个重要的知识点:# e8 E, m' d3 O7 B* r

5 K! Y- H1 j6 u. M' s5 g8 }$ t1.波特率。(数据传输的速度,两个设备在通信时的速度要设置成一样,否则会出现乱码)。
# g- C* ?- K" u2 a; E4 ^3 Y# ]
5 b- Y  m7 x( W$ i4 n9 g2.硬件连接。串口通信是一种异步通信,一般都是TX->RX,RX->TX。
: P  q+ O- l- Y" Y; b" Q: M3 O. r& S' |8 _% j
3.停止位。( \: g4 D6 M8 O! C# I/ X. d' O* t
+ p0 C- N1 h) }4 L4 y5 L/ _5 K& @
4.奇偶校验。
  l+ c" F# n( H6 S# x; i
7 u; |/ @6 {+ H0 V5.硬件数据流。7 R8 q+ M" ~& L

; \6 F! r: Z8 v" `, f5 [# ~' Y5 O) i2 H/ O
. S- x: c- G* X' a7 D' a& M8 g
3、4、5,这几项一般不需要改变,所以在这就不用多说了。
$ N; c- X. `: _7 e% P% \
! |: a3 y0 `% K, m( ?! w& g% H2 ^) S' \( i4 {# N

% t( l! d  s$ F; }0 ~串口作用: t% U$ a+ N- {6 W% g/ k+ K
& H2 t" U$ U! e( J8 Q  O7 C
$ V7 c' u7 k& L& O- a! c! ~+ Y
; {$ |% Y5 S0 w+ O" [" g/ n
4 k5 b3 `9 B: X
串口能用来做什么事情?
* e$ Y" o. m0 U8 O5 j! Q1 ^( x9 j4 h; F1 u+ b  |, {
3 k- b0 O" ~/ t' H

( a% w8 A; W' p* K学过C语言的人都知道,程序开发需要不断调试不断验证。很多的语言编程软件都有很完整的程序调试功能。使用起来很方便。而我们的开发虽然也是用C语言,但我们的程序最终运行的环境不是在我们的开平台而是在真正的硬件系统中运行。这时想要查看程序的运行过程或者结果就不像编程软件那么方便了。
( U: s% ], Q7 C$ l0 ]: k8 C- T0 U& D/ D# _1 R

4 j7 z: U0 k$ `, b( J* b9 k, c9 T7 F2 J, o% A* E8 |8 `
想要解决这个问题,我们这时就可以借助串口通信来把我们需要知道的结果又或者是程序运行的关键步骤发送到电脑上,我们就知道程序在硬件系统中运行是否出现问题。51单片机可以用串口来调试,STM32可以用串口来调试。高级一点的LINUX开发板也是使用串口来调试。
3 I, l+ G) r/ [
4 `8 X2 T& l- s1 Y0 p3 c0 t, ~
: T/ c8 y0 U/ ]9 D0 [  a! b; P
+ N5 n, ]7 d) k8 f学会串口通信能做什么8 w* I$ Q( ?9 F: O- t6 s; `

1 [; K+ H$ {( q3 I; ]9 C9 U' p& M5 \8 r% h6 G# ^

; S5 V; ?. x! r+ B& t, @0 m9 Q# t, C0 g( {1 z- u( w. v( _+ y
当你学会串口通信时,你可以开始玩WIFI模块、GSM模块、蓝牙模块、GPS模块、以及各种使用串口通信的传感器等等。有能力你还可以编写上位机软件通过串口通信来控制设备。
$ F$ p- I; U( p% L6 a/ V
  b, u) E6 ]# d" a# h: i: p! L6 b2 u- @5 I  T
3 f& f* G8 p1 Z
串口通信需要什么
+ X8 n1 M" e& C2 T3 s0 V* I
- K  C- s% I% _7 d( t  \/ }- m5 Z4 z9 A9 {; E5 u9 E$ L% K

( F1 q  L5 D3 a; n0 [
7 F4 r4 h3 N, K% h% q如果你只有STM32核心板,那么你还需要一个串口转USB模块和一个串口数据接收软件还有几根杜邦线就可以了。如果你的是比较完整的一款开发板的话,一般都已经带有串口转USB模块,这样使用起来就更简单了。聪明的你是不是发现还缺少了点什么,对。没错因为还缺少了最重要的程序。想要使用串口通信当然还需要写串口通信的程序。下面就教你如何去用,而不是写。; j3 @  ^2 b. m; U: `9 T

9 A; t8 M! h( k- ^5 `
8 e4 E: R: v" g8 u
7 Z+ Y& k  i/ P. S5 Q% H4 n# c串口实验
1 s) d2 @- g7 N: d! {+ b0 [" S$ E/ F9 h' S; f, X% s' `
8 n+ E- D9 Y  w) Z& j- G
欢迎厂家入驻,推文!免费!微信:yinpinyingyong

2万

积分

4

听众

-1655

音贝

音频应用初级会员

Rank: 6Rank: 6

积分
27131
 楼主| 发表于 2006-6-30 03:51:00 | 显示全部楼层
- _, ~/ B! J; Y6 N

3 C3 A& P+ W2 o& V7 J# ~在做一个实验时,最好把这个实验分割成几个关键的步骤,这样做的好处就是可以清晰的知道自己需要做什么,以及做完了哪些。还有哪些还没做。下面笔者把串口实验分成几个关键的步骤:
: ~4 W7 X/ r, ^6 g2 e* h1 q8 m# ?7 \. l9 t8 q; T& z* j
1)串口通信使用到的GPIO引脚配置
+ d  {2 [+ s0 [8 {6 ^
& R1 S  N4 V, d/ J2 V& p8 t0 rSTM32F103系列的芯片一般都有三个串口以上,用来调试使用的串口一般都是使用USART1。其他的串口配置都是一样的。
3 ~. n/ t$ H5 v9 g( Q" L
4 F+ Q+ E3 Q: p9 z; }' M7 p9 @9 @. U7 v3 q6 ]4 T3 `

7 s/ I$ z  {% {8 ~8 a; S" G9 a2 j下面这段就是串口配置的程序:" p& v7 c' ]* i8 f% W1 e
6 b0 f2 o5 l0 n/ Z& [! i) {
5 s  x$ E9 H: F2 F' p. ^& H$ v

1 ~) j: w8 a+ u5 @1 Q# x
3 _/ y; Q) D0 o* N3 E6 QGPIO_InitTypeDef GPIO_InitStructure;, Y. q* X; i6 v* `" y* |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能USART1,GPIOA时钟
& q/ R9 X! k) O& H( V1 ]/ e1 O( o) d. G1 y5 D) P
//USART1_TX GPIOA.9: B1 _* T: c: g$ J! c( C. e( W
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.93 g4 X! e2 Z/ J! y; @
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
6 C8 i' j( h5 mGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出# l- u% V7 {, {. Z
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9& X* w$ f# d7 W, |
//USART1_RX GPIOA.10初始化
# f! R% t2 j- Y. ~) W, U" ^( q- `, f  p1 O- d, \
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
5 T; H' e% p8 {& x8 [# w; o
! J# b: v5 ~* }3 |# NGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
% C- X9 H& T/ a9 s; zGPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
+ ^9 o: M; T, L( g. L
5 z* Z6 y1 h& L. n" B0 [: z* R  v- U' H4 K7 s
  f7 Q: T0 y! L' J( }* m
串口使用的的GPIO口是PA9和PA10,所以只需配置这两个IO口的输入输出模式就可以了。" y/ [3 O! L1 \& X
6 E- F( x3 Q/ J& ?6 K  Y

4 N, a9 {1 O' b- r  f) g
$ h3 b% g0 _8 ~  i" I2)串口主要参数设置(直接看程序)
- F: L% p4 e! B- a; i3 E
6 U: ?* e5 }& G
# V" {# p( v- v7 Z7 Z
- b3 n. f8 l% D9 X5 i* y
" M0 k4 F5 e1 L5 d+ `USART_InitTypeDef USART_InitStructure;$ P3 U+ R+ W3 ]3 \- l
//USART 初始化设置; k5 z+ P2 M; N2 q# G; p; c
USART_InitStructure.USART_BaudRate = bound;0 _" Q2 J  [% s
//串口波特率
. @5 D4 u" \* {  D; g" t8 F5 iUSART_InitStructure.USART_WordLength = USART_WordLength_8b;
/ N- ?3 @2 K0 h( W5 r. g% B//数据格式,8位/ S, {7 t* V+ a2 g, b' c+ N5 i
USART_InitStructure.USART_StopBits = USART_StopBits_1;0 m+ f! @2 O. @: d) J& S- S
//一个停止位' m- D9 X+ a1 T  E  M) G
USART_InitStructure.USART_Parity = USART_Parity_No;
* `7 L! Z, ^* M* s! G# W' `( A//无奇偶校验位  `0 h' U% V; q( m  N; c* }; A2 a
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
: X% w; G" T: I/ ^//无硬件数据流控制
0 l" T% I! k! l7 I1 U5 d8 f0 VUSART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
, Y1 e2 \7 B, J- y6 w, @//收发模式7 }; X, ~4 C7 f8 r$ M
USART_Init(USART1, &USART_InitStructure); / T2 w8 Q/ F) S- P) {5 \' y2 ~( B; O" j
//初始化串口1/ ?1 k6 s$ }' E9 O! ]" i0 p
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
% t1 i  X8 Q# t6 C0 ]7 u! ^3 c2 T//开启串口接受中断; t" p  O+ q# J

; Y2 _! u  b+ J: w
1 V; ~3 e$ ~- s: r) h2 D6 w0 X' G! a7 n- H4 x& F
% A8 Z, T* V$ K+ V

" ~0 f  ~4 j9 ]/ u串口参数配置无法就是配置串口的波特率、数据格式、停止位、奇偶校验、硬件流、收发模式。除了波特率需要改变其他的参数都不需要管。直接复制拿来用。* g1 F6 s! P9 F- G" P! r( f9 [
3 j2 @1 x: h  X* e5 p- C, y4 {
3)串口中断配置
; K# v  q9 M, M
# {2 c: `0 w0 b$ x2 j串口如果使用中断接收,那么就需要配置串口的中断参数,配置项无法就是配置那个的中断源和中断的优先级。. c" n' e8 V4 {# U

% |1 o, J3 u1 O: x& ~( F
, n) @5 t: N& ^3 a4 O7 ]: R" m4 _' X( V

8 Q! E$ F  Y. e: S, X. {1 Q2 `7 eNVIC_InitTypeDef NVIC_InitStructure;
8 m# M5 Y( w' s7 |6 O! A1 x7 U+ P//Usart1 NVIC 配置; F! I4 i) k2 p. F

9 o( e: c& U5 H7 ^, D; |5 zNVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
6 [1 }' t% J7 P" m/ X+ SNVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级31 q2 F0 ?, ^3 F+ b, L
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子优先级3
% X" K6 X4 I- ]( V% Z* g; WNVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能& v2 l1 X+ G4 O. H; V! x% X
NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器
. k& n  W3 ^9 l+ C+ Z
6 V+ Y) c& p: g1 F6 e, k$ E& O2 B" T
/ Q6 w- M' B2 t

  S* X' T+ c. ]; S; p4)串口使能# A4 H' O8 r4 j

# @  U: O( J+ n+ q& K' M/ ^就是你需要什么时候开始使用串口功能,就是一句原有的函数。( E0 Y6 _5 w8 W/ i- H* c/ Z$ `- d
0 O  a% w/ L% B' j9 `

3 D0 f- r- p- N  H; s1 H$ O
0 t, x- M3 L; Q( Y* l! z* ?USART_Cmd(USART1, ENABLE); //使能串口1 8 U" C! f2 v! N
, P( j4 r8 n3 q2 w0 k) o; O3 p
& ?: X8 v2 F  Q) \& Y- a
; N5 g% g$ K7 L$ K: s% Q
5)编写串口中断处理函数
' F* ?. o+ w% u% h" t0 `
+ n- ?! X: S8 A使用库函数开发,所有的中断函数都是已经存在的,只是中断函数里面没有处理任何事情而已。中断函数如下:
4 l4 j" t8 u% L+ J4 r6 I) A0 H) ]$ `& _, z: _  S- `6 D
& m2 b; p5 D0 E9 }5 b" S1 h
1 B& n6 z/ \# Y. K
) R0 H, `; n! ?; _7 |1 s* t
void USART1_IRQHandler(void)7 P/ ]$ E+ a0 s8 S0 q
{% {* z- I- h0 Q2 k0 @
//这里是编写中断处理的内容,但是一般会先判断相关的标准才算完整
8 Y6 G$ d! j" v}6 k5 k8 u& f- h$ V2 V  `

" u& M- I4 D- q4 b* V+ }7 w6 u
6 D6 Z3 e4 z# H$ o3 U# K3 D" v  {* M# M4 S: b0 {
完整的串口中断函数:
  J5 h' z+ M& @# W/ W. n- D7 q1 y2 L# W/ K: Y% a' E
1 J7 r7 y6 k9 h4 j/ _% K3 g; N

4 ]5 }% Y! ]5 m1 f. q- [8 }0 T: F5 D: E+ f, ~
void USART1_IRQHandler(void)0 [* e1 r4 _9 v: ~" h
{
3 s9 s# O- p  e' k$ R: r5 pint Res=0; //定义一个变量用来接收串口数据集
' c- O, x* O% @! M1 tif(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
, e0 K" S8 b0 w! V5 q* Z* ^: K  {
5 j; ?7 d" v5 S! u7 n, S$ I  Res =USART_ReceiveData(USART1);//读取接收到的数据
* U5 n! {1 C$ c# q  D6 f  USART_SendData(USART1,Res ); //把接收到的数据通过串口1发送出去
' n3 A3 d) V0 F2 x" s% q$ q  }8 u/ S' [  r: Z* n
}
# W) a7 v# @3 R! J0 i
# F  y3 {( `- ]1 R7 N# d! j2 L5 K
5 W' d! [/ `3 X5 n5 b: B9 x
* E; a( Y/ a; Z9 u( f7 m串口数据的接收和发送的函数都是库函数提供的,想用时只需找到它直接拿来用就可以了。8 H+ f  u/ [( N7 z( {/ H% C5 H" l

# B2 P, d5 n* \
3 F! B( ?5 O  n3 q( v, ^' C$ g* r' `
以上就完成了一个最简单的串口实验。把程序编译烧写到STM32然后用串口转USB模块连接到电脑,使用串口数据接收软件SSCOM或其他的数据接收软件设置好波特率,打开串口,正常的话,那发送什么到STM32那就会收到什么。这样就算完成了。
+ G/ V, }( S1 }8 E7 o3 G: R
2 G& k( N) Z& f7 S6 d8 Y
" S2 o1 P) W' Q$ ~5 u. y( ]3 l+ h% h# O
这次就说到这了,如果有开发板的配套例程可以先使用,用多了,慢慢就理解了。这篇文章主要想说明串口的重要性。用串口来调试真的方便很多。
欢迎厂家入驻,推文!免费!微信:yinpinyingyong
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则