mini2440 development board UART Conclusion

一.概述:

s3c2440A 提供三个独立异步串口端,每个端口可以在中断模式和DMA模式下操作,也就是讲UART可以产生一个中断或DMA请求用于CPU和UART之间的数据传输。

每一个串口UART都有一个64字节的发送FIFO,一个64字节的接收FIFO。

要实现UART与上位机之间的通信,必须遵循木一个协议,通过ULCON可以定义传输数据的位数,停止的位数,红外模式等。

波特率的时钟源有:PCLK,FCLK/n,UEXTCLK,通过UCON寄存器的10,11位进行选择。大小可以这样计算:时钟源频率/(波特率*16)-1;如果计算的结果是个小数,那么把这个最接近的整数放到UBRDIVn中,即如果算的结果是16.25,那么可以把这个数取16放到UBRDIVn中。

对于FIFO和MODEM的设定是否决定相应寄存器的设定。如果没有使用FIFO和MODEM那么可以不设定这两个相应寄存器

二.UART发送与接收:

数据发送:先由ULCON寄存器设置停止位,数据位,奇偶校验位等,因为他是可编程的,发送完数据后可以发送一个终止信号。之后串口发送数据到TxFIFO。

数据接收:先由ULCON寄存器设置停溢出,停止条件,奇偶校验错等,因为他是可编程的,接收到的数据存放在RxFIFO中。当接收器三个字长的时间內没有接收到数据并且RxFIFO在FIFO模式下不为空那么接收超时。

三.相关寄存器

S3C2440A的UART单元对每个串口使用10多个寄存器,3个串口共使用了30多个寄存器。我稍微总结了下(下面的n表示串口编号,取值为0,1,2;寄存器名称中第一个字母U应该是表示UART):

ULCONn:线路控制寄存器,用于设定线路的字长度、停止位个数、奇偶校验方式、是否使用红外模式。(看的书中翻译成“线性控制寄存器”,我感觉是不正确的)

UCONn: 控制寄存器,用于设定操作模式(中断或轮询/DMA)、环回模式、中断方式、时钟选择。

UFCONn:FIFO控制寄存器,用于控制FIFO操作方式,如是否使用FIFO以及触发级别。

UMCONn:Modem控制寄存器,用于设置是否使用AFC(自动流控制)和RTS。TTL2是不支持流控制的,所以没有UMCON2寄存器。

UTRSTATn:收发状态寄存器,可从中读取收发保持寄存器的状态,即是否有数据,仅在非FIFO模式下使用。

UFSTATn:FIFO状态寄存器,可从中读取FIFO状态信息,用于FIFO模式。

UMSTATn:Modem状态寄存器,可从中读取Modem状态,即CTS信号状态。TTL2不支持流控制,所以没有UMSTAT2寄存器。

UERSTATn:错误状态寄存器,可从中读取接收错误状态。

UTXHn和URXHn:收发保持(对非FIFO模式)和缓冲(对FIFO模式)寄存器,用于收发数据。

UBRDIV:波特率除数寄存器,用于设定串口通信波特率。

四.看到有关于中断的介绍不错 贴进来分享下:

边沿(脉冲?)触发:一旦(as soon as)Tx缓冲区变为(becomes)空(非FIFO模式)或者达到(reaches)Tx FIFO触发级别(FIFO模式),则请求中断。注意,这里的“一旦”不仅限定前半句(非FIFO模式),也限定后半句(FIFO模式)。“一旦”与“变为”和“达到”连接起来,表示的是一个时间点,一个变化过程,是变为空或者达到触发级别的时间点或者说变化过程中请求中断。这个时间点过后,或者变化完成后,就不再请求中断了。只要处理中断后,清除源未决寄存器(SRCPND)和中断寄存器(INTPND)的相关位,就不会再有中断发生了。

电平触发:当(while)Tx缓冲区为空(非FIFO模式)或者达到Tx FIFO触发级别,则请求中断。这里的“当”限定前半句和后半句。“当”表示的是一种状态,是处于缓冲区空或者达到Tx FIFO触发级别的状态的时候,就请求中断。处理中断后,即使清除了源未决寄存器(SRCPND)和中断寄存器(INTPND)的相关位,只要这种状态存在,就一直请求中断,即会再次发起中断请求。只有不存在这种状态了,才不会再发起中断请求。

