您的位置 首页 测评

s3c2440的UART用法

SPI、IIC和UART是最常用的三种串行总线,这三种总线在s3c2440中都被集成了。在这里我们主要介绍UART,另两个总线在后面的文章中给出。U…

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 request status
#define rINTMSK(*(volatile unsigned *)0x4a000008)//Interrupt mask control
#define rINTPND(*(volatile unsigned *)0x4a000010)//Interrupt request status
#define rSUBSRCPND(*(volatile unsigned *)0x4a000018)//Sub source pending
#define rINTSUBMSK(*(volatile unsigned *)0x4a00001c)//Interrupt sub mask

void __irq uartISP(void)
{
char ch;

rSUBSRCPND |= 0x3;
rSRCPND = 0x1<<28;
rINTPND = 0x1<<28; if(rUTRSTAT0 & 1)//接纳数据处理部分
{
ch = rURXH0;//接纳字节数据
if(ch==0x55)
rGPBDAT = ~0x61;//亮两个LED
else
rUTXH0 = ch;//发送字节数据
}
else//发送数据处理部分
{
rGPBDAT = ~0x1e1;//亮4个LED
}
}

void Main(void)
{

rGPBCON = 0x015551;
rGPBUP= 0x7ff;
rGPBDAT = 0x1e0;

rGPHCON = 0x00faaa;
rGPHUP= 0x7ff;

rULCON0 = 0x3;
rUCON0 = 0x5;
rUFCON0 = 0;
rUMCON0 = 0;
rUBRDIV0 = 26;

rSRCPND = 0x1<<28;
rSUBSRCPND = 0x3;
rINTPND = 0x1<<28;
rINTSUBMSK = ~(0x3);//翻开UART0发送和接纳中止屏蔽
rINTMSK = ~(0x1<<28);//翻开UART0中止屏蔽 pISR_UART0 = (U32)uartISP; while(1)
{

}
}

最终还要着重几点关于非FIFO形式下UART中止的一些注意事项:
1.关于s3c2440来说,接纳数据是被迫的,发送数据是自动的,因而一般来说,接纳数据用中止办法,发送数据用查询办法较好;
2.在中止办法下,当接纳到数据时,虽然或许该数据无用,但也必定要读取它,不然下次再接纳数据时,不会再引起中止,我们接纳数据缓存器被前次接纳到的数据所强占,只需没有读取它,它就永久在那里;
3.咱们UART中止触及到SUBSRCPND寄存器,因而在中止处理程序中不只要清SRCPND寄存器,还要清SUBSRCPND寄存器,它们的次序必定是先清SUBSRCPND寄存器,再清SRCPND寄存器,不然就会引起一个中止两次呼应的问题。我们是否中止由SRCPND寄存器决议,而SRCPND寄存器的相关状况位由SUBSRCPND寄存器决议,假如先清SRCPND寄存器,而还没有清SUBSRCPND寄存器的话,SRCPND寄存器的相关位仍是会被置1,而一旦被置1,则必定还会引起中止。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ceping/265496.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部