004 uart裸机编程

在前面学习了clock设置的基础上,我们现在对uart配置。

最后达到的效果是我们可以使用printf函数来输出任意格式的数据,包括字符串等等。

 

第一步还是要从spec上面配置好uart的寄存器。

首先查看原理图,我们使用的是uart0。

接下来我们要设置GPH2/3为uart0端口,spec上面可以查到设置的寄存器。由于流控什么的都不需要设置,故我们只要设置uart使用的基本功能即可。这里设置bit[7:6] = 0b10,  bit[5:4] = 0b10

到这里uart mode设定成功。注意:这里设置完成后要记得拉高。因为uart的协议是从拉低开始。

接下来设置波特率的一些数据参数,baudrate、stop bit,parity bit等等。

 

首先我们要选择uart使用的是PCLK,而PCLK配置的时候使用的是50MHz的频率。

然后波特率设置为115200,S3C2440在这里有个计算波特率的公式:

UART CLK = 50MHz,baudrate = 115200可以得到 UBRDIVn = 26.

然后需要设置我们的串口接收数据mode,可以选择polling 或者interrupt两种。

接收和发送数据都采用IR or polling mode。

然后设置数据位,停止位,校验位

到这里,我们的uart性能设置结束。接下来要设置我们的收发数据。

在状态寄存器中查询收发shift register的数据标记位是否有置位/复位。

一旦有检测到要发送或者接收的数据,立马启动发送/接收机制。  

配置完成后就是上代码了:

//这里是基本的硬件配置。

/*
 * brief:init GPIO, set uart mode.
 *       config baudrate/parity/stop bit/start bit.
 * param: none
 * return: none
 * notice: none
 */
void uart_init(void)
{
    /*init GPIO, set uart mode*/
    GPHCON &= ~((3<<4) | (3<<6));  //clear bit[7:4]
    GPHCON |= ((2<<4) | (2<<6));   //config bit[7:4] = 2b1010, uart mode
    GPHUP &= ~((1<<2) | (1<<3));   //enable pullup
    
    /* config baudrate:
     * UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1
     * UBRDIVn = (50000000/115200*16) - 1 = (int)26.1 = 26
     */
    UCON0 = 0x5; //select interrupt or polling mode
    UBRDIV0 = 26; //config badurate 115200
     
    /*config uart data format 8N1*/
    ULCON0 = 0x3;
    
}

/*
 * brief: send data
 * param: c tobe send
 * return: none
 * notice: none
 */
int putchar(int c)
{
    /* UTRSTAT0 */
    /* UTXH0 */
    while(!(UTRSTAT0 & (1<<2)));
    UTXH0 = (unsigned char)c;
}

/*
 * brief: receive data
 * param: none
 * return: none
 * notice: none
 */
int getchar(void)
{
    /* UTRSTAT0 */
    /* URXH0 */
    while(!(UTRSTAT0 & (1<<0)));
    return URXH0;
}


/*
 * brief: send data
 * param: str tobe send
 * return: none
 * notice: none
 */
int puts(const char *s)
{
    while(*s)
    {
        putchar(*s);
        s++;
    }
}
 

//到这里我们开始重定向printf函数。

 
#include  "my_printf.h"


//==================================================================================================
typedef char *  va_list;
#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )
//#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_arg(ap,t)    ( *(t *)( ap=ap + _INTSIZEOF(t), ap- _INTSIZEOF(t)) )
#define va_end(ap)      ( ap = (va_list)0 )

//==================================================================================================
unsigned char hex_tab[]={'0','1','2','3','4','5','6','7',\
                         '8','9','a','b','c','d','e','f'};

static int outc(int c) 
{
    __out_putchar(c);
    return 0;
}

static int outs (const char *s)
{
    while (*s != '\0')    
        __out_putchar(*s++);
    return 0;
}

static int out_num(long n, int base,char lead,int maxwidth) 
{
    unsigned long m=0;
    char buf[MAX_NUMBER_BYTES], *s = buf + sizeof(buf);
    int count=0,i=0;
            

    *--s = '\0';
    
    if (n < 0){
        m = -n;
    }
    else{
        m = n;
    }
    
    do{
        *--s = hex_tab[m%base];
        count++;
    }while ((m /= base) != 0);
    
    if( maxwidth && count < maxwidth){
        for (i=maxwidth - count; i; i--)    
            *--s = lead;
}

    if (n < 0)
        *--s = '-';
    
    return outs(s);
}
   

/*reference :   int vprintf(const char *format, va_list ap); */
static int my_vprintf(const char *fmt, va_list ap) 
{
    char lead=' ';
    int  maxwidth=0;
    
     for(; *fmt != '\0'; fmt++)
     {
            if (*fmt != '%') {
                outc(*fmt);
                continue;
            }
            
        //format : %08d, %8d,%d,%u,%x,%f,%c,%s 
            fmt++;
        if(*fmt == '0'){
            lead = '0';
            fmt++;    
        }
             //For continue used %8u, code will chaos.
        lead=' ';
        maxwidth=0;
        
        while(*fmt >= '0' && *fmt <= '9'){
            maxwidth *=10;
            maxwidth += (*fmt - '0');
            fmt++;
        }
        
            switch (*fmt) {
        case 'd': out_num(va_arg(ap, int),          10,lead,maxwidth); break;
        case 'o': out_num(va_arg(ap, unsigned int),  8,lead,maxwidth); break;                
        case 'u': out_num(va_arg(ap, unsigned int), 10,lead,maxwidth); break;
        case 'x': out_num(va_arg(ap, unsigned int), 16,lead,maxwidth); break;
            case 'c': outc(va_arg(ap, int   )); break;        
            case 's': outs(va_arg(ap, char *)); break;                  
                
            default:  
                outc(*fmt);
                break;
            }
    }
    return 0;
}


//reference :  int printf(const char *format, ...); 
int printf(const char *fmt, ...) 
{
    va_list ap;

    va_start(ap, fmt);
    my_vprintf(fmt, ap);    
    va_end(ap);
    return 0;
}


int my_printf_test(void)
{
    printf("This is www.100ask.org   my_printf test\n\r") ;    
    printf("test char           =%c,%c\n\r", 'A','a') ;    
    printf("test decimal number =%d\n\r",    123456) ;
    printf("test decimal number =%d\n\r",    -123456) ;    
    printf("test hex     number =0x%x\n\r",  0x55aa55aa) ;    
    printf("test string         =%s\n\r",    "www.100ask.org") ;    
    printf("num=%08d\n\r",   12345);
    printf("num=%8d\n\r",    12345);
    printf("num=0x%08x\n\r", 0x12345);
    printf("num=0x%8x\n\r",  0x12345);
    printf("num=0x%02x\n\r", 0x1);
    printf("num=0x%2x\n\r",  0x1);

    printf("num=%05d\n\r", 0x1);
    printf("num=%5d\n\r",  0x1);

    return 0;
}

上面是主要的程序部分,完整代码我上传到资源里面。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值