微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > s3c2440的UART用法

s3c2440的UART用法

时间:11-19 来源:互联网 点击:
SPI、IIC和UART是最常用的三种串行总线,这三种总线在s3c2440中都被集成了。在这里我们主要介绍UART,另两个总线在后面的文章中给出。

UART(Universal Asynchronous Receiver/Transmitter,通用异步接收/发送装置)用于异步通信,可以实现全双工发送和接收。它不仅可以实现不同嵌入式系统之间的通信,还可以实现与PC之间的通信。

s3c2440提供了三个UART端口,它们都可以通过查询、中断和DMA方式传输数据,而且每个UART都分别有一个64个字节的接收FIFO和一个64个字节的发送FIFO。在这里,我们只给出非FIFO模式,即传输数据不利用FIFO缓存,一个字节一个字节地传输。

下面我们就给出如何用s3c2440来实现非FIFO的UART通信。要实现某种通信,就必须遵循该通信协议。UART的协议包括传输数据的位数,停止位的位数,以及是否进行奇偶校验,这些设置是利用ULCONn寄存器完成的。另一个很重要的地方就是设置波特率。s3c2440波特率的时钟源有三个:PCLK、FCLK/n和UEXTCLK。时钟源的选择是由UCONn的第10位和第11位来完成的。波特率的具体计算公式为:
时钟源频率÷(波特率×16)-1
这个计算结果很可能是小数,把该小数取最接近的整数,放入寄存器UBRdivn中就完成了波特率的设置。如我们选择波特率的时钟源为PCLK,它为50MHz,我们设置的波特率为115.2kHz,通过上式计算的结果为26.13,取整后得到26,那么我们把26放入UBRdivn中即可。由于我们没有使用FIFO和MODEM,所以可以不用设置FIFO控制寄存器UFCONn和MODEM控制寄存器UMCONn。通过以上寄存器的设置,UART就可以正常传输数据。

接收到的数据是放到接收缓存器URXHn中,要发送数据时,是把数据放入发送缓存器UTXHn中。由于UART是通过字节方式传输数据的,因此要区分是大端模式还是小端模式,也就是说这两个寄存器在这两种模式下,所在的地址是不同。为了了解当前数据传输的各种状态,还需要一些状态寄存器。传输状态寄存器UTRSTATn非常有用,它的第0位可以用来判断接受缓存器内是否有可接收的数据,第1位和第2位可以用来判断发送缓存器中是否为空,为空时可以发送数据。由于在这里我们不进行传输数据时错误的判断,因此错误状态寄存器UERSTATn不需要,FIFO状态寄存器UFSTATn和MODEM状态寄存器UMSTATn在这里也不需要。

我们给出UART通信的两种方法:查询和中断。为了验证程序,使用任一款的串行通信软件来实现PC和s3c2440之间的通信即可。

首先给出的是查询程序。它是在主程序的循环体内不断查询UART端口,当有数据来时,就接收数据,并再通过UART发送该数据。然后根据所接收数据的不同,分别执行不同的内容,如点亮、熄灭LED,蜂鸣器响、或不响。在这里,我们每次只完成一个字节的传输。

#define rGPBCON(*(volatile unsigned *)0x56000010)//Port B control
#define rGPBDAT(*(volatile unsigned *)0x56000014)//Port B data
#define rGPBUP(*(volatile unsigned *)0x56000018)//Pull-up control B

#define rGPHCON(*(volatile unsigned *)0x56000070)//Port H control
#define rGPHUP(*(volatile unsigned *)0x56000078)//Pull-up control H

#define rULCON0(*(volatile unsigned *)0x50000000)//UART 0 Line control
#define rUCON0(*(volatile unsigned *)0x50000004)//UART 0 Control
#define rUFCON0(*(volatile unsigned *)0x50000008)//UART 0 FIFO control
#define rUMCON0(*(volatile unsigned *)0x5000000c)//UART 0 Modem control
#define rUTRSTAT0(*(volatile unsigned *)0x50000010)//UART 0 Tx/Rx status
#define rUERSTAT0(*(volatile unsigned *)0x50000014)//UART 0 Rx error status
#define rUFSTAT0(*(volatile unsigned *)0x50000018)//UART 0 FIFO status
#define rUMSTAT0(*(volatile unsigned *)0x5000001c)//UART 0 Modem status
#define rUBRdiv0(*(volatile unsigned *)0x50000028)//UART 0 Baud rate divisor

