我們學(xué)習(xí)的RS232與UART的區(qū)別是,UART使用標(biāo)準(zhǔn)的TTL/COMS電平 進(jìn)過一個芯片使它的高低電平從TTL中0與3.3V 變成了 低電平5v到15v
高電平-3v到-12v。
首先說一下串口的數(shù)據(jù)幀格式。它由一個開始位,數(shù)據(jù)位,校驗位和停止位組成。
平時數(shù)據(jù)處于1狀態(tài)。
當(dāng)要開始發(fā)送時,從UART改變TxD數(shù)據(jù)變成0狀態(tài)1個位的時間,在接受端到0之后的1.5位的時間,接收端開始接受數(shù)據(jù)。
數(shù)據(jù)位分為5,6,7,8。四種類型的數(shù)據(jù)位。之后就是校驗位站1位,可以設(shè)置也可以不設(shè)置。最后的是停止位??梢允?位,1.5位,2位。這個是高電平1。
UART可以用中斷或DMA來工作。它有3個單獨的通道。它由4部分組成,發(fā)送器,接收器,波特率發(fā)生器,控制邏輯組成。
這些部分的設(shè)置都是通過寄存器來實現(xiàn)的。
發(fā)送的過程是這樣的,UART只能通過shifter一位一位的來發(fā)數(shù)據(jù)。它先把要發(fā)的數(shù)據(jù)放到它的緩存FIFO里,當(dāng)然緩存也可以取消。然后放入shifter里面來發(fā)出去。接受也是一樣的。通過緩存來接受,然后再通過接受的shifter來接。
具體繼電器的設(shè)置主要由以下幾個:
ULCON 邏輯數(shù)據(jù)楨格式控制器
UCON 串口的控制繼電器
UFCON FIFO控制寄存器
UMCON 串口MODEN控制器 (可以控制AFC 自動流控制)
以下是狀態(tài)寄存器,用來確定狀態(tài)的,比如說shifter發(fā)送器的狀態(tài),接收器的狀態(tài)。
UTRSTAT 接受發(fā)送控制器
UERSTAT 錯誤狀態(tài)寄存器
UFSTAT FIFO狀態(tài)寄存器
最后一個單獨的設(shè)置寄存器,它用來設(shè)置波特率
UBRDIV 波特率發(fā)生器
以下來寫個簡單的串口例子。
它不使用FIFO 中斷 而直接用shifter收發(fā),采用輪詢的方式來檢測數(shù)據(jù)是否發(fā)送或被接受。然后通過minicom向開發(fā)板發(fā)送1表示亮燈,發(fā)送2表示熄燈。
文件總共是7個 一個crt0.s main.c addr.h uart.h uart.c uart.lds makefile
crt0.s 是關(guān)閉watchdog 并跳轉(zhuǎn)到mian 之后用個deadloop。
.text.globl _start_start:ldrr0, =0x53000000 @ WATCHDOG closemovr1, #0x0strr1, [r0]ldr sp, =1024*4 @set stack,but the capitcy of cache is only 4k
bl mainhalt_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_Hvoid 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();//關(guān)燈#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的設(shè)置,他們用的是GPH2和3復(fù)用的特殊GPHUP = 0x0c;//功能,所以還要在這設(shè)置上拉電阻,以區(qū)別高低電平的。ULCON0 = 0x3; //楨格式的設(shè)置8個數(shù)據(jù)位,無校驗UCON0 = 0x5;//選擇的是中斷與輪詢模式UFCON0 = 0;//不設(shè)FIFOUMCON0 = 0;//不設(shè)AFCUBRDIV0 = UART_BRD; //設(shè)置波特率}
void uart_write(char *a){do{while(!(UTRSTAT0&2)); //UTRSTAT0的第2位是1的話表示發(fā)送數(shù)據(jù)的shifter內(nèi)的數(shù)據(jù)已經(jīng)被發(fā)送了,現(xiàn)在數(shù)據(jù)為空。如果里面的數(shù)據(jù)沒有空的話?。║&2)會一直是1,造成一直循環(huán),知道出現(xiàn)UTRSTAT0第2位為1的情況。
UTXH0 = *(a++); //發(fā)送寄存器只能一次最多發(fā)8位}while(*a!=\0);}
void uart_read(char *a,int n){do{
while(!(UTRSTAT0&1));//第1位為1表示shifter內(nèi)的數(shù)據(jù)已經(jīng)有了,可以讀了,如果為0的話將一直循環(huán),知道有數(shù)據(jù)可讀。*(a++) = (char)URXH0;n--;}while(n>0);}
void uart_read_line(char *a){do{
while(!(UTRSTAT0&1));*(a++) = URXH0;}while(*a!=\0);}
void led_on(){ GPEDAT = 0;}
void led_off(){GPEDAT = (3<<12);}
第5個文件main.c文件
#include"addr.h"#include"uart.h"
int main(){char *t = "Welcome to bootloader...\r\n";//這里只能用指針來傳遞,指針指向常量字符串的首地址傳入。char *t1 = "press 1 to light loop on\r\n";char *t2 ="press 2 to light loop off\r\n";char *t3 ="please input your choice\r\n";char r[10] ;//這里指針務(wù)必用數(shù)組來分配,一個沒有malloc函數(shù)。GPECON = GPE12_out|GPE13_out;uart_init();uart_write(t);uart_write(t1);uart_write(t2);uart_write(t3);while(1){uart_read(r,1);UTXH0 = *r;//這里是為了回顯switch(*r){case 1:led_on();break;case 2:led_off();break;}}return 0;}
第6個連接文件
SECTIONS {. = 0x00; .text : { *(.text) }.rodata ALIGN(4) : {*(.rodata)} .data ALIGN(4) : { *(.data) } .bss ALIGN(4) : { *(.bss) *(COMMON) }}最后介紹下makefile比較好的寫法。
SRC := $(wildcard *.c) //設(shè)定直接變量SRC,$(wildcard )表示使用通配符OBJC := $(patsubst %.c,%.o,$(SRC)) //表示把SRC里的值是.c結(jié)尾的換成.o結(jié)尾的結(jié)果保存到OBJC中
uart.bin:uart.elfarm-linux-objcopy -O binary -S $^ $@//表示$@目標(biāo)文件$^所有依賴arm-linux-objdump -D -m arm $^ >uart.disuart.elf:crt0.o $(OBJC)arm-linux-ld -T uart.lds $^ -o $@%.o:%.c //任意.o的依賴為.carm-linux-gcc -c $^ -o $@%.o:%.sarm-linux-gcc -c $^ -o $@
clean:rm -f uart.bin uart.dis uart.elf uart.o crt0.o main.o
然后用jtag燒入0x0內(nèi)部SRAM的4k容量內(nèi),并在minicom里輸入數(shù)據(jù)來控制led
關(guān)鍵詞: UART串口編
網(wǎng)站首頁 |網(wǎng)站簡介 | 關(guān)于我們 | 廣告業(yè)務(wù) | 投稿信箱
Copyright © 2000-2020 ffpps.com All Rights Reserved.
中國網(wǎng)絡(luò)消費網(wǎng) 版權(quán)所有 未經(jīng)書面授權(quán) 不得復(fù)制或建立鏡像
聯(lián)系郵箱:920 891 263@qq.com
坐公交忘穿内裤被挺进老外| 天天躁夜夜躁狠狠躁av乐播蜜桃| 2018午夜福利| 被全村灌满精的雯雯| aaaaa级少妇高潮大片免费看| 老七干白结33章| 国产优优A片在线观看| 亚洲欧美日本A∨在线观看| 野花免费社区在线| 日韩亚洲变态另类中文| 奶水h人妻销魂共妻高h| 把腿张开我帮你揉出水| 日韩精品一区二区三区中文| 人妻换人妻a片爽麻豆| 中文字幕二区AV人妻少妇| 欧美精品一区二区| 亚洲愉拍99热成人精品| 国产欧美久久久精品影院| 人妻少妇被猛烈进入中文字幕| 国产裸模视频免费区无码| 把腿扒开让我添30分钟视频| 女人做爰高潮呻吟17分钟| 亚洲妇熟xxxx妇色黄| 狠狠躁夜夜躁人爽碰88a| 一本大道久久东京热无码av| 可播放的中国男gary| 青娱乐极品盛宴| 中文字幕人妻偷伦在线视频| 欧美精产国品一二三产品区别| 精品国产自在天天线2019| 沈阳45老熟女高潮喷水亮点| 中文字幕av人妻一本二本| 成人白浆超碰人人人人| 学长别揉了我快尿了男男| 国模少妇一区二区三区| 国产一区二区精品久久岳| 国产精品沙发午睡系列99| 怀孕高潮潮喷大肚子孕妇| 将军边走边挺进她的小泬| 国内精品九九久久久精品| 成人性爱视频在线观看|