S3C2440 中UART的实现

S3C2440A的有3个UART,都可以基于中断和DMA进行数据传输,可以支持最高115.2Kbps的比特率。每个UART通道包含两个64字节的FIFO。
UART的七种状态信号:溢出错误,奇偶校验错误,帧错误,断点,接收缓冲器数据就绪,发送缓冲空以及发送移位空,全部由状态寄存器(UTRSTATn/UERSTATn)标示。
波特率的产生:可以选择内部时钟和UEXTCLK,由UCONn设置并由16位分频系数决定
寄存器配置:

ULCONn:行控制寄存器,主要控制数据帧格式
UCONn:时钟选择及其他控制
UFCONn:FIFO控制寄存器
UMCONn:模式控制位
UBRDIVn:16位波特率分频值
UTRSTATn:TX/RX状态寄存器 只读
UERSTATn:RX错误状态寄存器只读
UTXHn:发送缓冲寄存器 只写,以字节为单位
URXH0接收缓冲状态寄存器 只读,以字节为单位
UFSTATn:FIFO状态寄存器只读
UMSTAT0:

UART操作:
1.串口初始化
引脚的初始化,第二功能,电阻上拉
设置ULCONn寄存器:一般设为0x03,设置含义,八个数据位,一个停止位,无校验,正常操作模式
设置UCONn寄存器:一般设为0x0245,除了位[3:0],其他为都可以是默认设置,表示:发送和接收都是用“中断或查询方式”
设置UFCONn:设置为00,一般不使用FIFO
设置UMCONn:设置00,不使用流控
设置UBRDIV0具体设置,常用波特率115200

2.发送数据和接收数据
发送时,首先查询UTRSTATn[2]是否为1,若为1则表示f发送移位寄存器,发送缓冲器空闲,可以发送,UTXHn = C;
位[1]==1,在不使用FIFO的情况下,表示发送缓冲寄存器空(移位寄存器不一定空),此时也可以将数据写入缓冲器,前提是UCONn[9]设为1,中断响应才能使UTRSTATn[2]==1


接收时,若位[0]==1,则表示有缓冲区接收到数据

源码如下:

uart.c

#include"def.h"
#include"2440addr.h"
#include "option.h"
#include "uart.h"

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

static unsigned char CHANG_UART = 0;


void Uart_Init( U8 uart_number,int baud)
{
 int pclk,i;
 rGPHCON = 0x2afaaa;
 rGPHUP  = 0x7ff;
 pclk = PCLK;
 switch(uart_number)
 {
 case 0:
  {
   
   rULCON0 = 0x03;
   rUCON0 =  0x245;
   rUBRDIV0 = ( (int)(pclk/16./baud+0.5) -1 );   //Baud rate divisior register 0
   rUFCON0 = 0x0;   //UART channel 0 FIFO control register, FIFO disable
   rUMCON0 = 0x0;   //UART chaneel 0 MODEM control register, AFC disable
   CHANG_UART = 0;
   break;
  }
 case 1:
  {
   
   rULCON1 = 0x03;
   rUCON1 =  0x245;
   rUBRDIV1 = ( (int)(pclk/16./baud+0.5) -1 );   //Baud rate divisior register 0
   rUFCON1 = 0x0;   //UART channel 1FIFO control register, FIFO disable
   rUMCON1 = 0x0;   //UART chaneel 1 MODEM control register, AFC disable
   CHANG_UART = 1;
   break;
  
  }
 case 2:
  {
   
   rULCON2 = 0x03;
   rUCON2 =  0x245;
   rUBRDIV2 = ( (int)(pclk/16./baud+0.5) -1 );   //Baud rate divisior register 0
   rUFCON2 = 0x0;   //UART channel 2 FIFO control register, FIFO disable
   CHANG_UART = 2;
   break;
 
  }
  default: break;
  
  
 }
 for(i = 0; i < 100; i++);
 
}

//等待发送移位寄存器空
void Uart_TxEmpty(int ch)
{
 if(ch==0)
        while(!(rUTRSTAT0 & 0x4)); //Wait until tx shifter is empty.
         
    else if(ch==1)
        while(!(rUTRSTAT1 & 0x4)); //Wait until tx shifter is empty.
       
    else if(ch==2)
        while(!(rUTRSTAT2 & 0x4)); //Wait until tx shifter is empty. 


 
 //  rUTRSTAT0[2]==1,发射缓冲器空
}   
   
//接收串口一个字节数据,此时会先等待串口接收
char Uart_Getch(void)
{
    if (CHANG_UART == 0)
    {      
        while(!(rUTRSTAT0 & 0x1)); //Receive data ready
        return RdURXH0();
    }
    else if(CHANG_UART == 1)
    {      
        while(!(rUTRSTAT1 & 0x1)); //Receive data ready
        return RdURXH1();
    }
    else if(CHANG_UART == 2)
    {
        while(!(rUTRSTAT2 & 0x1)); //Receive data ready
        return RdURXH2();
    }
   
    return 0 ;
}

