www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 單片機 > 單片機
[導(dǎo)讀]在嵌入式軟件開發(fā)過程中,往往都會用到串口進行打印信息以跟蹤調(diào)試代碼的運行。只要在代碼的關(guān)鍵位置加入打印函數(shù),即可分析代碼在這一位置的關(guān)鍵參數(shù)是否正確,運行狀態(tài)是否無誤以及相關(guān)的出錯信息。通過串口線連接

在嵌入式軟件開發(fā)過程中,往往都會用到串口進行打印信息以跟蹤調(diào)試代碼的運行。只要在代碼的關(guān)鍵位置加入打印函數(shù),即可分析代碼在這一位置的關(guān)鍵參數(shù)是否正確,運行狀態(tài)是否無誤以及相關(guān)的出錯信息。通過串口線連接PC端COM口與開發(fā)板的UART即可實現(xiàn)開發(fā)板與PC機的通信。在代碼調(diào)試階段,開始板的狀態(tài)信息通過串口打印顯示在PC端屏幕,可以一目了然,是一種非常重要的調(diào)試手段。筆者此處就s3c2416的串口打印使用作一個簡單的介紹。

1. UART模塊實現(xiàn)1.1. UART初始化

在使用任何外設(shè)前,一般都是需要對外設(shè)初始化。UART也不例外,使用前需設(shè)置波特率、通信控制、通信的處理方式(中斷還是查詢)等。設(shè)置波特率為115200,8位數(shù)據(jù),1位停止位,沒有奇偶檢驗(uboot默認設(shè)置),對于慢速外設(shè),高速cpu一般不應(yīng)通過查詢的方式去確定外設(shè)發(fā)送完數(shù)據(jù)或接收到數(shù)據(jù),這會讓cpu處于空等的狀態(tài),cpu效率很低,對于外設(shè)需發(fā)送或接收大量數(shù)據(jù)的情況更是如此。因此筆者此處主要講解s3c2416串口中斷方式去發(fā)送和接收數(shù)據(jù)的情況。由于s3c2416的UART發(fā)送和接收均有64字節(jié)的FIFO,通過中斷的方式可以連續(xù)裝載發(fā)送的數(shù)據(jù)到FIFO中或從FIFO中連續(xù)讀出接收的數(shù)據(jù),應(yīng)用只需通過Uart0中斷請求告知需發(fā)送或接收的數(shù)據(jù)長度及數(shù)據(jù)保存位置,即可進行等待掛起(如ucos中等待信號量標(biāo)志等函數(shù)OSSemPend),cpu可轉(zhuǎn)而處理其它的事情,當(dāng)Uart0中斷發(fā)送或接收完應(yīng)用請求的所有數(shù)據(jù),即可發(fā)送相關(guān)的信號量或標(biāo)志喚醒之前等待掛起的應(yīng)用(如ucos中發(fā)送信號量標(biāo)志等函數(shù)OSSemPost),cpu再轉(zhuǎn)而繼續(xù)處理之前的應(yīng)用。Uart0_Init()函數(shù)如下:

voidUart0_Init()