五.FIFO与非FIFO的区别:

S3C2440A的UART内部对于接收和发送各有64字节的缓冲区,当使用FIFO模式时,UART将使用这个缓冲区进行数据暂存操作,这样可以增加数据吞吐量,提高传输速率。其实,非FIFO模式也可以看作是特殊的FIFO模式,即只有一个字节缓冲区的FIFO模式。二者的主要不同在于读取缓冲区状态的方式:非FIFO模式下,通过UTRSTAT寄存器得知收发缓冲区状态;FIFO模式下,则从UFSTAT寄存器获得缓冲区状态。要注意的是,在FIFO模式下,只有达到触发级别后才会发起Rx或Tx中断。比如说,如果设置接收触发级别为16字节,则只有在接收缓冲区中有16个字节以上数据时,才会发起Rx中断请求。如果需要进行输入回显,则可能导致不能立即回显用户在串口工具中输入的字符

六。自动流控制(AFC)

AFC(Auto Flow Control):自动流控制。S3C44BoX中的UART用nRTS(发送请求信号)和nCTS(清除发送信号)来支持自动流控制,以此实现UART之间的互联。

自动流控制涉及到RTS和CTS,我查了下相关缩写的含义:

DTE:Data Terminal Equipment,数据终端设备,一般指计算机。

DCE:Data Communication Equipment,数据通信设备,一般是调制解调器(Modem)。

DTR:Data Terminal Ready,数据终端就绪,DTE向DCE发送这个信号表示已经准备就绪。

DSR:Data Set Ready,数据设备就绪,DCE向DTE发送这个信号表示已经准备就绪。

RTS:Request To Send,请求发送,DTE向DCE请求发送数据。

CTS:Clear To Send,清除发送,DCE向DTE表示准备就绪,可以接收数据了。

摘自百度文库:

 The S3C2440A's UART 0 and UART 1 support auto flow control with nRTS and nCTS signals. In case, it can be

  connected to external UARTs. If users want to connect a UART to a Modem, disable auto flow control bit in

  UMCONn register and control the signal of nRTS by software.

  In AFC, nRTS depends on the condition of the receiver and nCTS signals control the operation of the transmitter.

  The UART's transmitter transfers the data in FIFO only when nCTS signals are activated (in AFC, nCTS means

  that other UART's FIFO is ready to receive data). Before the UART receives data, nRTS has to be activated when

  its receive FIFO has a spare more than 32-byte and has to be inactivated when its receive FIFO has a spare under

  32-byte (in AFC, nRTS means that its own receive FIFO is ready to receive data).

 

下面是代码UART详细注释:

//=========================================================================
//  工程名称: UART.mcp
//  文件名称:  main.c
//  功能描述:  通过超级终端完成PC和S3C2440的数据传输,利用超级终端输入需要发送的字符,回车后,字符会再发送回来显示。
//  组成文件: main.c 2440lib.c 2440init.s 2440slib.s
//    头文件:  2440addr.h def.h option.h 2440lib.h 2440slib.h
//  程序分析: 采用宏定义的方法实现LED循环点亮
//  硬件连接: 用串口线将开发板和PC机串口相连  
//  维护记录: 2009-8-14 v1.0  
//=========================================================================

#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "option.h"

#include <stdarg.h>


#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

//====================================================
// 函数定义区
//====================================================
extern void Delay(int time);//延时函数在lib.h中定义
void myUart_Select(int ch);//串口选择
void myUart_Init(int whichuart, int baud);//初始化串口
void myUart_SendByte(char ch);//串口发送一个字节
char myUart_ReceiveByte(void);//接收一个字节
void myUart_Send (char *str);//发送一个字符串
void myUart_receive(char *string);//接收一个字符串
void myUart_Printf(char *fmt,...);//输出串口信息

extern unsigned int PCLK;
static int UartNum=0;
char *string;

