S3C2451_uart_ARM 직렬 작업

33778 단어 ARM
제가 쓴 S3C2451의 UART 멀티 인터페이스 초기화 프로그램을 보여드리겠습니다.
설정하고자 하는 직렬 번호, 포트 속도, 비트 비트 너비와 정지 위치를 입력하면 직렬 포트 속도와 수신 문자, 발송 문자열, 직렬 인터럽트 등 함수를 자동으로 설정합니다. 잘못된 점이 있으면 가르쳐 주십시오!
/*UART*/
#define     ULCON0      (*(volatile unsigned long *)0x50000000)
#define     ULCON1      (*(volatile unsigned long *)0x50004000)
#define     ULCON2      (*(volatile unsigned long *)0x50008000)
#define     ULCON3      (*(volatile unsigned long *)0x5000c000) 

#define     UCON0       (*(volatile unsigned long *)0x50000004)
#define     UCON1       (*(volatile unsigned long *)0x50004004)
#define     UCON2       (*(volatile unsigned long *)0x50008004)
#define     UCON3       (*(volatile unsigned long *)0x5000c004)

#define     UFCON0      (*(volatile unsigned long *)0x50000008)
#define     UFCON1      (*(volatile unsigned long *)0x50004008)
#define     UFCON2      (*(volatile unsigned long *)0x50008008)
#define     UFCON3      (*(volatile unsigned long *)0x5000c008)

#define     UMCON0      (*(volatile unsigned long *)0x5000000c)
#define     UMCON1      (*(volatile unsigned long *)0x5000400c)
#define     UMCON2      (*(volatile unsigned long *)0x5000800c)

#define     UTRSTAT0    (*(volatile unsigned long *)0x50000010)
#define     UTRSTAT1    (*(volatile unsigned long *)0x50004010)
#define     UTRSTAT2    (*(volatile unsigned long *)0x50008010)
#define     UTRSTAT3    (*(volatile unsigned long *)0x5000c010)

#define     UERSTAT0    (*(volatile unsigned long *)0x50000014)
#define     UERSTAT1    (*(volatile unsigned long *)0x50004014)
#define     UERSTAT2    (*(volatile unsigned long *)0x50008014)
#define     UERSTAT3    (*(volatile unsigned long *)0x5000c014)

#define     UFSTAT0     (*(volatile unsigned long *)0x50000018)
#define     UFSTAT1     (*(volatile unsigned long *)0x50004018)
#define     UFSTAT2     (*(volatile unsigned long *)0x50008018)
#define     UFSTAT3     (*(volatile unsigned long *)0x5000c018)

#define     UMSTAT0     (*(volatile unsigned long *)0x5000001c)
#define     UMSTAT1     (*(volatile unsigned long *)0x5000401c)
#define     UMSTAT2     (*(volatile unsigned long *)0x5000801c)

#define     UTXH0       (*(volatile unsigned long *)0x50000020)
#define     UTXH1       (*(volatile unsigned long *)0x50004020)
#define     UTXH2       (*(volatile unsigned long *)0x50008020)
#define     UTXH3       (*(volatile unsigned long *)0x5000c020)

#define     URXH0       (*(volatile unsigned long *)0x50000024)
#define     URXH1       (*(volatile unsigned long *)0x50004024)
#define     URXH2       (*(volatile unsigned long *)0x50008024)
#define     URXH3       (*(volatile unsigned long *)0x5000c024)

#define     UBRDIV0     (*(volatile unsigned long *)0x50000028)
#define     UBRDIV1     (*(volatile unsigned long *)0x50004028)
#define     UBRDIV2     (*(volatile unsigned long *)0x50008028)
#define     UBRDIV3     (*(volatile unsigned long *)0x5000c028)

#define     UDIVSLOT0   (*(volatile unsigned long *)0x5000002c)
#define     UDIVSLOT1   (*(volatile unsigned long *)0x5000402c)
#define     UDIVSLOT2   (*(volatile unsigned long *)0x5000802c)
#define     UDIVSLOT3   (*(volatile unsigned long *)0x5000c02c)
/*       */
typedef enum
{
    UART0 = 0,
    UART1,
    UART2,
    UART3

}UART_TyPeDef;

/*        */
typedef enum
{
    DATA_WIDTH_5BIT = 0,
    DATA_WIDTH_6BIT,
    DATA_WIDTH_7BIT,
    DATA_WIDTH_8BIT
}DATA_WTDTH_TyPeDef;

/*       */
typedef enum
{
    STOP_BIT0 = 0,
    STOP_BIT1
}STOP_BIT_TyPeDef;
#ifndef _TYPEDEF_H_
#define _TYPEDEF_H_

#define U32 unsigned int
#define U16 unsigned short
#define S32 int
#define S16 short int
#define U8  unsigned char
#define S8  char

#define TRUE   1
#define FALSE  0

#endif
/*========================================================
 function :       
 arguments:ART_TyPeDef uartx   
            DATA_WTDTH_TyPeDef bit_w        
            STOP_BIT_TyPeDef stop   
            ========================================================*/
void uart_init(UART_TyPeDef uartx, U32 bps, DATA_WTDTH_TyPeDef bit_w, STOP_BIT_TyPeDef stop)
{
    float femp; //   DIV_VAL    
    switch(uartx)
    {
        case UART0:
        {
            ULCON0 &= ~0x3;  //      (    )
            switch (bit_w)
            {
                //          5、6、7、8bit
                case DATA_WIDTH_5BIT: ULCON0 |= 0x00;break;
                case DATA_WIDTH_6BIT: ULCON0 |= 0x01;break;
                case DATA_WIDTH_7BIT: ULCON0 |= 0x02;break;
                case DATA_WIDTH_8BIT: ULCON0 |= 0x03;break;
            }
            ULCON0 &= ~0x4;  //     
            if (stop == STOP_BIT1)
            {
                ULCON0 |= 0x4;
            }
            //      
            // HCLK    AHB          
            // PCLK    APB          
            // UART0123  APB 
            // DIV_VAL = (PCLK / (bps x 16 ) ) - 1 = (66000000/(115200x16))-1 = 34.807
            // DIV_VAL = 34.807
            UBRDIV0 = (int)((66000000/(bps * 16)) - 1);
            femp = (float)(66000000/(float)(bps * 16)) - 1 - UBRDIV0;
            VOIDSET(UART0, femp);
            break;
        }
        case UART1:
        {
            ULCON1 &= ~0x3;  //Çå¿Õ×îµÍÁ½Î»£¨Êý¾Ý¿í¶È£©
            switch (bit_w)
            {
                //          5、6、7、8bit
                case DATA_WIDTH_5BIT: ULCON1 |= 0x00;break;
                case DATA_WIDTH_6BIT: ULCON1 |= 0x01;break;
                case DATA_WIDTH_7BIT: ULCON1 |= 0x02;break;
                case DATA_WIDTH_8BIT: ULCON1 |= 0x03;break;
            }
            ULCON1 &= ~0x4;  //Çå³ýֹͣλ£¬Ê¹ÆäΪ0
            if (stop == STOP_BIT1)
            {
                ULCON1 |= 0x4;
            }
            UBRDIV1 = (int)((66000000/(bps * 16)) - 1);
            femp = (float)(66000000/(float)(bps * 16)) - 1 - UBRDIV1;
            VOIDSET(UART1, femp);
            break;
        }
        case UART2:
        {
            ULCON2 &= ~0x3;  
            switch (bit_w)
            {
                //          5、6、7、8bit
                case DATA_WIDTH_5BIT: ULCON2 |= 0x00;break;
                case DATA_WIDTH_6BIT: ULCON2 |= 0x01;break;
                case DATA_WIDTH_7BIT: ULCON2 |= 0x02;break;
                case DATA_WIDTH_8BIT: ULCON2 |= 0x03;break;
            }
            ULCON2 &= ~0x4;  //     ,   0
            if (stop == STOP_BIT1)
            {
                ULCON2 |= 0x4;
            }
            UBRDIV2 = (int)((66000000/(bps * 16)) - 1);
            femp = (float)(66000000/(float)(bps * 16)) - 1 - UBRDIV2;
            VOIDSET(UART2, femp);
            break;
        }
        case UART3:
        {
            ULCON3 &= ~0x3;  //Çå¿Õ×îµÍÁ½Î»£¨Êý¾Ý¿í¶È£©
            switch (bit_w)
            {
                //          5、6、7、8bit
                case DATA_WIDTH_5BIT: ULCON3 |= 0x00;break;
                case DATA_WIDTH_6BIT: ULCON3 |= 0x01;break;
                case DATA_WIDTH_7BIT: ULCON3 |= 0x02;break;
                case DATA_WIDTH_8BIT: ULCON3 |= 0x03;break;
            }
            ULCON3 &= ~0x4;
            if (stop == STOP_BIT1)
            {
                ULCON3 |= 0x4;
            }
            UBRDIV3 = (int)((66000000/(bps * 16)) - 1);
            femp = (float)(66000000/(float)(bps * 16)) - 1 - UBRDIV3;
            VOIDSET(UART3, femp);
            break;
        }
    }
}

