本文章针对的是ARM2200环境下编写串口程序,其中设计轮循方式,中断方式,以及在UC/OS-II操作系统下的串口编程。 使用轮循和中断两种方式来实现串口编程。 (当然了,用中断实现串口编程,系统的效率较高。但是难度也较大 。轮循方式效率较低,但是编程比较简单)
一. 串口编程的硬件原理 1. 串口特性: 1>16字节接收FIFO和16字节发送FIFO 2>接收FIFO触发点可设置为1,4,8或14字节。 3>内置波特率发生器。 2. UART0引脚:
1>RxD0 引脚用于UART0接受数据,接受方式为串行输入。 2>TxD0引脚用于UART0发送数据,发送方式为串行发送数据。 3. UART0的结构和工作方式
先看图在说明:
1> VPB总线提供CPU与UART0之间得的通信连接 (CPU内核通过VPB接口对UART0的寄存器进行读写访问.) 2> UART0 接收器模块监视串行输入线RxD0的有效输入。UART0 接收单元的移位寄存器(U0RSR)通过RxD0接收有效的字符。当U0RSR接受到一个有效字符时,它将该字符传送到UART0 接收单元缓冲寄存器FIFO中,等待CPU通过VPB接口进行访问。 3> UART0发送器模块接收CPU或主机写入的数据并将数据缓存到UART0 的FIFO或U0THR中,UART0发送模块中的移位寄存器(U0TSR)读取U0THR或FIFO中的数据并将数据通过串行输出到引脚TxD0发送。 4> UART0的接收模块和发送模块的状态信息保存在U0LSR中。 控制信息保存在U0LCR中。 5> UART0波特率发送器模块产生UART0 发送模块所使用的定时。波特率发生器模块时钟源为VPB时钟(pclk)。主时钟与U0DLL和U0DLM寄存器所定义的除数相除得到UART0 发送器模块使用的时钟,该时钟必须为波特率的16倍。 6> 中断接口包含寄存器U0IER和U0IIR。中断接口接收UART0发送模块和接收模块发出的单时钟宽度的使能信号。 4. UART0和ARM7 CPU之间的通信过程 1>CPU通过UART0发送模块发送信息给外设 l CPU发出信息通过AHB总线到AHB-VPB桥 l 通过AHB-VPB桥把信息转换后发送给VPB总线。 l UART0接收模块接受来自VPB总线的数据。并将数据缓存到U0THR寄存器中。 l UART0接受模块的移位寄存器U0TSR读取U0THR中的数据 并将数据通过输出引脚TxD0发送 2>外设通过UART0接收模块向ARM7 CPU发送信息 l UART0移位寄存器(U0RSR)通过引脚RxD0接收有效字符。 l 当UART0接收到一个有效字符后,通过读取U0RBR寄存器可以将FIFO中最早接收到的字节读出,当FIFO中不再包含有效数据时,该寄存器反映接收到的最后一个有效字节数据。接收的数据不足8位时,高位用0填充。 l VPB总线将缓冲寄存器(U0RBR)中的数据通过AHB-VPB桥传到AHB总线上 l AHB总线将数据传送给ARM7 CPU 二. 轮训方式的串口编程 1. 串口程序都有那几部分组成 看图: 1> 串口初速化 A. 串口初始化的流程 l 设置I/O引脚连接到UART0 l 设置串口波特率 l 设置串口工作模式 B. 串口初始化需要设置的寄存器 l U0LCR(控制寄存器):设置UART0的通信格式。 l U0DLL,U0DLM(寄存器):设置UART0的通信波特率。 C. 具体寄存器的设置 (1) U0LCR(线控制寄存器) l 作用:设置通信格式(通信字符长度,停止位个数,奇偶校验位 l 长度:8位寄存器 l 各位寄存器的含义: 第[1 ,0]位: 表示字长 00:表示5位字长 01:表示6位字符长度 10:表示7位字符长度 11:表示8位字符长度 第2位: 表示停止位选择 0:1个停止位 1:2个停止位 3位:表示奇偶使能 0:禁止奇偶产生和校验 1:使能奇偶产生和校验 注:奇偶使能:控制是否进行奇偶校验。如果使能,发送时将添加一位校验位。 第[5 4]位:表示奇偶选择位 00:奇数(数据位+校验位=奇数) 01:偶数(数据位+校验位=偶数) 10:校验位强制为1 11:校验位强制为0 注:奇偶选择主要是设置奇偶校验类型。 第6位:间隔控制 0:禁止间隔发送 1:使能间隔发送 注:当该位为1时,输出引脚(TxD0)强制为逻辑0,可以引起通信对方产生间隔中断。在一些通信方式中,使用间隔中断作为通信的起始信号(eg:LIN Bus) 第7位:除数锁存访问位 0:禁止访问除数锁存寄存器 1:始能访问除数锁存寄存器 (2) U0DLL,U0DLM(除数锁存寄存器) l 作用:U0DLL和U0DLM寄存器一起构成一个16位除数。 l U0DLL和U0DLM都为8位寄存器。 l U0DLL:存放分频值的低8位 l U0DLM:存放分频值的高8位。 注: Ø 1.使用U0DLL和U0DLM配置波特率之前,必须先计算分频值。 Fdiv=Fpclk/(16*baud) Ø 2.使用U0DLL和U0DLM配置波特率之前必须把U0LCR控制寄存器的第8位置为1才能进行配置。配置完后要把U0LCR控制寄存器的第8位置位0。 2> 串口初始化化程序 A方法一: /********************************************************** * 作者:tiger-john * 时间:2011年1月17日 * 名称:UART0_Init() * 功能:UART0初始化(通讯波特率115200,8位数据位,1位停止 位,无奇偶校验) * 入口参数:bps 串口波特率 * 出口参数:无**********************************************************/ void UART0_Init(uint32 bps) { uint16 Fdiv; PINSEL0=0x00000005; //设置串口引脚 U0LCR=0x83; //置为除数锁存位,进行配置 Fdiv=(Fpclk>>4)/UART0_BPS; U0DLM=Fdiv>>8; U0DLL=Fdiv&0xff; U0LCR=0x03; //清除除数锁存位,并设置工作模式 } B.方法二: /********************************************************** * 作者:tiger-john * 时间:2011年1月17日 * 名 称:UART0_Init() * 功 能:初始化串口0。设置其工作模式及波特率。 * 入口参数:baud 波特率 * set 模式设置(UARTMODE数据结构) * 出口参数:返回值为1时表示初化成功,为0表除参数出错********************************************************/ /* 定义串口模式设置数据结构 */ typedef struct UartMode { uint8 datab; // 字长度,5/6/7/8 uint8 stopb; // 停止位,1/2 uint8 parity; // 奇偶校验位,0为无校验,1奇数校验,2为偶数校验 } UARTMODE; uint8 UART0_Init(uint32 baud, UARTMODE set) { uint32 bak; /* 参数过滤 */ if( (0==baud)||(baud>115200) ) { return(0); } if( (set.datab<5)||(set.datab>8) ) { return(0); } if( (0==set.stopb)||(set.stopb>2) ) { return(0); } if( set.parity>4 ) { return(0); } /* 设置串口波特率 */ U0LCR = 0x80; // DLAB位置1 bak = (Fpclk>>4)/baud; U0DLM = bak>>8; U0DLL = bak&0xff; /* 设置串口模式 */ bak = set.datab-5; // 设置字长度 if(2==set.stopb) { bak |= 0x04; // 判断是否为2位停止位 } if(0!=set.parity) { set.parity = set.parity-1; bak |= 0x08; } bak |= set.parity<<4; // 设置奇偶校验 U0LCR = bak; return(1); }
|