//====================================================
// 语法格式:int Main(void)
// 功能描述: 发送并接收字符串,测试UART通信
// 入口参数: 字符串指针
// 出口参数: 无
//======================================================================

int Main(void)
  
     //设置系统 总线时钟
    SetSysFclk(FCLK_400M);
    ChangeClockDivider(2, 1);
    CalcBusClk();

   

    myUart_Select(1);   //串口数量 
    myUart_Init(0,115200);//初始化串口
 while(1)
 
     myUart_Printf("Please Input a string:\n");// 通过串口向上位机打印信息
     myUart_receive(string);  
     Delay(50);
     myUart_Send(string);
     myUart_Send("\n");
    } 
}

void myUart_Select(int ch)//选择串口数量
{
    UartNum = ch;
}

//====================================================
// 语法格式:void myUart_Init(int whichuart, int baud)
// 功能描述: 对Uart进行初始化,以所需要的波特率为输入参数
// 入口参数: UART端口号  波特率
// 出口参数: 无
//======================================================================

void myUart_Init(int pclk, int baud)
{
    if (pclk == 0)//这里用于计算下面串口波特率
     pclk = PCLK;
    if(UartNum == 0)  //判断是否使用UART0,是的话需要设置相应的管脚位从原理图可以看到需要配GPHCON寄存器  
    {        
      rGPHCON = rGPHCON & (~(0xffff));  

//UART0: RXD0<==>GPH3  TXD0<==>GPH2 这里串口1和串口2也进行了配置,但是没用到。
      rGPHCON = rGPHCON | (0xaaa0) ;     //设置GPH端口为UART口1010101010100000
      rGPHUP  = 0x0;                     //使能上拉功能

s3c2440A开发板UART总结以及UART代码详解


 
        rUFCON0=0x00;   // 不使用FIFO 
        rUMCON0=0x00;   //不使用自动流控制
        rULCON0=0x03;   //不采用红外线传输模式,无奇偶校验位,1个停止位,8个数据位
        //发送中断为电平方式,接收中断为边沿方式,禁止超时中断,允许产生错误状态中断,禁止回送模式,禁止中止信号,传输模式为中断请求模式,接收模式也为中断请求模式。 001001000101
        rUCON0=0x245;  

         s3c2440A开发板UART总结以及UART代码详解


        rUBRDIV0=( (int)(pclk/16./baud+0.5) -1 );  //根据波特率计算UBRDIV0的值
        Delay(10);
     }
     else if(UartNum == 1)
     {
       rGPHCON = rGPHCON & (~(0xffff)) ; //UART1: RXD1<==>GPH5  TXD1<==>GPH4
       rGPHCON = rGPHCON | (0xaaa0) ;    //设置GPH端口为UART口
       rGPHUP  = 0x0;                    // 使能上拉功能
 
        rUFCON1=0x0;   
        rUMCON1=0x0;  
        rULCON1=0x3;
        rUCON1=0x245;
        rUBRDIV1=( (int)(pclk/16./baud+0.5) -1 );
        Delay(10);
     }
}

//====================================================
// 语法格式:void myUart_SendByte(char ch)
// 功能描述: 发送字节数据
// 入口参数: 发送的字节数据      
// 出口参数: 无
//====================================================================

void myUart_SendByte(char ch)
{
 if (UartNum ==0)
    {
  if(ch=='\n')
  {

s3c2440A开发板UART总结以及UART代码详解

 //非FIFO模式时,等待,直到发送缓冲区为空,0010为空的时候退出,如果是FIFO模式那么检测UFTRSTAT寄存器,MODEM模式下,检测UMTRSTAT寄存器

      while(!(rUTRSTAT0 & 0x2)); 

       Delay(10);             //超级中断的响应速度较慢 
     //这个在addr.h的宏定义,向发送缓冲区写入一个数#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)

      WrUTXH0('\r');              //发送回车符
  }
    while(!(rUTRSTAT0 & 0x2));      //等待,直到发送缓冲区为空
//  Delay(10);
    WrUTXH0(ch);                    //发送字符

//发送
    }
 else
    {
  if(ch=='\n')
     {
      while(!(rUTRSTAT1 & 0x2));   //等待,直到发送缓冲区为空
//      Delay(10);                  //等待
      rUTXH1='\r';
     }
     while(!(rUTRSTAT1 & 0x2));  //Wait until THR is empty.
//     Delay(10);
     WrUTXH1(ch);
    } 
}