//little endian
#define rUTXH0 (*(volatile unsigned char *)0x50000020)//UART 0 Transmission Hold
#define rURXH0 (*(volatile unsigned char *)0x50000024)//UART 0 Receive buffer

void Main(void)
{
char ch;
rGPBCON = 0x015551;
rGPBUP= 0x7ff;
rGPBDAT = 0x1e0;

rGPHCON = 0x00faaa;//使用UART0功能
rGPHUP= 0x7ff;

rULCON0 = 0x3;//设置UART0无奇偶校验,一位停止位,8位数据
rUCON0 = 0x245;//PCLK为时钟源,接收和发送数据为查询或中断方式
rUFCON0 = 0;//
rUMCON0 = 0;//
rUBRdiv0 = 26;//设置波特率,PCLK为50MHz,波特率为115.2kHz

while(!(rUTRSTAT0 & 0x2));//等待并判断发送缓存是否为空
rUTXH0 = 0xaa;//是空,则发送0xAA字节

while(1)
{
while(!(rUTRSTAT0 & 0x1)); //等待并判断接收缓存是否准备好
ch = rURXH0;//接收一个字节数据
while(!(rUTRSTAT0 & 0x2));//等待并判断发送缓存是否为空
rUTXH0 = ch;//发送一个字节数据

switch(ch)//根据所接收数据的不同,执行不同的程序
{
case 0x11://灭LED
rGPBDAT |= 0x1e0;
break;
case 0x22://亮LED
rGPBDAT &= 0x1f;
break;
case 0x33://蜂鸣器不响
rGPBDAT &= 0x1e0;
break;
case 0x44://蜂鸣器响
rGPBDAT |= 0x1;
break;
default://LED灭,蜂鸣器不响
rGPBDAT = 0x1e0;
break;
}
}
}

下面是UART中断程序,它要比查询复杂一些,因为涉及到了中断处理,并且UART发送数据和接收数据是一个中断源。主程序循环体内不执行任何程序,都在UART中断程序内执行。当接收到0x55字节数据时,亮两个LED,当接收到其他数据时,发送该字节,并在发送部分执行亮4个LED程序。

#define _ISR_STARTADDRESS 0x33ffff00
#define pISR_UART0(*(unsigned *)(_ISR_STARTADDRESS+0x90))
#define U32 unsigned int

#define rGPBCON(*(volatile unsigned *)0x56000010)//Port B control
#define rGPBDAT(*(volatile unsigned *)0x56000014)//Port B data
#define rGPBUP(*(volatile unsigned *)0x56000018)//Pull-up control B

#define rGPHCON(*(volatile unsigned *)0x56000070)//Port H control
//#define rGPHDAT(*(volatile unsigned *)0x56000074)//Port H data
#define rGPHUP(*(volatile unsigned *)0x56000078)//Pull-up control H

#define rULCON0(*(volatile unsigned *)0x50000000)//UART 0 Line control
#define rUCON0(*(volatile unsigned *)0x50000004)//UART 0 Control
#define rUFCON0(*(volatile unsigned *)0x50000008)//UART 0 FIFO control
#define rUMCON0(*(volatile unsigned *)0x5000000c)//UART 0 Modem control
#define rUTRSTAT0(*(volatile unsigned *)0x50000010)//UART 0 Tx/Rx status
#define rUERSTAT0(*(volatile unsigned *)0x50000014)//UART 0 Rx error status
#define rUFSTAT0(*(volatile unsigned *)0x50000018)//UART 0 FIFO status
#define rUMSTAT0(*(volatile unsigned *)0x5000001c)//UART 0 Modem status
#define rUBRdiv0(*(volatile unsigned *)0x50000028)//UART 0 Baud rate divisor

//little endian
#define rUTXH0 (*(volatile unsigned char *)0x50000020)//UART 0 Transmission Hold
#define rURXH0 (*(volatile unsigned char *)0x50000024)//UART 0 Receive buffer

#define rSRCPND(*(volatile unsigned *)0x4a000000)//Interrupt r

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top