第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\n\r");

	while(1)
	{
		c = getchar();
		if(c == '\r')
		{
			putchar('\n');
		}
		if(c == '\n')
		{
			putchar('\r');
		}

		putchar(c);
	}

	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM