久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

新聞中心

EEPW首頁 > 嵌入式系統 > 設計應用 > 第4課:UART串口編程

第4課:UART串口編程

作者: 時間:2016-11-11 來源:網絡 收藏
首先明確一點:我們學習的串口是異步串口。在傳輸時,他們各自有各自的時鐘。就是我們說的波特率。

我們學習的RS232與UART的區別是,UART使用標準的TTL/COMS電平 進過一個芯片使它的高低電平從TTL中0與3.3V 變成了 低電平5v到15v

本文引用地址:http://cqxgywz.com/article/201611/316803.htm

高電平-3v到-12v。

首先說一下串口的數據幀格式。它由一個開始位,數據位,校驗位和停止位組成。

平時數據處于1狀態。

當要開始發送時,從UART改變TxD數據變成0狀態1個位的時間,在接受端到0之后的1.5位的時間,接收端開始接受數據。

數據位分為5,6,7,8。四種類型的數據位。之后就是校驗位站1位,可以設置也可以不設置。最后的是停止位。可以是1位,1.5位,2位。這個是高電平1。

UART可以用中斷或DMA來工作。它有3個單獨的通道。它由4部分組成,發送器,接收器,波特率發生器,控制邏輯組成。

這些部分的設置都是通過寄存器來實現的。

發送的過程是這樣的,UART只能通過shifter一位一位的來發數據。它先把要發的數據放到它的緩存FIFO里,當然緩存也可以取消。然后放入shifter里面來發出去。接受也是一樣的。通過緩存來接受,然后再通過接受的shifter來接。

具體繼電器的設置主要由以下幾個:

ULCON 邏輯數據楨格式控制器

UCON 串口的控制繼電器

UFCON FIFO控制寄存器

UMCON 串口MODEN控制器 (可以控制AFC 自動流控制)

以下是狀態寄存器,用來確定狀態的,比如說shifter發送器的狀態,接收器的狀態。

UTRSTAT 接受發送控制器

UERSTAT 錯誤狀態寄存器

UFSTAT FIFO狀態寄存器

最后一個單獨的設置寄存器,它用來設置波特率

UBRDIV 波特率發生器

以下來寫個簡單的串口例子。

它不使用FIFO 中斷 而直接用shifter收發,采用輪詢的方式來檢測數據是否發送或被接受。然后通過minicom向開發板發送1表示亮燈,發送2表示熄燈。

文件總共是7個 一個crt0.s main.c addr.h uart.h uart.c uart.lds makefile

crt0.s 是關閉watchdog 并跳轉到mian 之后用個deadloop。

.text
.globl _start
_start:
ldrr0, =0x53000000 @ WATCHDOG close
movr1, #0x0
strr1, [r0]
ldr sp, =1024*4 @set stack,but the capitcy of cache is only 4k

bl main
halt_loop:
b halt_loop

第2個是addr.h用來寫寄存器的宏定義。

#ifndef ADDR_H
#define ADDR_H
#define GPECON (*(volatile unsigned int *)0x56000040)
#define GPEDAT (*(volatile unsigned int *)0x56000044)

#define GPE12_out (1<<(12*2))
#define GPE13_out (1<<(13*2))

#define GPHCON (*(volatile unsigned int *)0x56000070)
#define GPHUP (*(volatile unsigned int *)0x56000074)
#define ULCON0 (*(volatile unsigned int *)0x50000000)
#define UCON0 (*(volatile unsigned int *)0x50000004)
#define UFCON0 (*(volatile unsigned int *)0x50000008)
#define UMCON0 (*(volatile unsigned int *)0x5000000C)
#define UTRSTAT0 (*(volatile unsigned int *)0x50000010)
#define UFSTAT0 (*(volatile unsigned int *)0x50000018)
#define UTXH0 (*(volatile unsigned int *)0x50000020)
#define URXH0 (*(volatile unsigned int *)0x50000024)
#define UBRDIV0 (*(volatile unsigned int *)0x50000028)

#endif

第3個文件來寫uart.h,這是個我們的功能

#ifndef UART_H
#define UART_H
void uart_init(); //初始化繼電器

void uart_write(char *a); //串口寫一行

void uart_read(char *a,int n);//串口讀n個字

void uart_read_line(char *a); //讀一行

void led_on(); //開燈

void led_off();//關燈
#endif

第4個文件具體來寫uart.C

#include"uart.h"
#include"addr.h"
#define UART_CLK 50000000 //我們用的是PCLK 50MHz
#define UART_BAUD_RATE 115200 //比特率是115200
#define UART_BRD (int)(UART_CLK/(UART_BAUD_RATE *16))-1 //計算公式的宏
void uart_init()
{
GPHCON |=0xa0;//這個是TXD0與RXD0的設置,他們用的是GPH2和3復用的特殊
GPHUP = 0x0c;//功能,所以還要在這設置上拉電阻,以區別高低電平的。
ULCON0 = 0x3; //楨格式的設置8個數據位,無校驗
UCON0 = 0x5;//選擇的是中斷與輪詢模式
UFCON0 = 0;//不設FIFO
UMCON0 = 0;//不設AFC
UBRDIV0 = UART_BRD; //設置波特率
}

void uart_write(char *a)
{
do{
while(!(UTRSTAT0&2)); //UTRSTAT0的第2位是1的話表示發送數據的shifter內的數據已經被發送了,現在數據為空。如果里面的數據沒有空的話?。║&2)會一直是1,造成一直循環,知道出現UTRSTAT0第2位為1的情況。

UTXH0 = *(a++); //發送寄存器只能一次最多發8位
}
while(*a!=