1. 程式人生 > >ARM串列埠(UART)的使用 (S3C2440)

ARM串列埠(UART)的使用 (S3C2440)

UART概述 通用非同步收發器簡稱UART(Universal Asynchronous Receiver and Transmitter) 工作方式為:序列、全雙工。 只需3根線:TXD(傳送資料)、RXD(接收資料)、GND。

資料傳輸流程:

  1. 原來是高電平(空閒狀態)
  2. 傳送方拉低電平,保持1bit時間,為起始位。
  3. 接收方檢測到起始位,然後通訊雙方按照波特率傳送和接收5-8位資料。
  4. 若使用校驗功能,則傳送完資料位後還要接著傳送奇偶校驗位。
  5. 最後,傳送停止位。

S3C2440的UART的特性

  • 3個獨立非同步序列I/O埠,每個都可以是基於中斷或基 於 DMA 模式的操作。
  • UART 通過使用系統時鐘可以支援最高 115.2Kbps 的位元率。如果是外部器件提供 UEXTCLK 的 UART,則 UART可以執行在更高的速度。
  • 每個 UART 通道包含兩個的 64 位元組的 FIFO 給傳送和接收。
  • S3C2440A 的 UART 包括了可程式設計波特率,紅外(IR)傳送/接收,插入 1 個或 2 個停止位,5 位、6 位、7 位或 8 位的資料寬度以及奇偶校驗。
  • 每個 UART 包含一個波特率發生器、傳送器、接收器和一個控制單元。波特率發生器可以由PCLK、FCLK/n 或 UEXTCLK(外部輸入時鐘)時鐘驅動。

UART的結構框圖 在這裡插入圖片描述 要傳送資料時,CPU控制記憶體要傳送的資料通過FIFO傳給UART單位,UART裡面的移位器,依次將資料傳送出去,在傳送完成後產生中斷提醒CPU傳輸完成。

接收資料時,獲取接收引腳的電平,逐位放進接收移位器,再放入FIFO,寫入記憶體。在接收完成後產生中斷提醒CPU傳輸完成。

波特率發生 每個 UART 的波特率發生器為傳送器和接受器提供序列時鐘。波特率發生器的源時鐘可以選擇 S3C2440A 的內部系統時鐘或 UEXTCLK。換句話說,分頻由設定 UCONn 的時鐘選項選擇。波特率時鐘是通過 16 和由 UART波特率分頻暫存器(UBRDIVn)指定的 16 位分頻係數來分頻源時鐘(PCLK,FCLK/n 或 UEXTCLK)產生的。 UBRDIVn 由下列表達式決定: UBRDIVn = (int)( UART 時鐘 / ( 波特率 × 16) ) - 1 例如,如果波特率為 115200 bps 並且 UART 時鐘為 40 MHz,則 UBRDIVn 為: UBRDIVn = (int)(40000000 / (115200 x 16) ) - 1 = (int)(21.7) - 1 [取最接近的整數] = 22 - 1 = 21

**

程式設計

** 目的:實現串列埠初始化函式、傳送一個位元組函式、接收一個位元組函式、傳送字串函式。

用到的特殊功能暫存器: 在這裡插入圖片描述 在這裡插入圖片描述 在這裡插入圖片描述 在這裡插入圖片描述 在這裡插入圖片描述 在這裡插入圖片描述 初始化函式: 1.要配置相應的GPIO引腳為串列埠功能。 2.設定方式(中斷查詢方式)、時鐘源選擇(PCLK)。 3.設定資料位、校驗位、停止位。 4.設定波特率(配置UBRDIVn)。

/* 115200,8n1 */
void uart0_init()
{
	/* 配置GPH2、3為 TXD0、RXD0,並且開啟上拉電阻 */
	GPHCON &= ~((3<<4) | (3<<6));
	GPHCON |=  ((2<<4) | (2<<6));
	GPHUP &= ~(3<<2);
	
	/* 配置UART CONTROL REGISTER,時鐘源為PCLK,中斷/查詢方式 */
	UCON0 = 0x00000005;
	
	/* 配置UART LINE CONTROL REGISTER 為 8n1 */
	ULCON0 = 0x00000003;
	
	/* 配置UBRDIV0,波特率為115200,UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1 */
	UBRDIV0 = 26;
}

傳送和接收函式則用到 狀態暫存器UTRSTATn 和 傳送緩衝暫存器UTXHn、接收緩衝暫存器URXHn。 具體程式碼如下:

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++;
	}
	
}