//====================================================
// 语法格式:char myUart_ReceiveByte(void)
// 功能描述: 接收字节数据
// 入口参数: 无
// 出口参数: 接收的字节数据
//====================================================================

char myUart_ReceiveByte(void)
{
    if(UartNum==0)
    {    

        //等待接收数据如果没有数据一直循环,有数据退出 返回
       while(!(rUTRSTAT0 & 0x1));s3c2440A开发板UART总结以及UART代码详解

         return RdURXH0();
    }
    else if(UartNum==1)
    {      
        while(!(rUTRSTAT1 & 0x1)); //等待接收数据接收到数据的话退出循环。
        return RdURXH1();
    }
    return 0;
}

//====================================================
// 语法格式:void myUart_Send (char *str)
// 功能描述: 发送字符串
// 入口参数: 字符串指针
// 出口参数: 无
//====================================================================

void myUart_Send (char *str)
{
    myUart_Init(0,115200);//这里把这个字符串发送出去
    while (*str)
    myUart_SendByte(*str++);


//====================================================
// 语法格式:void myUart_receive(char *string)
// 功能描述: 接收字符串
// 入口参数: 字符串指针
// 出口参数: 无
//===================================================================

void myUart_receive(char *string)
{
     char *string2 ;
     char c;
     string2 = string;
     myUart_Init(0,115200);
     while((c = myUart_ReceiveByte())!='\r')// /r 回车(CR) ,将当前位置移到本行开头
     {
        if(c=='\b')//退格(BS) ,将当前位置移到前一列这里是删除一个字节
        {
            if( (int)string2 < (int)string ) //真心没看懂这个
            {
                printf("\b \b");
                string--;
            }
        }
        else
        {
            *string++ = c;           
            myUart_SendByte(c);//把接收到的字节存放到string中
        }
     }
     *string='\0';
     myUart_SendByte('\n');   
    
}

void myUart_Printf(char *fmt,...)//主要目的为让函数能够接收可变参数。[
{
    va_list ap;//typedef int *va_list[1]一个指针数组
    char string[256];

    va_start(ap,fmt);//调用va_start并传入两个参数:第一个参数为va_list类型的变量,第二个为省略号前最后一个有名字的参数的名称,接着每一调用va_arg就会返回下一个参数,va_arg的第一个参数为va_list,第二个参数为返回的类型
    vsprintf(string,fmt,ap);
    myUart_Send(string);
    va_end(ap);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenART是一个基于分布式处理器的开源平台。Mini UART通信是OpenART平台中的一种通信方式,它是一种简单的串行通信接口,主要用于实现OpenART平台各个模块之间的通信。Mini UART通信采用UART协议,具有简单、稳定、可靠等特点。在OpenART平台中,Mini UART通信可以用于传输命令、数据和状态信息等。 Mini UART通信的实现需要使用GPIO。在OpenART平台中,GPIO被用作连接OpenART主控制器和各个模块的信号线。Mini UART通信可以通过GPIO和串口通信模块实现。其中,串口通信模块作为Mini UART通信的核心模块,负责将OpenART平台中不同的模块之间的数据进行转换和传输。 在OpenART平台中,Mini UART通信采用基于中断的方式实现。首先,OpenART主控制器将要传输的数据存储在发送缓冲区中,并将其转换为串行数据。然后,OpenART主控制器通过GPIO将这些数据发送到串口通信模块。串口通信模块再将这些数据进行转换和加工,并将其传输到接收缓冲区中。接收缓冲区中的数据再通过GPIO被传输到各个模块中,完成Mini UART通信的实现。 总之,OpenART平台中的Mini UART通信是一种简单、可靠的通信方式,可以广泛应用于各个模块之间的数据传输。通过Mini UART通信,不仅可以实现OpenART平台内部模块之间的通信,也可以实现与外部设备的通信,提高了整个OpenART平台的灵活性和可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值