|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
一. 串口编程的硬件原理
# T: p- O- y3 Y2 r1. 串口特性:: X; @: F. O1 {4 F; T1 T% X
1>16字节接收FIFO和16字节发送FIFO( F6 |/ U2 |# \! e
2>接收FIFO触发点可设置为1,4,8或14字节。7 O8 N- p3 J3 W, q4 J: i; z" Y
3>内置波特率发生器。
: \+ _0 R' g! j' W# J2. UART0引脚:8 i0 g& [1 w$ h' Y8 ^
1>RxD0 引脚用于UART0接受数据,接受方式为串行输入。. M$ a/ \/ @9 o# R% s
2>TxD0引脚用于UART0发送数据,发送方式为串行发送数据。/ F8 i7 v, Y5 Z* L. w: X
3. UART0的结构和工作方式
1 ]9 [# [5 w( y* T% n: }- D% C先看图在说明:
: U4 _4 | E( a7 V' @
* @- n4 U+ t1 e# M+ X, M2 G1> VPB总线提供CPU与UART0之间得的通信连接. _% r+ @8 N8 p% i. N
(CPU内核通过VPB接口对UART0的寄存器进行读写访问.)5 F8 g% m4 J; Z9 r
2> UART0 接收器模块监视串行输入线RxD0的有效输入。UART0 接收单元的移位寄存器(U0RSR)通过RxD0接收有效的字符。当U0RSR接受到一个有效字符时,它将该字符传送到UART0 接收单元缓冲寄存器FIFO中,等待CPU通过VPB接口进行访问。; N7 g( \" G/ k \- [3 Z& A
3> UART0发送器模块接收CPU或主机写入的数据并将数据缓存到UART0 的FIFO或U0THR中,UART0发送模块中的移位寄存器(U0TSR)读取U0THR或FIFO中的数据并将数据通过串行输出到引脚TxD0发送。
/ o% o/ {7 |3 e6 V( b4> UART0的接收模块和发送模块的状态信息保存在U0LSR中。
) [4 d0 k% ] |% D8 N# L5 r控制信息保存在U0LCR中。/ V) w& y4 A$ \- P# Z4 V- V
5> UART0波特率发送器模块产生UART0 发送模块所使用的定时。波特率发生器模块时钟源为VPB时钟(pclk)。主时钟与U0DLL和U0DLM寄存器所定义的除数相除得到UART0 发送器模块使用的时钟,该时钟必须为波特率的16倍。
6 Q! y [' h$ @/ Q( ^6> 中断接口包含寄存器U0IER和U0IIR。中断接口接收UART0发送模块和接收模块发出的单时钟宽度的使能信号。
& m1 d, Q. p7 N, G# s4. UART0和ARM7 CPU之间的通信过程8 v2 u6 o) X: |8 ?
1>CPU通过UART0发送模块发送信息给外设
/ W1 O1 x4 { f% j; m. H( ol CPU发出信息通过AHB总线到AHB-VPB桥8 s+ H* f9 ^ Z/ z) F- S
l 通过AHB-VPB桥把信息转换后发送给VPB总线。
d7 e; N- V$ i, P9 C) \l UART0接收模块接受来自VPB总线的数据。并将数据缓存到U0THR寄存器中。$ |$ d/ j1 x8 A Z
l UART0接受模块的移位寄存器U0TSR读取U0THR中的数据 并将数据通过输出引脚TxD0发送
0 q, V l2 h( w+ W: @/ B/ t3 X$ L
S5 d& S! i/ H/ Q2>外设通过UART0接收模块向ARM7 CPU发送信息
6 Y* _+ K5 U7 I9 Z- \( _# yl UART0移位寄存器(U0RSR)通过引脚RxD0接收有效字符。" ]. R+ E$ V. z5 [/ ~( T% i
l 当UART0接收到一个有效字符后,通过读取U0RBR寄存器可以将FIFO中最早接收到的字节读出,当FIFO中不再包含有效数据时,该寄存器反映接收到的最后一个有效字节数据。接收的数据不足8位时,高位用0填充。
, M1 J$ q$ u& l- g2 v2 tl VPB总线将缓冲寄存器(U0RBR)中的数据通过AHB-VPB桥传到AHB总线上0 }& G1 y8 `9 @' K( o9 R
l AHB总线将数据传送给ARM7 CPU
8 B& n+ L5 a$ b( M1 L: o3 l; ` B2 _2 D: M* C6 q+ }1 A
二. 轮训方式的串口编程
, Y0 Y* F, J' R4 U- C1 M( |1. 串口程序都有那几部分组成
2 v! G! Z* W0 l! z看图:! H0 @- k. U# _# G
$ |4 P% O/ v1 A0 U+ h* m, |2 N/ J E1> 串口初速化- M+ ^3 o$ I5 n/ W% |/ k( }
A. 串口初始化的流程
9 ]: A( o% Q+ t6 r6 ?l 设置I/O引脚连接到UART0
% ]) l2 ?, o9 \l 设置串口波特率
2 v. A- X: w6 |' [( ?: X4 Ul 设置串口工作模式) R: G8 Z9 p# e. K' s7 n& t5 T
B. 串口初始化需要设置的寄存器
+ _; i3 u1 L: Z6 u1 ?* ql U0LCR(控制寄存器):设置UART0的通信格式。5 \4 X* p% j+ B6 y' H( D
l U0DLL,U0DLM(寄存器):设置UART0的通信波特率。
% p( d4 T" Y m8 Z6 Z( O# ?2 jC. 具体寄存器的设置$ x& @! a9 ?: z& ~( p
(1) U0LCR(线控制寄存器)
" K. K4 c- t* _5 Y3 }l 作用:设置通信格式(通信字符长度,停止位个数,奇偶校验位
/ x) T" H2 e4 G! Vl 长度:8位寄存器
$ t& D2 A8 ]! w" Dl 各位寄存器的含义:
" }/ f1 i6 O% _6 ]. [0 R) E0 F第[1 ,0]位: 表示字长
7 V7 p% b& d1 t4 v% h00:表示5位字长
( r/ }7 A, {) ]$ X. j01:表示6位字符长度. y- N( q8 C; l# R, H5 E
10:表示7位字符长度
% `! x5 X" S5 _8 u+ |11:表示8位字符长度5 _) ~; {" K3 _, B, b. T
第2位: 表示停止位选择* e/ |5 v( {: I: |1 \& a3 t
0:1个停止位
) w; s9 ~* o; R- r# l1:2个停止位8 J, I: c' |' P7 ^" W
3位:表示奇偶使能$ A6 c; }: `9 I% c8 \ c
0:禁止奇偶产生和校验
2 W5 u( a! p1 L. e$ H; W1:使能奇偶产生和校验5 M9 s5 \1 B* E* R& H# t/ B' I- M
注:奇偶使能:控制是否进行奇偶校验。如果使能,发送时将添加一位校验位。
~1 n1 ]3 r6 K第[5 4]位:表示奇偶选择位
+ l( Q& K# W) \$ X00:奇数(数据位+校验位=奇数)
- S5 d, D4 J1 ]0 E01:偶数(数据位+校验位=偶数)4 `: n% a+ z8 R5 B. f- X N- |
10:校验位强制为1
; ]& I u! ~4 h11:校验位强制为0
4 p- @4 u, D* u0 ~/ w$ E; R注:奇偶选择主要是设置奇偶校验类型。
6 l+ x! E( ~( |+ O8 I第6位:间隔控制" F& E+ U% f7 I7 I
0:禁止间隔发送
" Q+ @! W; [; X4 B9 i1:使能间隔发送$ X8 k/ z H4 u- ~
注:当该位为1时,输出引脚(TxD0)强制为逻辑0,可以引起通信对方产生间隔中断。在一些通信方式中,使用间隔中断作为通信的起始信号(eg IN Bus)
5 C0 x$ B8 T% Z% s* b# J$ h第7位:除数锁存访问位* v6 P* D4 g O8 @1 D
0:禁止访问除数锁存寄存器' x) r, i, w1 h
1:始能访问除数锁存寄存器
* I7 F5 T9 \2 B! q: J( O; g
) s9 x/ S! U2 {/ | o6 J8 r5 @(2) U0DLL,U0DLM(除数锁存寄存器)
, [3 Y; U [& `9 I9 C. Dl 作用:U0DLL和U0DLM寄存器一起构成一个16位除数。) C: m, C2 ~2 B& E$ Y
l U0DLL和U0DLM都为8位寄存器。
" j" k: D! ^! F7 w2 {% S) I, }; Nl U0DLL:存放分频值的低8位
; L2 j/ \$ K/ Nl U0DLM:存放分频值的高8位。
/ M) n; j2 L0 a, G6 ~. t注:
: l% F/ A L& g* zØ 1.使用U0DLL和U0DLM配置波特率之前,必须先计算分频值。8 N K1 ]9 E0 w7 o. H
Fdiv=Fpclk/(16*baud)
8 ], [3 _1 k$ B2 W1 d6 mØ 2.使用U0DLL和U0DLM配置波特率之前必须把U0LCR控制寄存器的第8位置为1才能进行配置。配置完后要把U0LCR控制寄存器的第8位置位0。
( [ m8 U. a6 G, X: S: Z2> 串口初始化化程序) P m/ q) T4 z( |1 J
A方法一:
2 O1 J- y! M; s3 v# M1 B. E; \2 S% y- a/ Y7 `0 [
void UART0_Init(uint32 bps)
! x0 `& ?- d% u; Q5 L{" _& B. b& g; }5 h) n7 d+ E
+ V. H& ?- i3 N. X/ _. m+ z- Nuint16 Fdiv;, X3 B$ O- ~) e6 V( @
PINSEL0=0x00000005; //设置串口引脚0 C; |6 o: A+ D, G
U0LCR=0x83; //置为除数锁存位,进行配置; e8 t; @* J) h9 h6 k7 U1 `7 g; Z. x- u
Fdiv=(Fpclk>>4)/UART0_BPS;/ a9 ]4 O; Y# ]4 r8 i
U0DLM=Fdiv>>8;7 Q; J% `6 M1 h1 v* P' C
U0DLL=Fdiv&0xff;, T( [( X: p' O9 q
U0LCR=0x03; //清除除数锁存位,并设置工作模式' P- y* V% c8 l) f% y3 F0 ^8 s
}
( o4 P! ]2 e8 @% L7 z2 j: _9 N6 gB.方法二:
2 k, d6 @( k6 ~
3 E, f0 w2 S- z9 b. Q$ n7 _( Y' `' P, l6 I
typedef struct UartMode/ B. Z6 x$ m3 `; C
{ uint8 datab; // 字长度,5/6/7/80 b8 Q$ _# ?8 g3 Q, X
uint8 stopb; // 停止位,1/27 w: g) P* r- {
uint8 parity; // 奇偶校验位,0为无校验,1奇数校验,2为偶数校验% E* _) S* S# X# L: u" N
} UARTMODE;
8 M4 _0 t1 {, ]. Duint8 UART0_Init(uint32 baud, UARTMODE set)
; V8 R% r8 S3 b4 h3 _6 f- C# x{ uint32 bak;: }) c7 c4 N, `* J$ h0 U6 r
- ~2 n4 h+ k \8 t8 {4 B# b
8 W7 e/ l8 X. s% [! I1 H6 ?if( (0==baud)||(baud>115200) )0 f" R6 H y" m5 O
{
! T; d" _, } j# wreturn(0);
+ K# C7 h/ y: R}
% h. @8 Q) N2 {; u7 G# i9 jif( (set.datab<5)||(set.datab>8) )
$ h6 @7 l) \" n- F5 u! E. t{
3 C% l: f0 i4 qreturn(0);
5 i2 H" w( _ K% F& d: k}2 O* q8 y1 F. a2 h/ a
if( (0==set.stopb)||(set.stopb>2) )8 ]7 m3 M2 W$ _, Y* x
{
- l2 c# A- E; e7 qreturn(0);1 N1 f" B: l2 [. n
} I" h* x) S- I8 \' e
if( set.parity>4 )) G2 [. x. S' Y8 w
{
u' e5 p1 d, ~' U3 n$ |6 ?return(0);
9 X B; _2 g3 Z; A2 k: d4 I}
- y2 }2 K" B! I. w% W& i! Z, h |
|
|