关于串口

对于嵌入式设备的开发,刚开始好多设备都无法使用,由于无法获得程序的运行状态,调试程序需要花费好多时间和精力,因此串口对于嵌入式程序的调试的作用显而易见,当串口不能用时,可能只能用led的亮灭来略微指示程序的运行状态,有了串口后,就能获得更多的调试信息了。S3C6410的串口使用和其它设备都差不多,初始化配置串口后,就可以收发数据了。首先来看下芯片手册上的串口框图:

uart
串口信号线有发送数据信号线TXDn,接受数据信号线RXDn,如上图,这两根信号线分别连到了发送移位寄存器和接收移位寄存器,另外串口模块还包含了两个64Bytes的FIFO用来收发数据。除此外还有一个控制单元和波特率产生模块,相应的部分都被连到了系统的外围总线上面。

串口寄存器

先来看下相关的寄存器:
uart1
S3C6410有UART0,1,2,3四个串口,上面只列出了串口0的相关寄存器,其他几个串口的寄存器说明和这个一样,下面来详细的说下:

###### ULCONx: 串口数据格式设置 数据长度,停止位长度 ,奇偶校验位
ulcon

UCONx: 串口控制寄存器 选择时钟源,发送接收方式

ucon
ucon

UFCONx: FIFO控制寄存器 设置FIFO触发等级 使能

ufcon

UTRSTATx: 发送接收状态寄存器

utrstat

UERSTATx: 错误状态寄存器 帧错误,奇偶校验错误等

uerstat

UFSTATx: FIFO 状态寄存器

UFSTAT

UTXx: 发送数据寄存器 将要发送的数据丢给它

utx

URXx: 接收数据寄存器 从这个寄存器获得收到的数据

urx

UBRDIV : 波特率分频值寄存器

ubrdiv

UDIVSLOT: 波特率分频值小数部分(我起的名字。。。)

slot

串口初始化

串口初始化中需要完成的任务主要有以下几个:

###### 波特率设置
BAUD
波特率分频值设置:
DIV_VAL=(PCLK/(bps 16 ))-1
eg:
PCLK=66.5M=66500000
bps=115200 波特率
DIV_VAL=(66500000/115200
16)-1=35.078
UBRDIVn=35
小数部分为0.078
UDIVSLOTn中1的个数 除以16=0.078
UDIVSLOTn中1的个数 =1.248=1
根据上表,所以UDIVSLOTn的值为0x0080;

代码实现


#define UCON0      (*((volatile unsigned long *)0x7F005004))
#define UFCON0     (*((volatile unsigned long *)0x7F005008))
#define UMCON0     (*((volatile unsigned long *)0x7F00500C))
#define UTRSTAT0   (*((volatile unsigned long *)0x7F005010))
#define UFSTAT0    (*((volatile unsigned long *)0x7F005018))
#define UTXH0      (*((volatile unsigned char *)0x7F005020))
#大专栏  15.uboot study 串口初始化eta-keyword">define URXH0      (*((volatile unsigned char *)0x7F005024))
#define UBRDIV0    (*((volatile unsigned short *)0x7F005028))
#define UDIVSLOT0  (*((volatile unsigned short *)0x7F00502C))
#define GPACON     (*((volatile unsigned long *)0x7F008000))
#define PCLK 66500000
#define BOUD 115200

void uart_init(void)
{
    GPACON &= ~0xff;
    GPACON |= 0x22;

    
    ULCON0 = 0x3;  /* 数据位:8, 无较验, 停止位: 1, 8n1 */
    UCON0  = 0x5;  /* 使能UART发送、接收 */
    UFCON0 = 0x01; /* FIFO ENABLE */

    UMCON0 = 0;

    /* 波特率 */
    /* DIV_VAL = (PCLK / (bps x 16 ) ) - 1 
     * bps = 115200
     * DIV_VAL = (66000000 / (115200 x 16 ) ) - 1 
     *         = 35.08
     */
    UBRDIV0 = (int)(PCLK/(BOUD*16)-1);

    /* x/16 = 0.08
     * x = 1
     */
    UDIVSLOT0 = 0x1;

}

void putc(unsigned char c)
{
    while (UFSTAT0 & (1<<14)); /* 如果TX FIFO满,等待 */
    UTXH0 = c;                         /* 写数据 */
}


unsigned char getc(void)
{
    unsigned char ret;
    while ((UFSTAT0 & 0x7f) == 0);  /* 如果RX FIFO空,等待 */
    ret = URXH0;                   /* 取数据 */
    if((ret == 0x0d) || (ret == 0x0a))
    {
        putc(0x0d);
        putc(0x0a);
    }
    else
    {
        putc(ret);
    }

        return ret;
}


void uart_send_string(char *str)
{
    while(*str)
    {
        putc(*str++);    
    }
    putc(0x0d);
    putc(0x0a);    
}



转载本站原创内容请注明作者砦龑堃及出处http://ykzhai.top/2016/08/15/开发/嵌入式/s3c6410/15-uboot-study-串口初始化/
 
  • 相关阅读:
    调整vmware虚拟机硬盘空间的方法
    微型网络IP转换工具
    初观线程(1)
    Linux逻辑盘卷管理LVM详解(转载)
    微型IP转换工具V1.0升级版
    android 模拟器一键root
    android自用小软件"小毛毛起床啦!“<1>
    很久没更新博客了,写下最近的情况
    解决skype突然无法启动的问题(原创)
    OllyDBG处理C++ EH exception异常
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12147646.html
  • Copyright © 2020-2023  润新知