TX2440 看手册学习2440-UART的配置(ADS1.2编译)

来源:互联网 发布:网络布线报价单 编辑:程序博客网 时间:2024/05/17 00:04

TX2440 看手册学习2440-UART的配置(ADS1.2编译)

 

1) 串口对外参数---串口com口,波特率,数据位(一般8位),校验位(一般不设置),停止位(一般1位),流控制(一般全不设置):

1-1) com口:s3c2440有3个,分别是uart0-2,其中com0,1支持64位FIFO,红外,流控制。com0-2,支持中断或DMA方法发送接收数据;

1-2) 波特率:由除数寄存器UBRDIVn分频时钟源(PCLK, FCLK/n or UEXTCLK)所得;时钟源由控制寄存器UCONn[11:10]选择,如果是FCLK/n还要配合UCONn[15:12]设置;

UBRDIVn的计算公式:UBRDIVn = (int) (UART clock / (buad rate x 16)) –1;其中(UART clock:PCLK, FCLK/n or UEXTCLK),UBRDIVn应该是从1 到2^16-1当使用小于PCKL的外部时钟UEXTCLK时应该设置 0.

     例如如果波特率是 115200bps 且UART时钟是40MHz, UBRDIVn是
UBRDIVn = (int)(40000000 / (115200 x 16) ) -1
= (int)(21.7) -1 [round to the nearest whole number]
=22-1=21

另外,必须符合波特率错误公差:

波特率错误公差Baud-Rate Error Tolerance
UART帧错误应该少于1.87%(3/160).
tUPCLK = (UBRDIVn + 1) x 16 x 1Frame / PCLK tUPCLK : Real UART Clock
tUEXACT = 1Frame / baud-rate tUEXACT : Ideal UART Clock
UART error = (tUPCLK – tUEXACT) / tUEXACT x 100%
注:
1. 1Frame = start bit + data bit + parity bit + stop bit.
2. 在特定条件下,我们支持波特率最高达到 921.6K bps。例如,当PCLK为60MHz, 你可以在
1.69UART 错误公差下使用921.6K bps under UART error of 1.69%.

1-3) 数据位,校验位,停止位:由线性寄存器ULCONn[5:0]设置.

1-4) 流控制: modem控制寄存器UMCONn[4]开启关闭自动流AFC;如果关闭,又要使用流控制,就要用IO口进行软件模拟了.

2) 串口对内参数:FIFO缓冲,传输模式:

2-1) FIFO 缓冲: 由FIFO控制寄存器UFCONn[0]开启关闭.

2-2) 传输模式: 由控制寄存器UCONn[3:0]选择.   

 

通过理解上面的寄存器设置.基本的串口功能就出来了.我们来看下代码的实现:

//=========================================================================
//  工程名称: 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  by xgc
//=========================================================================

#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);
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;
extern unsigned int FCLK;
static int UartNum=0;
char *string;

#define BUF_MAX 512

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

int Main(void)
{   
    char uart_buf[BUF_MAX + 1] = {0};
   
    SetSysFclk(FCLK_400M);
    ChangeClockDivider(2, 1);
 CalcBusClk();

 myUart_Select(0);   
    myUart_Init(0,115200);

    string = uart_buf;
 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    
    {        
  rGPHCON = rGPHCON & (~(0xffff));   //UART0: RXD0<==>GPH3  TXD0<==>GPH2
  rGPHCON = rGPHCON | (0xaaa0) ;     //设置GPH端口为UART口
     rGPHUP  = 0x0;                     //使能上拉功能
 
  rUFCON0=0x00;   // 不使用FIFO 
        rUMCON0=0x00;   //不使用自动流控制
        rULCON0=0x03;   //不采用红外线传输模式,无奇偶校验位,1个停止位,8个数据位
        rUCON0=0x245;   //发送中断为电平方式,接收中断为边沿方式,禁止超时中断,允许产生错误状态中断,禁止回送模式,禁止中止  
                        //信号,传输模式为中断请求模式,接收模式也为中断请求模式。
        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')
  {
      while(!(rUTRSTAT0 & 0x2));  //等待,直到发送缓冲区为空
//      Delay(10);             //超级中断的响应速度较慢
      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)); //等待接收数据
        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')
     {
        if(c=='\b')
        {
            if( (int)string2 < (int)string )
            {
             char del_last_char[] = {'\b', ' ', '\b'};
                printf("\b \b");
                myUart_Send(del_last_char);
                string--;
            }
        }
        else
        {
         if(string - string2 < BUF_MAX)
         {
             *string++ = c;           
             myUart_SendByte(c);
            }
            else
         {
          char* max_buf = "\n\t***input errer***:too many chars!!!";
          myUart_Send(max_buf);
         }
        }      
     }
     *string='\0';
     myUart_SendByte('\n');   
    
}

void myUart_Printf(char *fmt,...)
{
    va_list ap;
    char string[256];

    va_start(ap,fmt);
    vsprintf(string,fmt,ap);
    myUart_Send(string);
    va_end(ap);
}

 

 基本的串口功能实现了.后续再研究FIFO的使用,使用FCLK/n时钟源,红外.modem功能,AFC自动流这几项.

原创粉丝点击