UART通信协议

嵌入式

UART(Universal Asynchronous Receiver Transmitter:通用异步收发器),UART总线是异步串口,因此一般比前两种同步串口的结构要复杂很多,一般由波特率产生器(产生的波特率等于传输波特率的16倍)、UART接收器、UART发送器组成,硬件上由两根线,一根用于发送,一根用于接收(rxd,txd)。

显然,如果用通用IO口模拟UART总线,则需一个输入口,一个输出口。

UART是用于控制计算机与串行设备的芯片。有一点要注意的是,它提供了数据终端设备接口,这样计算机就可以和调制解调器或其它使用RS-232C接口的串行设备通信了。作为接口的一部分,UART还提供以下功能:

将由计算机内部传送过来的并行数据转换为输出的串行数据流;

将计算机外部来的串行数据转换为字节,供计算机内部使用并行数据的器件使用;

在输出的串行数据流中加入奇偶校验位,并对从外部接收的数据流进行奇偶校验;

在输出数据流中加入启停标记,并从接收数据流中删除启停标记;

处理由键盘或鼠标发出的中断信号(键盘和鼠票也是串行设备);

可以处理计算机与外部串行设备的同步管理问题;


异步串口通信协议,工作原理是将传输数据的每个字符以串行方式一位接一位的传输。如下图:

其中每一位(bit)的意义如下:

   起始位:先发出一个逻辑“0”的信号,表示传输字符的开始。

   数据位:紧跟起始位之后。数据位的个数可以是4、5、6、7、8等,构成一个字符。通常采用ASCII码。从最低位开始传送,靠时钟来定位。

   奇偶校验位:数据位加上这一位后(跟在数据位尾部),使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验数据传送的正确性。

   停止位:它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平(逻辑“1”)。

   空闲位:处于逻辑“1”状态,表示当前线路上没有数据的传送。

   波特率:是衡量数据传输速率的指针。表示为每秒钟传送的二进制位数(bit数)。例如资料传送速率为120字符/秒,而每一个字符为10位,则其传送的波特率为:

                                            10×120   =  1200字符/秒=1200波特。

 以上的数据位、奇偶校验位、波特率等均可以在COM接口中设置。也可以在代码中对UART寄存器的各位进行设置,UART

寄存器的各位所代表的含义如下:

下面通过几个小程序,了解UART通信协议进行数据传输的过程:

#include "2410lib.h"

/*********************************************************************************************
* name:		uart0_test
* func:		uart test function
* para:		none
* ret:		none
* modify:
* comment:		
*********************************************************************************************/
void uart0_test()
{
	char cInput[256];
	UINT8T ucInNo=0;
	char c;
	uart_init(0,115200,0); //define the baud rate
	uart_printf("\n UART0 Communication Test Example\n");	
	uart_printf(" Please input words, then press Enter:\n");
#ifdef BOARDTEST	
	sprintf(&cInput, "Type via UART0 to test.");
	print_lcd(195,170,0x1c,&cInput);	
#endif
	uart_printf(" ");
	g_nKeyPress = 1;
	while(g_nKeyPress==1)			// only for board test to exit
	{
		c=uart_getch();
		//uart_sendbyte(c);
		
		uart_printf("%c",c);
		if(c!='\r')
			cInput[ucInNo++]=c;
		else
		{
			cInput[ucInNo]='\0';
			break;
		}
	}
	delay(1000);	

	uart_printf(" \nThe words that you input are: %s\n",cInput);		
	uart_printf(" end.\n"); 
}

void Main(int argc,char **argv)
{
	
	sys_init();			// Initial s3c2410's Clock, MMU, Interrupt,Port and UART     
	
	while(1)
	{
		uart0_test();
	}
	for(;;);

}
在这里我们使用 uart_init 函数便完成了UART各个位的设置,现在来看看uart_init在系统中是如何定义的:

void uart_init(int nMainClk, int nBaud, int nChannel)
{
    int i;
    
    if(nMainClk == 0)
    nMainClk    = PCLK;
    
    switch (nChannel)
    {
    	case UART0: 
		rUFCON0 = 0x0;   //UART channel 0 FIFO control register, FIFO disable
		rUMCON0 = 0x0;   //UART chaneel 0 MODEM control register, AFC disable
		rULCON0 = 0x3;   //Line control register : Normal,No parity,1 stop,8 bits
		// [10]       [9]     [8]     [7]          [6]      [5]        [4]         [3:2]          [1:0]
		// Clock Sel, Tx Int, Rx Int, Rx Time Out, Rx err,  Loop-back, Send break, Transmit Mode, Receive Mode
		// 0          1       0,      0            1        0          0,          01             01
		// PCLK       Level   Pulse   Disable      Generate Normal     Normal      Interrupt or Polling
		rUCON0  = 0x245;							// Control register
		//rUBRDIV0=( (int)(nMainClk/16./nBaud) -1 );	// Baud rate divisior register 0
		rUBRDIV0=( (int)(nMainClk/16./nBaud+0.5) -1 );	// Baud rate divisior register 0    
		break;
			
	case UART1: 
		rUFCON1 = 0x0;   //UART channel 1 FIFO control register, FIFO disable
		rUMCON1 = 0x0;   //UART chaneel 1 MODEM control register, AFC disable
		rULCON1 = 0x3;
		rUCON1  = 0x245;
		rUBRDIV1=( (int)(nMainClk/16./nBaud) -1 );
		break;
			
    	case UART2: 
		rULCON2 = 0x3;
		rUCON2  = 0x245;
		rUBRDIV2=( (int)(nMainClk/16./nBaud) -1 );    
		rUFCON2 = 0x0;   //UART channel 2 FIFO control register, FIFO disable
		break;
			
	default:
		break;
	}

    for(i=0;i<100;i++);
    delay(0);
}

  UART0 --- UART2 便是开发板为我们提供的三个寄存器,通过rUFCON、rUMCON、rULCON、rUCON、rUBRDIV 等引脚的赋值完成UART寄存器的设置。

文章如需转载请注明:转载自:TTF的家园
« 上一篇下一篇 »