/*====================================================================
 function:  DIV_VAL         UDIVSLOT
 arguments:ART_TyPeDef uartx   
            femp:   Floating point part

====================================================================*/
void VOIDSET(UART_TyPeDef uartx, float femp)
{
    S32 i;
    float absnum = 0.0;
    float min = femp;
    float src[16] = {0,0.0625,0.125,0.18175,0.25,0.3125,0.375,0.4375,0.5,0.5625,0.625,0.6875,0.75,0.8125,0.875,0.9375};
    //   femp        
    for (i = 0; i <= 15; i++)
    {
        absnum = src[i] - femp;
        if (absnum < 0) 
        {
            absnum = -absnum;
        }
        if (absnum < min)
        {
            min = absnum;
        }
    }
    //                
    for (i = 0; i <= 15; i++)
    {
        absnum = src[i] - femp;
        if (absnum < 0) 
        {
            absnum = -absnum;
        }
        if (absnum == min)
        {
            break;
        }
    }
    //       UDIVSLOT
    switch(uartx)
    {
        case UART0:
        {
            switch(i)
            { 
                case 0:UDIVSLOT0 = 0x0000;break;
                case 1:UDIVSLOT0 = 0x0080;break;
                case 2:UDIVSLOT0 = 0x0808;break;
                case 3:UDIVSLOT0 = 0x0888;break;
                case 4:UDIVSLOT0 = 0x2222;break;
                case 5:UDIVSLOT0 = 0x4924;break;
                case 6:UDIVSLOT0 = 0x4A52;break;
                case 7:UDIVSLOT0 = 0x54AA;break;
                case 8:UDIVSLOT0 = 0x5555;break;
                case 9:UDIVSLOT0 = 0xD555;break;
                case 10:UDIVSLOT0 = 0xD5D5;break;
                case 11:UDIVSLOT0 = 0xDDD5;break;
                case 12:UDIVSLOT0 = 0xDDDD;break;
                case 13:UDIVSLOT0 = 0xDFDD;break;
                case 14:UDIVSLOT0 = 0xDFDF;break;
                case 15:UDIVSLOT0 = 0xFFDF;break;               
                default:break;       
            }

            break;
        }
        case UART1:
        {
            switch(i)
            { 
                case 0:UDIVSLOT1 = 0x0000;break;
                case 1:UDIVSLOT1 = 0x0080;break;
                case 2:UDIVSLOT1 = 0x0808;break;
                case 3:UDIVSLOT1 = 0x0888;break;
                case 4:UDIVSLOT1 = 0x2222;break;
                case 5:UDIVSLOT1 = 0x4924;break;
                case 6:UDIVSLOT1 = 0x4A52;break;
                case 7:UDIVSLOT1 = 0x54AA;break;
                case 8:UDIVSLOT1 = 0x5555;break;
                case 9:UDIVSLOT1 = 0xD555;break;
                case 10:UDIVSLOT1 = 0xD5D5;break;
                case 11:UDIVSLOT1 = 0xDDD5;break;
                case 12:UDIVSLOT1 = 0xDDDD;break;
                case 13:UDIVSLOT1 = 0xDFDD;break;
                case 14:UDIVSLOT1 = 0xDFDF;break;
                case 15:UDIVSLOT1 = 0xFFDF;break;               
                default:break;      
            }
            break;
        }
        case UART2:
        {
            switch(i)
            { 
                case 0:UDIVSLOT2 = 0x0000;break;
                case 1:UDIVSLOT2 = 0x0080;break;
                case 2:UDIVSLOT2 = 0x0808;break;
                case 3:UDIVSLOT2 = 0x0888;break;
                case 4:UDIVSLOT2 = 0x2222;break;
                case 5:UDIVSLOT2 = 0x4924;break;
                case 6:UDIVSLOT2 = 0x4A52;break;
                case 7:UDIVSLOT2 = 0x54AA;break;
                case 8:UDIVSLOT2 = 0x5555;break;
                case 9:UDIVSLOT2 = 0xD555;break;
                case 10:UDIVSLOT2 = 0xD5D5;break;
                case 11:UDIVSLOT2 = 0xDDD5;break;
                case 12:UDIVSLOT2 = 0xDDDD;break;
                case 13:UDIVSLOT2 = 0xDFDD;break;
                case 14:UDIVSLOT2 = 0xDFDF;break;
                case 15:UDIVSLOT2 = 0xFFDF;break;
                default:break;                      
            }
            break;
        }
        case UART3:
        {
            switch(i)
            { 
                case 0:UDIVSLOT3 = 0x0000;break;
                case 1:UDIVSLOT3 = 0x0080;break;
                case 2:UDIVSLOT3 = 0x0808;break;
                case 3:UDIVSLOT3 = 0x0888;break;
                case 4:UDIVSLOT3 = 0x2222;break;
                case 5:UDIVSLOT3 = 0x4924;break;
                case 6:UDIVSLOT3 = 0x4A52;break;
                case 7:UDIVSLOT3 = 0x54AA;break;
                case 8:UDIVSLOT3 = 0x5555;break;
                case 9:UDIVSLOT3 = 0xD555;break;
                case 10:UDIVSLOT3 = 0xD5D5;break;
                case 11:UDIVSLOT3 = 0xDDD5;break;
                case 12:UDIVSLOT3 = 0xDDDD;break;
                case 13:UDIVSLOT3 = 0xDFDD;break;
                case 14:UDIVSLOT3 = 0xDFDF;break;
                case 15:UDIVSLOT3 = 0xFFDF;break;
                default:break;      
            }
            break;
        }
        default:
        {
            break;
        }
    }       
}
void Uart_SendData(U8 data)
{
    UTXH0 = data;
    while( (UTRSTAT0&(1<<2)) == 0); 

}

void UART_SendDataBuf(unsigned char *dat,unsigned int len)
{
    unsigned char i;
    for(i=0;ivoid)
{
    //while( (UTRSTAT0&(1<<0)) == 0);
    return (URXH0);
}

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

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

    Uart_SendString(string); //default send from uart0
}


void Uart_SendString(char *s)
{
    while(*s)
    {
        Uart_SendData(*s++);
    }
}
void UART_Interrupt_IRQInit(UART_TypeDef UARTx,U32 addr)
{
        switch(UARTx)
        {
            case UART0: pISR_UART0=addr;break;
            case UART1: pISR_UART1=addr;break;
            case UART2: pISR_UART2=addr;break;
            default:
                break;
        }
}

좋은 웹페이지 즐겨찾기