LCD實驗學習筆記(九):UART

s3c2440包含三個通用異步收發器,可工做於中斷模式或DMA模式。每一個UART包含兩個64字節的FIFOs用於接收和發送數據。可編程設置波特率、1或2箇中止位,5/6/7/8個數據位和奇偶校驗狀態。git

串口線通常是3條,TxD,RxD,Gnd,即發送線,接收線和地線。編程

數據傳送以前,UART之間約定好傳輸速率(每位所佔據的時間,其倒數潙波特率)、數據傳輸的格式(多少個數據位、是否使用校驗位、奇校驗仍是偶校驗、多少箇中止位)。異步

發送數據時,CPU先將數據寫入發送FIFO,UART會自動將FIFO中的數據複製發送移位器(Transmit Shifter)中,發送移位器將數據一位一位的發送到TxDn數據線上。接收則過程相反。函數

使用UART:get

1,將涉及的管腳設爲UART功能。好比UART0,GPH二、GPH3分別用做TxD0和RxD0,要設置GPHCON寄存器,將兩個引腳功能設爲TxD0、RxD0。it

2,設置波特率。UBRDIVn寄存器的值對應三個UART通道的波特率。UBRDIVn=(int)(UART clock/(buad rate *16))-1。這個公式計算出來的值不必定是整數,偏差<1.87%就能夠。偏差計算公式(略)。方法

 3,設置傳輸格式。在ULCON0n寄存器中設置,[1:0]爲數據寬度(0b00爲5位,0b01爲6位,0b10爲7位,0b11爲8位),[2]爲中止位(0爲一個,1爲兩個),[5:3]爲校驗方法(0xx無校驗,100奇校驗,101偶校驗,110強制1,111強制0)。im

4,設置時鐘源、中斷方式。在UCONn中設置。[1:0]設置接收模式(00禁止,01中斷或查詢,其餘爲DMA),[3:2]設置接收模式(01中斷或查詢模式),[10]設爲0爲選擇PCLK時鐘源。數據

5,設置FIFO。UFCONn寄存器用於設置是否使用FIFO,設置FIFO觸發閾值。讀取UFSTATn寄存器能夠知道FIFO是否已滿、有多少數據。查詢

6,UMCOMn和UMSTATn用於流量控制(實驗中未用)。

7,狀態查詢。UTRSTATn寄存器表示數據是否已發送完畢、是否已經接收數據。[0]是接收緩衝區數據狀態位,在接收到數據時會自動設爲1;[1]是發送緩衝區空標誌位,當發送緩衝區無數據時自動設爲1;[2]爲發送區空標誌位,當發送緩衝區中沒有數據,且最後一個數據已發送出去時,自動設爲1。數據緩衝區就是FIFO,在不使用FIFO時,能夠認爲其深度爲1。

8,當有錯誤發生時,UERSTATn寄存器的[0]~[3]爲1分別表示不一樣的錯誤,讀取這個寄存器,它會自動清0。

9,發送數據操做:將數據寫入UTXHn寄存器,UART會自動把數據保存到緩衝區,並自動發送。

10,數據接收:當UART接收到數據時,CPU讀取URXHn寄存器,便可得到數據。

 示例代碼:對UART初始化,讀取輸入數據並回發


#define GPHCON              (*(volatile unsigned long *)0x56000070)

#define GPHDAT              (*(volatile unsigned long *)0x56000074)

#define GPHUP               (*(volatile unsigned long *)0x56000078)

/*UART registers*/

#define ULCON0              (*(volatile unsigned long *)0x50000000)

#define UCON0               (*(volatile unsigned long *)0x50000004)

#define UFCON0              (*(volatile unsigned long *)0x50000008)

#define UMCON0              (*(volatile unsigned long *)0x5000000c)

#define UTRSTAT0            (*(volatile unsigned long *)0x50000010)

#define UTXH0               (*(volatile unsigned char *)0x50000020)

#define URXH0               (*(volatile unsigned char *)0x50000024)

#define UBRDIV0             (*(volatile unsigned long *)0x50000028)

#define TXD0READY (1<<2)
#define RXD0READY (1)

#define PCLK 50000000 // init.c中的clock_init函數設置PCLK爲50MHz
#define UART_CLK PCLK // UART0的時鐘源設爲PCLK
#define UART_BAUD_RATE 115200 // 波特率
#define UART_BRD ((UART_CLK / (UART_BAUD_RATE * 16)) - 1)

void uart0_init(void);

void putc(unsigned char c);

unsigned char getc(void);

int isDigit(unsigned char c);

int isLetter(unsigned char c);

/*
* 初始化UART0
* 115200,8N1,無流控
*/
void uart0_init(void)
{
  GPHCON |= 0xa0; // GPH2,GPH3用做TXD0,RXD0  
  GPHUP = 0x0c; // GPH2,GPH3內部上拉禁用(默認值是啓用的)

  ULCON0 = 0x03; // 8N1(8個數據位,無較驗,1箇中止位)
  UCON0 = 0x05; // 中斷或查詢方式,UART時鐘源爲PCLK
  UFCON0 = 0x00; // 不使用FIFO
  UMCON0 = 0x00; // 不使用流控
  UBRDIV0 = UART_BRD; // 波特率爲115200
}

/*
* 發送一個字符
*/
void putc(unsigned char c)
{
  /* 等待,直到發送緩衝區中的數據已經所有發送出去 */
  while (!(UTRSTAT0 & TXD0READY));
  /* 向UTXH0寄存器中寫入數據,UART即自動將它發送出去 */
  UTXH0 = c;
}

/*
* 接收字符
*/
unsigned char getc(void)
{
  /* 等待,直到接收緩衝區中的有數據 */
  while (!(UTRSTAT0 & RXD0READY));
  /* 直接讀取URXH0寄存器,便可得到接收到的數據 */
  return URXH0;
}

/*
* 判斷一個字符是否數字
*/
int isDigit(unsigned char c)
{
  if (c >= '0' && c <= '9')
    return 1;
  else
  return 0;
}

/*
* 判斷一個字符是否英文字母
*/
int isLetter(unsigned char c)
{
  if (c >= 'a' && c <= 'z')
    return 1;
  else if (c >= 'A' && c <= 'Z')
    return 1;
  else
    return 0;
}

 

相關文章
相關標籤/搜索