S5PV210 串口

S5PV210 处理器提供了 4 个独立的异步串行 I/O 端口 (或通道) , 每个端口都可以工作于中断或者 DMA 模式,也就是说 UART 控制器可以通过发出中断或 DMA

请求以便在 CPU 和 UART 间传输数据。S5PV210 的 UART 波特率最大可达 3Mbps。每个 UART 通道都有 2 种 FIFO (缓存区),一种是发送 FIFO,另一种是接收 FIFO,而

通道 0 的 FIFO 深度是 256 bytes,通道 1 的 FIFO 深度是 64 bytes,通道 2 和通道 3 的 FIFO 深度都是 16 bytes发送数据时, CPU 先将数据写入发送 FIFO 中,然后 UART 控

制器会自动将 FIFO的数据复制到“transmit shifter”,它按照设定的格式将数据一位一位地发送到 TxDn 数据线上。接收数据时, “receive shifter”将 RxDn 数据线上的数据一

位一位接收进来,然后复制到接收 FIFO 中,CPU 即可从中读取数据。每一个 UART 都包含四个主要部分,分别是波特率发生器、控制单元、发送器和接收器。发送器中包含

一个移位器和一个发送 FIFO 寄存器,接收器中同样包含一个移位器和一个接收 FIFO 寄存器。

UART波特率的计算

公式·1:DIV_VAL = (SCLK_UART/(bps * 16)) – 1

公式2:DIV_VAL = UBRDIVn + (UDIVSLOTn 值为 1 的个数) / 16;
       DIV_VAL = ( PCLK / (bps * 16)) - 1;

例如:波特率 = 115200 bps,PCLK = 40MHz

DIV_VAL = (40000000/(115200 * 16)) -1
= 21.7 – 1
= 20
UBRDIVn = 20 (取 DIV_VAL 的整数部分)

UART 操作的一般步骤

①  设置所涉及引脚为 UART 功能
②  设置波特率、传输格式(如:数据位、停止位、校验位、流控)
③  UART 通道的工作模式(查询/中断/DMA 模式)
④  等待发送/接收数据的完成

//uart.h
#ifndef _UART_H_
#define _UART_H_

/*UART0 Pins To ARM*/
#define  GPA0CON  	(*(volatile unsigned int *) 0xE0200000)

/*UART0 Pins*/
#define  ULCON0  	  	(*(volatile unsigned int *) 0xE2900000)
#define  UCON0  	  	(*(volatile unsigned int *) 0xE2900004)
#define  UFCON0  		(*(volatile unsigned int *) 0xE2900008)
#define  UMCON0  		(*(volatile unsigned int *) 0xE290000c)
#define  UTRSTAT0  		(*(volatile unsigned int *) 0xE2900010)
#define  UTXH0  		(*(volatile unsigned char*) 0xE2900020)
#define  URXH0  		(*(volatile unsigned char*) 0xE2900024)
#define  UBRDIV0 		(*(volatile unsigned int *) 0xE2900028)
#define  UDIVSLOT0  (*(volatile unsigned int *) 0xE290002c)

void uart_init();
void uart0_sendbyte(unsigned char c);
unsigned char uart0_getbyte();

#endif //_UART_H_
void uart_init()
{
    /*uart_init()主要做了以下几件事:
    第一:设置 UART0 对应 GPIO 引脚为发送/接收功能。
    第二:设置数据帧格式。
    第三:选择时钟输入源,设置发送接收模式。
    第四:禁止 FIFO 功能。
    第五:无流控。
    第六:由波特率计算分频系数。*/
	/*  配置引脚
	 *	GPA0CON[1] = UART_0_TXD
	 *	GPA0CON[0] = UART_0_RXD
	 */
	GPA0CON = (0x2 << 4)|(0x2 << 0);

	/*
	 *	设置UART0的数据格式为:8个数据位,
	 *	一个停止位,无奇偶校验
	 */
	ULCON0 = (0 << 3)|(0 << 2)|(0x3 << 0);

	/*
	 *	设置UART0的时钟源为PCLK_PSYS = 66.7MHz,由时钟分频器产生
	 *	发送、接收均采用查询方式
	 */
	UCON0 = (0 << 10)|(0x1 << 2)|(0x1 << 0);

	/*  禁止UART0  FIFO!!!!!!!!!!!
	 *  这里如果使能的话实验效果差别相当大
	 */
	UFCON0 = (0 << 0);

	/* 无流控 */
	UMCON0 = (0 << 4);

	/*
	 *	波特率 = 115200bps
	 *	分频系数 = ( PCLK_PSYS / (Baud * 16)) - 1;
	 *	分频系数 = UBRDIVn寄存器的值 + (UDIVSLOTn寄存器中1的个数) / 16;
	 *	For example:
	 *		PCLKP =66.7MHz,波特率设为115200
	 *		分频系数 = ( 66700000 / (115200 * 16)) - 1 = 35.2;
	 *		所以:UBRDIVn寄存器的值 = 35;
	 *		所以UDIVSLOTn寄存器的值的1的个数为2,
	 *		根据S5PV210手册p880可知 UDIVSLOTn= 0x808;
	 */

	UBRDIV0 = 0x23;
	UDIVSLOT0 = 0x808;
}

void uart0_sendbyte(unsigned char c)
{
	/*直到发送缓存为空,不为空时一直等待*/
	while(!(UTRSTAT0 & (1 << 2)));

	/*向UTXH0 寄存器中写入数据,UART会自动将它发送出去*/
	UTXH0 = c;
}

unsigned char uart0_getbyte()
{
	/*直到发送缓存不为空,为空时一直等待*/
	while(!(UTRSTAT0 & (1 << 0)));

	/*直接读取URXH0 寄存器,即可获得接收到的数据*/
	return URXH0;
}



你可能感兴趣的:(嵌入式)