嵌入式入門3(UART)

UART:通用異步收發器(Universal Asynchronous Receiver and Transmitter),簡稱串口。主要用於:markdown

  • 一、打印調試信息。
  • 二、外接各類模塊,如:GPS、藍牙。

1、UART協議

  • 一、收發雙方約定好波特率(每一位佔據的時間)
  • 二、規定傳輸協議:數據位、中止位、校驗位、流量控制。

例如:115200 8n1,它表示發送的波特率爲115200,8個數據位,無校驗位,1箇中止位。也就是說:異步

1秒能傳輸115200位數據,即發送一位須要耗時t=1/115200秒。
每發送1byte數據,須要發送10位數據(開始位、數據位,中止位),耗時t=10/115200。
因此1秒鐘能傳輸11520byte的數據。spa

2、UART傳輸流程

最多見的UART串口都是採用TTL/CMOS電平,即0V ~ 0.7V表示邏輯02V ~ 5V表示邏輯1調試

在傳輸字符'A'時,發送波形以下:code

image.png

  1. 初始時,TxD引腳電平爲高電平。
  2. 開始發送數據時,ARM首先將TxD引腳電平拉低,並保持1bit時間。
  3. PC在低電平開始處計時。
  4. ARM根據數據依次驅動TxD的電平,發送數據。同時PC依次讀取RxD引腳電平,得到數據。

但一般狀況下,TTL電平知足不了長距離傳輸的要求,此時就引入RS-232電平,當電平在 +3V ~ +12V 時,表示邏輯0,當電平在 -3V ~ -12V 時,表示邏輯1。orm

image.png

3、UART打印調試信息

image.png

經過查閱芯片手冊第11章UART,知道S3C2440支持3個Uart口。引腳以下get

image.png

而後查看JZ2440電路圖,能夠知道USB串口採用的是UART0。string

image.png

因此咱們能夠經過配置UART0,來打印調試信息。it

3.一、設置引腳用於串口

首先,咱們配置GPH二、GPH3爲串口引腳,並使能其上拉電阻。io

image.png

image.png

//設置引腳用於串口
//GPH2,3用於TxD0,RxD0
GPHCON &= ~((3<<4)|(3<<6));
GPHCON |=  ((2<<4)|(2<<6));

//使能內部上拉
GPHUP &= ~((1<<2)|(1<<3));
複製代碼

3.二、配置UART0

一、設置波特率和時鐘

image.png

咱們經過設置UBRDIVn分頻,能夠分頻串口的時鐘,來知足咱們所指望的波特率。公式以下:

UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1

芯片手冊也給了例子,但咱們在上一章中,咱們將PCLK設置爲50MHz,因此咱們代入上式,獲得UBRDIVn=26。即此時UART clock爲50MHz,波特率爲115200。

此時,咱們重點關注,如何將PCLK設置爲UART clock。

image.png

這裏設置UCON0[11:10]爲00或10,讓UART clock等於PCLK的50MHz。

image.png

image.png

而後指定UCON0[3:2]和UCON0[1:0]爲01,開啓中斷或查詢模式。

//設置波特率
//UBRDIVn = (int)(UART clock / (buad rate x 16)) - 1
//UART clock = 50M
//UBRDIVn = 26
//PCLK,中斷/查詢模式
UCON0 = 0x00000005;
UBRDIV0 = 26;
複製代碼

二、設置數據格式

常見的數據格式爲8n1,即8個數據位,無校驗位,一箇中止位。

image.png

//設置數據格式
ULCON0 = 0x00000003;//8n1
複製代碼

三、發送和接收數據

image.png

當UTRSTATn[2]=1時,表示發送buffer和移位控制器都是空的,此時能夠繼續發送數據。
當UTRSTATn[0]=1時,表示接收buffer中有數據,此時能夠進行讀取數據。

image.png

咱們只需將數據存入UTXHn寄存器中,數據將會被UART自動發送出去。同時經過讀取URXHn寄存器,來讀取UART接收到的數據。

3.三、完整代碼

uart.c

#include "s3c2440_soc.h"
#include "uart.h"

void uart_init() {
    //設置引腳用於串口
    //GPH2,3用於TxD0,RxD0
    GPHCON &= ~((3<<4)|(3<<6));
    GPHCON |=  ((2<<4)|(2<<6));

    //使能內部上拉
    GPHUP &= ~((1<<2)|(1<<3));

    //設置波特率
    //UBRDIVn = (int)(UART clock / (buad rate x 16)) - 1
    //UART clock = 50M
    //UBRDIVn = 26
    //PCLK,中斷/查詢模式
    UCON0= 0x00000005;
    UBRDIV0 = 26;

    //設置數據格式
    ULCON0 = 0x00000003;//8n1
}

int uart_putchar(int c) {
    while(!(UTRSTAT0 & (1<<2)));
    UTXH0 = (unsigned char)c;
}

int uart_getchar(void) {
    while(!(UTRSTAT0 & (1<<0)));
    return URXH0;
}

int uart_puts(const char *s) {
    while(*s) {
        uart_putchar(*s);
        s++;
    }
}
複製代碼

main.c

#include "uart.h"

int main(void) {
    unsigned char c;

    uart_init();
    uart_puts("Hello, world!\n\r");

    while(1)
    {
        c = uart_getchar();
        uart_putchar(c);
    }
    return 0;
}
複製代碼

修改s3c2440_soc.h

......
#define __REG(x) (*(volatile unsigned int *)(x)) 
#define __REG_BYTE(x) (*(volatile unsigned char *)(x)) 

......

#define UTXH0 __REG_BYTE(0x50000020) //UART 0 transmission hold 
#define URXH0 __REG_BYTE(0x50000024) //UART 0 receive buffer 

......
複製代碼
相關文章
相關標籤/搜索