{

// 設(shè)置GPH0,GPH1為TX和RX

rGPHCON &= ~((3<<0)|(3<<2));

rGPHCON |= (2<<0)|(2<<2);

// 8位數(shù)據(jù),一個停止位,沒有奇偶檢驗

rULCON0 = 0x3;

// UART0 FIFO使能,Tx發(fā)送空時中斷,Rx 16bytes中斷

rUFCON0 = (0<<6) | (2<<4) | 0x7;

// 流控制禁止

rUMCON0 = 0;

// 發(fā)送接收中斷使能,使用PCLK時鐘66M

rUCON0 = 0x5 | (1<<7) | (2<<10);

// 設(shè)置波特率

rUBRDIV0 = 66000000/(16*Baudrate)-1;

rUDIVSLOT0 = 0x0888;

// 注冊UART0 IRQ中斷

IRQ_Register(INT_UART0, Uart0_IRQ);

// UART0 IRQ

rINTMOD1 &= ~(1 << INT_UART0);

// 開啟RX子中斷

// 在寫入FIFO之前,TX必須關(guān)閉中斷,不然FIFO空引發(fā)中斷

rINTSUBMSK |= 0x7;

rINTSUBMSK &= ~(1 <<0);

// UART0開啟中斷

rINTMSK1 &= ~(1 <

}

1.2. 格式化打印函數(shù)

C語言的一些庫函數(shù)功能很強大,沒有必要再自己去實現(xiàn)。軟件調(diào)試時,可能用的最多的函數(shù)就是printf。由于printf格式化輸出是面向控制臺的,在arm目標(biāo)中是通過一種半主機的方式,把printf函數(shù)輸出請求傳送至運行調(diào)試器的主機。如果不對printf進行重定向是不能在目標(biāo)板中使用printf等函數(shù)的(fputc和 fgetc重定向到串口或目標(biāo)板屏幕)。筆者此處為了通用,不重定向改寫printf,而是使用vsnprintf函數(shù)進行格式化輸出到字符串中,再把字符串發(fā)送到串口,實現(xiàn)與printf類似的串口打印輸出。串口格式化打印函數(shù)Uart0_Printf()如下:

// 串口打印函數(shù),替換庫函數(shù)printf函數(shù)功能

// printf是向控制臺輸出信息,通過vsnprintf格式化數(shù)據(jù)輸出

// 到字符串,并通過串口發(fā)送字符串函數(shù)進行串口打印

voidUart0_Printf(char *fmt, ...)

{

va_list ap;

char String[1024];

va_start(ap, fmt);

vsnprintf(String, sizeof(String), fmt, ap);

va_end(ap);

Uart0_SendString(String);

}

1.3. 串口字符串輸出

Uart0_Printf()通過vsnprintf()格式化輸出到字符串后,即可用Uart0_SendString()進行字符串發(fā)送,Uart0_SendString()會確定出字符串的長度,即確定串口發(fā)送的數(shù)據(jù)長度,再調(diào)用Uart0_SendData()進行發(fā)送一定長度的字節(jié)數(shù)據(jù)到串口。

// 通過串口發(fā)送字符串

voidUart0_SendString(char *String)

{

unsigned int Len;

char *Temp = String;

if (String == 0) {

return;

}

Len = 0;

// 獲得字符串的長度

while (*Temp++) {

Len++;

}

Uart0_SendData((unsigned char *)String,Len);

}

1.4. 任意長度字節(jié)輸出

Uart0_SendData()會最終向uart0請求發(fā)送一定長度的數(shù)據(jù),以及數(shù)據(jù)所在的位置,之后會進入等待,直到uart0中斷發(fā)送完所有請求的數(shù)據(jù)。由于Uart對外發(fā)送數(shù)據(jù)是很慢的,如果有操作系統(tǒng)或狀態(tài)機實現(xiàn)中,在while等待中,可改成類似信號量等待,把Uart0_SendData()函數(shù)掛起(如OSSemPend(ucos)),直到uart0中斷完成請求后,發(fā)送信號量或標(biāo)志再喚醒執(zhí)行(如OSSemPost(ucos))。Uart0_SendData()函數(shù)實現(xiàn)如下:

// 通過串口發(fā)送任意長度的數(shù)據(jù)

voidUart0_SendData(unsigned char *pBuffer, unsigned int Len)

{

if (pBuffer == 0 || Len == 0) {

return;

}

TxLen = Len; // 向中斷請求發(fā)送的數(shù)據(jù)字節(jié)長度

pTxData = pBuffer; // 發(fā)送數(shù)據(jù)的位置

TxLen--; // 發(fā)送了一字節(jié),發(fā)送數(shù)據(jù)長度減1

// 發(fā)送第一個字節(jié)完后會產(chǎn)生中斷,之后數(shù)據(jù)在中斷函數(shù)中連續(xù)發(fā)送

rUTXH0 = *pTxData++;

rINTSUBMSK &= ~(1 <<1); // 數(shù)據(jù)寫入FIFO后開啟TX發(fā)送完中斷

while(TxLen != -1) {

// 等待UART0數(shù)據(jù)發(fā)送完

// 可改成操作系統(tǒng)信號量等待函數(shù),提高cpu效率,如OSSemPend(ucos)

}

}

1.5. 發(fā)送字節(jié)函數(shù)

Uart0_SendByte()用來向串口發(fā)送一字節(jié)的數(shù)據(jù)(字符),其向uart0請求一字節(jié)的數(shù)據(jù)發(fā)送。

// 通過串口發(fā)送一字節(jié)數(shù)據(jù)

voidUart0_SendByte(unsigned char Byte)

{

TxLen = 0; // 發(fā)送1字節(jié)后,發(fā)送數(shù)據(jù)長度為0

rUTXH0 = Byte; // 1字節(jié)數(shù)據(jù)裝載進FIFO中

rINTSUBMSK &= ~(1 <<1); // 數(shù)據(jù)寫入FIFO后開啟TX中斷

while (TxLen != -1) { // 等待中斷中發(fā)送完標(biāo)志

// 等待UART0數(shù)據(jù)發(fā)送完

// 可改成操作系統(tǒng)信號量等待函數(shù),提高cpu效率,如OSSemPend(ucos)

}

}

1.6. 字符串接收函數(shù)

Uart0_ReceiveString()用來請求通過串口接收字符串,其會調(diào)用Uart0_ReceiveByte()來向uart0請求接收一個字節(jié)的數(shù)據(jù),根據(jù)接收到的字符數(shù)據(jù)判斷是否字符串結(jié)束或者回車結(jié)束。

// 通過串口接收字符串,指定緩存長度為Len

voidUart0_ReceiveString(char *pBuffer, unsigned int Len)

{

char *Temp;

unsigned int i;

if (pBuffer == 0 || Len == 0) {

return;

}

Temp = pBuffer;

for (i=0; i

*Temp = Uart0_ReceiveByte();

if (*Temp == 0 || *Temp == 'r') {

break; // 字符串結(jié)束或回車則結(jié)束輸入

}

Temp++;

}

if (i < Len) {

pBuffer[i] = 0; // 字符串末尾加入結(jié)束字符0

} else {

pBuffer[Len-1] = 0;

}

}

1.7. 字節(jié)接收函數(shù)

Uart0_ReceiveByte()會通過uart0請求接收一個字節(jié)的數(shù)據(jù),阻塞直到接收到數(shù)據(jù)返回。

// 通過串口接收一字節(jié)數(shù)據(jù)

charUart0_ReceiveByte(void)

{

unsigned char Value;

pRxData = &Value; // 中斷中接收的1字節(jié)數(shù)據(jù)放在Value中

RxLen = 1; // 接收長度為1字節(jié)

while(RxLen != 0) {

// 等待UART0數(shù)據(jù)接收

// 可改成操作系統(tǒng)信號量等待函數(shù),提高cpu效率,如OSSemPend(ucos)

}

return ((char)Value);

}

1.8. 中斷請求處理

Uart0_IRQ()中斷處理函數(shù)用來處理應(yīng)用的發(fā)送請求以及接收請求。如果請求的發(fā)送數(shù)據(jù)長度或請求的接收數(shù)據(jù)長度過大,將會分多個中斷請求來分包發(fā)送數(shù)據(jù)或接收數(shù)據(jù),直到所有的數(shù)據(jù)請求均完成后,通過發(fā)送信號量(如OSSemPost(ucos))或完成標(biāo)志告知請求的應(yīng)用。

// 請求通過串口發(fā)送的字節(jié)數(shù)

static volatile int TxLen = 0;

// 請求通過串口接收的

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

IIC是Philips推出的芯片間串行傳輸總線,它以二根連線實現(xiàn)完善的全雙工同步數(shù)據(jù)傳送,可以極方便地構(gòu)成多機系統(tǒng)和外圍器件擴展系統(tǒng)。由于其接口簡單靈活,很多外圍器件均提供了IIC接口,如手機、平板常用的重力傳感器

關(guān)鍵字: s3c2416 裸機開發(fā) iic驅(qū)動

現(xiàn)在主要講解一下在GCC移植UCGUI,Makefile工程如何加入目錄,加入源碼,c標(biāo)準庫,編譯選項的設(shè)置。筆者的Makefile模板提取自uboot,工程中加入目錄,加入源碼都是很簡單的,詳細的介紹請參考前面章節(jié)”...

關(guān)鍵字: gcc s3c2416 ucgui 移植 裸機開發(fā)

jpeg格式是一種針對相片影像而廣泛使用的一種失真壓縮標(biāo)準,其壓縮技術(shù)十分先進,用有損壓縮方式去除冗余的圖像數(shù)據(jù),在獲得極高壓縮率的同時,能展現(xiàn)十分豐富生動的圖像,能用最少的磁盤空間得到較好的圖像品質(zhì)。由

關(guān)鍵字: s3c2416 移植 裸機開發(fā) libjpeg

在消費電子產(chǎn)品中,往往都會用到音頻系統(tǒng)來播放音樂、進行通話等多媒體應(yīng)用,此外,對于一些需語音提示的產(chǎn)品,音頻部分都是不可或缺的功能。筆者此處就s3c2416的音頻驅(qū)動實現(xiàn)作一個簡單的介紹。1. IIS音頻總線s3c24

關(guān)鍵字: s3c2416 裸機開發(fā) 音頻驅(qū)動

S3C2416裸機開發(fā)系列十八_音頻驅(qū)動實現(xiàn)(2)標(biāo)簽:WM8960IIS音頻驅(qū)動s3c2416裸機開發(fā)2014-06-10 09:50853人閱讀評論(0)收藏舉報分類:s3c2416裸機開發(fā)(24)版權(quán)聲明:本文為博...

關(guān)鍵字: s3c2416 裸機開發(fā) 音頻驅(qū)動

很多的嵌入式系統(tǒng)都需要人機交互,對于輸出設(shè)備,LCD以其顯示質(zhì)量高、畫面效果好等優(yōu)點得到了極其廣泛的應(yīng)用。s3c2416包含了一個LCD控制器,筆者此處就s3c2416的LCD應(yīng)用作一個簡單的介紹。1、LCD控制器概述1...

關(guān)鍵字: s3c2416 裸機開發(fā) rgb屏 驅(qū)動顯示

在嵌入式設(shè)計中,由于Nand Flash具有大容量,擦寫次數(shù)高,接口簡單等優(yōu)點,常用作固化存儲器。S3C2416支持Nand啟動,因此Nand存儲器可以直接保存固化代碼以及其它的數(shù)據(jù)。筆者在此簡單的介紹Nand flas...

關(guān)鍵字: nand驅(qū)動 s3c2416 裸機開發(fā) nand啟動

筆者前面章節(jié)簡單介紹了s3c2416啟動代碼的實現(xiàn)過程,啟動代碼就是用來處理cpu體系結(jié)構(gòu)中一些底層內(nèi)容,一個功能強大的啟動代碼是可以當(dāng)作bootloader(如uboot)來用的。有了啟動代碼,用戶就可以專注于用c來作...

關(guān)鍵字: mdk s3c2416 啟動代碼 裸機開發(fā)

啟動代碼是處理器上電復(fù)位后最先運行的一段代碼。主要是用來把處理器初始化到一個確定的狀態(tài),為c運行環(huán)境作好準備。如設(shè)置異常向量表,初始化系統(tǒng)時鐘,初始化外部內(nèi)存,把用戶代碼拷貝到外部內(nèi)存,初始化棧,清0全

關(guān)鍵字: s3c2416 啟動代碼 流水燈 裸機開發(fā)

S3C2416裸機開發(fā)系列十九_Fatfs下播放錄音wav音頻文件標(biāo)簽:wavfatfs音頻播放s3c2416sd驅(qū)動2014-06-11 09:551938人閱讀評論(0)收藏舉報分類:s3c2416裸機開發(fā)(24)版...

關(guān)鍵字: s3c2416 裸機開發(fā) 播放錄音 音頻文件
關(guān)閉