zoukankan      html  css  js  c++  java
  • 第11课.串口(UART)的使用

    1.UART连线图

    S3C2440有3个独立通道的UART
    

    2.数据传输流程

    1.平时数据线处于“空闲”状态(1状态)
    2.当要发送数据时,UART改变TxD数据线的状态(变为0状态),并维持1位的时间,这样接收方检测到开始位后,在等待1.5位的时间就开始一位一位的检测数据线的状态得到所传输的数据
    3.UART一帧中可以有5,6,7或8位的数据,发送方一位一位的改变数据线的状态将它们发送出去。首先发送最低位
    4.如果使用校验功能,UART在发送完数据位后,还要发送1个校验位。有两种校验方法:奇校验,偶校验——数据位连同校验位,“1”的数目等于奇数或偶数
    5.最后,发送停止位。数据线恢复到“空闲”状态(1状态)。停止位的长度有3种:1位,1.5位,2位
    

    3.S3C2440中UART的工作过程

    S3C2440UART的FIFO深度为64。发送数据时,CPU先将数据写入发送FIFO中,然后UART会自动将FIFO中的数据复制到“发送移位器”中,发送移位器将数据一位一位的发送到TxDn数据线上(根据设定的格式,插入开始位,校验位和停止位)。接收数据时,“接收移位器”将RxDn数据线上的数据一位一位接收进来,然后复制到接收FIFO中,CPU即可从中读取数据。
    

    4.寄存器讲解

    UBRDIVn寄存器:设置波特率

    UBRDIVn = (int)(UART时钟 / (波特率 * 16)) - 1
    eg:
        UBRDIVn = (int)(50000000 / (115200 * 16)) - 1
                = 26
    

    ULCONn寄存器:设置传输格式

    UCONn寄存器:选择时钟源,设置UART的中断方式等。


    UFCONn寄存器

    UFCONn寄存器用于设置是否使用FIFO,设置各FIFO的触触发阈值,即发送FIFO中有多少个数据时产生中断,接收FIFO中有多少个数据时产生中断。并可以通过设置UFCONn寄存器来复位各个FIFO
    

    UFSTATn寄存器

    读取UFSTAT寄存器可以知道各个FIFO是否已经满,其中有多少个数据。
    不使用FIFO时,可以认为FIFO的深度为1,使用FIFO时S3C2440的深度为64
    

    UTRSTATn寄存器

    UTRSTATn寄存器用来表示数据是否已经发送完毕,是否已经接受到数据。
    

    UERSTATn寄存器

    用来表示各种错误是否发生,位[0]~[3]为1时分别表示溢出错误,校验错误,帧错误,检测到“break”信号,读取这个寄存器时,他会自动清0
    

    UTXHn

    CPU将数据写入这个寄存器,UART即会将它保存到缓冲区去,并自动发出
    

    URXHn

    当UART接收到数据时,CPU读取这个寄存器,即可获得数据
    

    UMCONn寄存器和UMSTATn寄存器

    这两类寄存器用于流量控制,这里不介绍
    

    5.硬件接线图

    6.代码编写

    uart.h

    #ifndef _UART_H
    #define _UART_H
    
    void uart0_init();
    int putchar(int c);
    int getchar(void);
    int puts(const char *s);
    
    #endif
    

    uart.c

    #include "s3c2440_soc.h"
    
    /*	115200, 8n1
     *	8: 数据位
     *	n: 没有校验位
     *  1: 停止位
     */
    void uart0_init()
    {
    	/*	设置引脚	*/
    	GPHCON &= ~((3<<4) | (3<<6));
    	GPHCON |= ((2<<4) | (2<<6));
    
    	/*	设置上拉	
    	 *	因为uart传输协议要求开始空闲为高电平
    	 */
    	GPHUP &= ((1<<2) | (1<<3));
    	
    	/*	设置波特率	*/
    	/*  UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1
    	 *  UART clock = 50M
    	 *  UBRDIVn = (int)( 50000000 / ( 115200 x 16) ) –1 = 26
    	 */
    	UCON0 = 0x00000005;		/*	PCLK,中断/查询模式	*/
    	UBRDIV0 = 26;
    		
    	/*	设置数据格式	*/
    	ULCON0 = 0x00000003;
    }
    
    int putchar(int c)
    {
    	while(!(UTRSTAT0 & (1<<2)));
    	UTXH0 = (unsigned char)c;
    }
    
    int getchar(void)
    {
    	while(!(UTRSTAT0 & (1<<0)));
    	return URXH0;
    }
    
    int puts(const char *s)
    {
    	while(*s)
    	{
    		putchar(*s);
    		s++;
    	}
    }
    

    main.c

    #include "s3c2440_soc.h"
    #include "uart.h"
    
    main(int argc, char **argv)
    {
    	unsigned char c;
    	uart0_init();
    	puts("Hello world
    
    ");
    
    	while(1)
    	{
    		c = getchar();
    		if(c == '
    ')
    		{
    			putchar('
    ');
    		}
    		if(c == '
    ')
    		{
    			putchar('
    ');
    		}
    
    		putchar(c);
    	}
    
    	return 0;
    }
  • 相关阅读:
    springmvc 处理静态资源
    springmvc jsp 获取 上下文
    springmvc 如何设置首页
    servlet-mapping url-pattern / 和 /*区别
    nginx支持php
    openresty 变量
    git tag用法
    python 导入模块,__init__.py 的作用
    python 转码问题
    python装饰器
  • 原文地址:https://www.cnblogs.com/huangdengtao/p/12103149.html
Copyright © 2011-2022 走看看