//直接得到串口键值,前提默认是串口已接收到数据
char Uart_GetKey(void)
{
    if(CHANG_UART==0)
    {      
        if(rUTRSTAT0 & 0x1)    //Receive data ready
            return RdURXH0();
        else
            return 0;
    }
    else if(CHANG_UART==1)
    {
        if(rUTRSTAT1 & 0x1)    //Receive data ready
            return RdURXH1();
        else
            return 0;
    }
    else if(CHANG_UART==2)
    {      
        if(rUTRSTAT2 & 0x1)    //Receive data ready
            return RdURXH2();
        else
            return 0;
    }   

 return 0 ;
}
//串口得到字符串
void Uart_GetString(char *string)
{
    char *string2 = string;
    char c;
    while((c = Uart_Getch())!='\r') //读取的是否为回车 ,若是回车,则读取结束
    {
        if(c=='\b')             //如果读取的是退格
        {
            if( (int)string2 < (int)string )   //且第一个字符不是退格
            {
                Uart_Printf("\b \b");
                string--;
            }
        }
        else
        {
            *string++ = c;  //将数据保存到string地址处
            Uart_SendByte(c); //并将此字符送PC显示
        }
    }
    *string='\0';    //字符串结束
    Uart_SendByte('\n');  //发送回车
}

//得到串口初始号
int Uart_GetIntNum(void)
{
    char str[30];
    char *string = str;
    int base     = 10;
    int minus    = 0;
    int result   = 0;
    int lastIndex;   
    int i;
   
    Uart_GetString(string);
   
    if(string[0]=='-')
    {
        minus = 1;
        string++;
    }
   
    if(string[0]=='0' && (string[1]=='x' || string[1]=='X'))
    {
        base    = 16;
        string += 2;
    }
   
    lastIndex = strlen(string) - 1;
   
    if(lastIndex<0)
        return -1;
   
    if(string[lastIndex]=='h' || string[lastIndex]=='H' )
    {
        base = 16;
        string[lastIndex] = 0;
        lastIndex--;
    }

    if(base==10)
    {
        result = atoi(string);
        result = minus ? (-1*result):result;
    }
    else
    {
        for(i=0;i<=lastIndex;i++)
        {
            if(isalpha(string[i]))
            {
                if(isupper(string[i]))
                    result = (result<<4) + string[i] - 'A' + 10;
                else
                    result = (result<<4) + string[i] - 'a' + 10;
            }
            else
                result = (result<<4) + string[i] - '0';
        }
        result = minus ? (-1*result):result;
    }
    return result;
}

//串口发送字节
void Uart_SendByte(char data)
{
 if(CHANG_UART == 0)
 {
  if(data=='\n')
  {
   while(!(rUTRSTAT0 & 0x2));
   // Delay(1);                 //because the slow response of hyper_terminal
   WrUTXH0('\r');
  }
  while(!(rUTRSTAT0 & 0x2));   //Wait until THR is empty.
  //  Delay(1);
  WrUTXH0(data);
 }
 else if(CHANG_UART == 1)
 {
  if(data=='\n')
  {
   while(!(rUTRSTAT1 & 0x2));
   //Delay(1);                 //because the slow response of hyper_terminal
   rUTXH1 = '\r';
  }
  while(!(rUTRSTAT1 & 0x2));   //Wait until THR is empty.
  //Delay(1);
  rUTXH1 = data;
 }  
 else if(CHANG_UART == 2)
 {
  if(data=='\n')
  {
   while(!(rUTRSTAT2 & 0x2));
   //Delay(1);                 //because the slow response of hyper_terminal
   rUTXH2 = '\r';
  }
  while(!(rUTRSTAT2 & 0x2));   //Wait until THR is empty.
  //Delay(1);
  rUTXH2 = data;
 }      
}

//串口发送数据串
void Uart_SendString(char *pt)
{
    while(*pt)
        Uart_SendByte(*pt++);

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

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

 

uart.h

#ifndef __uart_h__
#define __uart_h__

#include "def.h"

 

void Port_Init(void);

void Uart_TxEmpty(int ch);
void Uart_Init(U8 uart_number,int baud);
char Uart_Getch(void);
char Uart_GetKey(void);
void Uart_GetString(char *string); 
int  Uart_GetIntNum(void);
int Uart_GetIntNum_GJ(void) ;
void Uart_SendByte(char data);
void Uart_Printf(char *fmt,...);
void Uart_SendString(char *pt);

#endif



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值