S3C2440串口及其中斷系統(tǒng)詳解
S3C2440A的通用異步收發(fā)器(UART)配有3個(gè)獨(dú)立異步串行I/O(SIO)端口,每個(gè)都可以是基于中斷或基于DMA模式的操作。換句話說,UART可以通過產(chǎn)生中斷或DMA請(qǐng)求來進(jìn)行CPU和UART之間的數(shù)據(jù)傳輸。
UART通過使用系統(tǒng)時(shí)鐘可以支持最高115.2Kbps的比特率。如果是外部器件提供UEXTCLK的UART,則UART可以運(yùn)行在更高的速度。每個(gè)UART通道包含兩個(gè)的64字節(jié)的FIFO給發(fā)送和接收。
S3C2440A的UART包括了可編程波特率,紅外(IR)發(fā)送/接收,插入1個(gè)或2個(gè)停止位,5位、6位、7位或8位的數(shù)據(jù)寬度以及奇偶校驗(yàn)。每個(gè)UART包含一個(gè)波特率發(fā)生器、發(fā)送器、接收器和一個(gè)控制單元,如圖11-1所示。波特率發(fā)生器可以由PCLK、FCLK/n或UEXTCLK(外部輸入時(shí)鐘)時(shí)鐘驅(qū)動(dòng)。發(fā)送器和接收器包含了64字節(jié)FIFO和數(shù)據(jù)移位器。
將數(shù)據(jù)寫入到FIFO接著在發(fā)送前復(fù)制到發(fā)送移位器中。隨后將在發(fā)送數(shù)據(jù)引腳(TxDn)移出數(shù)據(jù)。與此同時(shí)從接收數(shù)據(jù)引腳(RxDn)移入收到的數(shù)據(jù),接著從移位器復(fù)制到FIFO
使用2440的uart和其他芯片的uart使用類似,也是分為以下幾步
設(shè)置數(shù)據(jù)長(zhǎng)度,開始為,停止位,奇偶校驗(yàn)相關(guān)
選擇設(shè)置uart時(shí)鐘,中斷類型,fifo狀態(tài)等
設(shè)置FIFO,(我禁用了fifo)
設(shè)置自動(dòng)流控制(我禁用了自動(dòng)流控制)
設(shè)置波特率
波特率的計(jì)算公式如下
然后很重要的一點(diǎn)是串口配置好了還需要配置串口IO,參見之前的IO配置
如果要使能中斷的話還要配置相應(yīng)的中斷,主要還是之前說過的寄存器,但是多了兩個(gè),子中斷寄存器,
也就是說打開串口總中斷之后需要再打開相應(yīng)的子中斷才能工作,中斷處理清除總中斷標(biāo)志之后還要清除對(duì)應(yīng)的子中斷標(biāo)志才行
Uart0.c
#include"uart0.h"#include"stdio.h"http:////////////////////////////////////////////////////////////////////加入以下代碼,支持printf函數(shù),而不需要選擇useMicroLIB#if1#pragmaimport(__use_no_semihosting)//標(biāo)準(zhǔn)庫(kù)需要的支持函數(shù)struct__FILE{inthandle;};FILE__stdout;//定義_sys_exit()以避免使用半主機(jī)模式_sys_exit(intx){x=x;}//重定義fputc函數(shù)intfputc(intch,FILE*f){while(!(rUTRSTAT0&0x2));//WaituntilTHRisempty.WrUTXH0((u8)ch);;returnch;}#endif/***********只打開接收中斷***********/void__irquartRxISP(void){charch;inti=0;rSUBSRCPND"=0x3;//清除rx,tx中斷請(qǐng)求rSRCPND|=0x1<<28;//清除串口源掛起rINTPND|=0x1<<28;//清除串口子掛起if(rUTRSTAT0&1)//接收緩沖區(qū)有數(shù)據(jù){ch=rURXH0;//接收字節(jié)數(shù)據(jù),接受處理Uart0SendByte(ch);}}voidUart0Init(u32baud){CalcBusClk();//計(jì)算總線頻率rULCON0=0x03;//8位數(shù)據(jù),1位停止位,無校驗(yàn),不使用紅外rUFCON0=0;//禁止fiforUMCON0=0;//禁止rts自動(dòng)流控制rUCON0=0x5;//使用pclk時(shí)鐘,中斷模式rUBRDIV0=((int)(PCLK/16./baud+0.5)-1);rGPHCON&=~((3<<4)|(3<<6));rGPHCON|=(2<<4)|(2<<6);//把GPH3、GPH2設(shè)置為RXD[0]、TXD[0]功能rSRCPND|=0x1<<28;//清除串口中斷掛起rSUBSRCPND|=0x3;//清除收發(fā)中斷rINTPND|=0x1<<28;//清除串口中斷請(qǐng)求rINTSUBMSK&=~(0x1);//打開UART0接收中斷,使能中斷rINTSUBMSK|=(0x1<<1);//關(guān)閉UART0發(fā)送中斷,禁止中斷rINTMSK&=~(0x1<<28);//打開UART0中斷屏蔽,總中斷pISR_UART0=(unsigned)uartRxISP;//中斷子程序建立連接}voidUart0SendByte(u8dat){while(!(rUTRSTAT0&0x2));//WaituntilTHRisempty.WrUTXH0(dat);while(!(rUTRSTAT0&0x2));//WaituntilTHRisempty.}
Uart0.h
#ifndef__UART0_H_#define__UART0_H_#include"2440addr.h"#include"def.h"#include"clock.h"#include"stdio.h"voidUart0Init(u32baud);voidUart0SendByte(u8dat);#endif