日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UART0串口编程(三):中断方式的串口编程;用中断编写发送函数

發布時間:2025/6/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UART0串口编程(三):中断方式的串口编程;用中断编写发送函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

UART0串口編程(三)

一:中斷方式的串口編程

1.用中斷方式編寫串口程序由那幾部分組成

2.硬件上的支持

1>UART0 發送FIFO緩沖區

A.UART0含有1個16字節的發送FIFO緩沖區

B.U0THR是UART0發送FIFO的最高字節

C.UART的發送FIFO是一直使能的

2>UART0接收FIFO緩沖區

A. UART0含有一個16字節的接收FIFO緩沖區。

B.?軟件設置接收FIFO緩沖區的觸發字節。

3> 中斷接口:UART0的中斷接口包含中斷使能寄存器(U0IER)和中斷標識寄存器(U0IIR)。

第一:U0IIR:提供狀態碼用于指示一個掛起中斷的中斷源和優先級。

第二:U0IER可以控制UART0的4個中斷源。

4> UART0有4個中斷源:

A. RLS(接收線狀態)中斷:

(1) 優先級最高

(2) 它在以下條件發生時產生錯誤

第一:幀錯誤(FE)

第二:溢出錯誤(OE)

第三:奇偶錯誤(PE)

第四:間隔中斷(BI)

注:可以通過查看U0LSR[4:1]中的值看到產生該中斷的錯誤條件,讀取U0LSR寄存器時清除該中斷。

B. RDA(接收數據可用)中斷:

(1)與CTI中斷并列第二優先級。

(2)在以下情況觸發中斷:

第一:當接收的有效數據到達接收FIFO設置寄存器(U0FCR)中設置的觸發點時,RDA被激活。當接收FIFO中的有效數據少于觸發點時,RDA復位。

第二:中斷過程:

1> ?移位寄存器(U0RSR)從RxD引腳接收串行數據后,送入接收FIFO中

2> ?當接收FIFO中的有效數據數量達到預定的觸發點時,置位RDA中斷。

3> ?從U0RBR寄存器中讀取FIFO中最早到達的數據,當FIFO中的有效數據小于觸發點時,清零RDA中斷。

C. ?CTI(字符超時指示)中斷

(1) 優先級為2.

(2) 在以下情況發生中斷:

當接收FIFO中的有效數據少于預定的觸發點數量時,如果在一定時間內仍沒有接收到新的數據,那將觸發該中斷。

(3) 上面的時間指的是:3.5~4.5個字節所需要的時間。

(4) ?對接收FIFO的任何操作都會清零該中斷標志。

(5) 中斷過程:

第一:移位寄存器(U0RSR)從RxD0引腳接收串行數據后,送入接收FIFO中。

第二:當接收FIFO中的有效數據少于觸發個數,但如果長時間沒有數據到達,則觸發CTI中斷。

第三:從U0RBR中讀取接收FIFO中的數據,或者有新的數據送入接收FIFO,都將清零CTI中斷。

注:3.5~4.5個字節的時間:指在串口當前的波特率下,發送3.5~4.5個字節所需要的時間。

當接收FIFO中存放多個數據,從U0RBR讀取數據,但是沒有讀完所有數據,那么在經過3.5~4.5個字節的時間后觸發CTI中斷。

D. ?THRE(發送)中斷

(1) 優先級為第三級優先級。

(2) 當FIFO為空并且在以下情況觸發中斷:

第一:系統啟動時,雖然發送FIFO為空,但不會產生THRE中斷。

第二:在上一次發生THRE中斷后,向發送FIFO中寫入1個字節數據,將在一個字節加上一個停止位后發生THRE中斷

(because:如果發送移位寄存器為空,那么寫入發送FIFO的數據將直接進入發送移位寄存器。此時發送FIFO仍然為空,如果立即產生THRE中斷,就會影響緊接著寫入發送FIFO的數據。所以在發送完該一個字節以及一個停止位后,才產生THRE中斷。)

如果在發送FIFO中有過兩個字節以上的數據,但是現在發送FIFO為空時,將立即觸發THRE中斷。當THRE中斷為當前有效的最高優先級中斷時,往U0THR寫數或者對U0IIR的讀操作,將使THRE中斷復位

我們來看看這些中斷源與存儲器之間的關系:

注:由上圖可知:UART0有4個中斷源:分別是RLS(線狀態)中斷,RDA(接收數據)中斷,CTI(字符超時)中斷,THRE(發送數據)中斷。4個中斷源的優先級如下圖所示:

?

3.串口中斷接收初始化

1>串口中斷接收初始化流程

l ?設置I/O引腳連接到UART0

l ?置位除數鎖存位,配置UART0幀數據格式

l ?根據波特率計算分頻值

l ?設置波特率

l ?清除除數鎖存位,并設置工作模式

l ?使能FIFO,并設置觸發點

l ?允許RBR中斷

注:我們可以發現與輪訓方式相比,中斷方式只是增加了使能FIFO,并設置中斷觸發點和允許RBR中斷兩步。

2>中斷串口初始化需要配置的寄存器

?????(與輪循方式配置方法相同的寄存器在此處不在涉及)

l ?U0FCR(FIFO控制寄存器):U0FCR控制UART0 Rx和Tx FIFO的操作。

l ?U0IER(中斷使能寄存器):U0IER用于使能4個UART0中斷源。

3>具體寄存器的配置

(1) U0FCR

A作用:控制UART0 Rx和Tx的操作。

B長度:8位寄存器。

C:每一位的含義:

l ?第0位:表示FIFO使能

置1:表示使能對UART0 Rx和Tx的FIFO以及U0FCR[7:1]的訪問。

置0:表示不能使用Rx和Tx的FIFO以及步能對U0FCR[7:1]的訪問。

注:該位的任何變化都將使UART0 FIFO清空。

l ?第1位:表示Rx FIFO的復位。

置1:會清零UART0 RxFIFO中的所有字節并復位指針邏輯。該位自動清零。

l ?第2位:表示Tx FIFO的復位。

置1:會清零UART0 TxFIFO中的所有字節并復位指針邏輯。改位自動清零。

l ?第[5:3]位:保留位,用戶不能對其進行操作。從保留位讀出的值未被定義。

l ?第[7:6]位:表示Rx觸發選擇

00:觸發點為0(默認為1字節)

01:觸發點為1(默認為4字節)

10:觸發點為2(默認為8字節)

11: 觸發點為3(默認為14字節)

注:這兩個位決定在激活中斷之前,接收UART0 FIFO必須寫入個字符。

(2) U0IER(中斷使能寄存器)

A 作用:U0IER用于使能4個UART0中斷源

B 長度:8位寄存器

C每一位的含義:

l ?第0位:表示RBR中斷使能

置1:使能RDA中斷

置0:禁止RDA中斷

注:U0IEER 第零位使能UART0接收數據可用中斷。它還控制(CTI)字符接收超時中斷。

l ?第1位:表示THRE中斷使能

置1:使能THRE中斷

置0:禁止THRE中斷

l ?第2位:表示Rx線狀態中斷使能

置1:使能Rx線狀態中斷

置0:禁止RX線狀態中斷

注:U0IER第二位使能UART0 Rx線狀態中斷。該中斷的狀態可從U0LSR[4:1]讀出

l ?第[7:3]位:是保留位

注:用戶不能向其寫入1.

4>串口初始化程序:void ??UART0_Init(uint32 bps)

4. ?中斷初始化

先來看一下UART0和VIC之間的關系:

1>中斷初始化流程:

l ?選擇中斷為向量中斷或快速中斷

l ?分配中斷通道

l ?設置UART0向量地址

l ?使能UART0中斷

2>關于ARM中斷編程方法和寄存器的使用在此不做涉及(如果想知道的話,可以看這篇文章http://blog.csdn.net/tigerjb/archive/2010/11/30/6045409.aspx

3>中斷初始化程序:void Interrupt_Init (void)

5.用中斷編寫接收函數

1> ?中斷服務函數流程

l ?清除串口中斷標識寄存器(U0IIR)

l ?清除中斷標志

l ?讀取接收FIFO中的數據

2> ?中斷函數服務函數中需要配置的寄存器

(1) U0IIR中斷標識寄存器。

l ?第0位:表示中斷掛起

置1:表示沒有掛起的中斷

置0:表示至少有一個中斷掛起

l ?第[3:1]位:中斷標識,這三位表示了對應UART0 Rx FIFO的中斷。

001:表示發送中斷(THRE)

010: ?表示接收數據可用中斷(RDA)

011: ?表示接收線狀態中斷(RLS)

110: ?表示字符超時中斷(CTI)

l ?第[7:4]:是保留位

注:

1. ???U0IIR提供的狀態碼可用于指示一個掛起中斷的中斷源和優先級。

2. ???在訪問U0IIR過程中,中斷被凍結

3. ???如果在訪問U0IIR時,產生了中斷,該中斷被記錄。在下次訪問U0IIR時可以讀出,避免中斷的丟失。

3> ?中斷服務函數程序:void ??__irq IRQ_UART0(void)

6.總程序:通過上位機給串口發送8字節數據,ARM2200接收到串口數據后,把數據又發送回上位機。

(在用中斷的時候在Startup.S文件中的InitStack子程序中,修改設置系統模式堆棧處的代碼為"MSR CPSR_c,#0x5f",
測試成功 ,在上面上發送16進制數時,每個之間用空格隔開不加前綴。)

#include "config.h" uint8 recver_buffer[8]; uint8 rcv_new; /********************************************************** * 名稱: UART0_Init() * 功能: UART0初始化(通訊波特率115200,8位數據位,1位停止位,無奇偶校驗) * 入口參數: bps 串口波特率 * 出口參數: 無 **********************************************************/ void UART0_Init(uint32 bps) { uint16 Fdiv;PINSEL0 = 0x00000005; //設置串口引腳U0LCR = 0x83; //置為除數鎖存位,進行配置Fdiv = (Fpclk >> 4) / bps; // 設置波特率U0DLM = Fdiv >> 8; U0DLL = Fdiv & 0xff; U0LCR = 0x03; //清除除數鎖存位,并設置工作模式模式U0FCR = 0x81; // 使能FIFO,并設置觸發點為8字節U0IER = 0x01; // 允許RBR中斷,即接收中斷} /********************************************************* * 名 稱: IRQ_UART0 * 功 能: 串口UART0中斷接收8個字節的數據 * 入口參數: 無 * 出口參數: 無 **********************************************************/ void __irq IRQ_UART0(void) { uint8 i;if( 0x04 == (U0IIR&0x0F) ) {rcv_new = 1; // 設置接收到新的數據標志,并清除中斷標志位for(i=0; i<8; i++){recver_buffer[i] = U0RBR; // 讀取FIFO的數據}VICVectAddr = 0;} //清除中斷 } /********************************************************** * 名稱: Interrupt_Init * 功能: 初始化串口中斷,給串口中斷選擇為向量中斷, * 分配向量通道號1給串口 * 入口參數: 無 * 出口參數: 無 **********************************************************/ void Interrupt_Init (void) {VICIntSelect = 0x00000000; // 設置所有通道為IRQ中斷VICVectCntl0 = 0x26; // UART0中斷通道分配到IRQ slot 0,即優先級最高VICVectAddr0 = (int)IRQ_UART0; // 設置UART0向量地址VICIntEnable = 0x00000040; // 使能UART0中斷} /********************************************************** * 名 稱: UART0_SendByte * 功 能: 向串口發送字節數據,并等待發送完畢。 * 入口參數: data 要發送的數據 * 出口參數: 無 **********************************************************/ void UART0_SendByte(uint8 data) {U0THR = data; while(0 == (U0LSR & 0x40)); } /********************************************************** * 名稱: UART0_SendBuf() * 功能: 通過串口發送一幀數據 * 入口參數: *buffer 存放一幀數據 * 出口參數: 無 **********************************************************/ void UART0_SendBuf(uint8 *buffer) {uint8 *pbuffer;uint8 i;for(pbuffer = buffer,i = 0;i < 8; i++)UART0_SendByte(*(pbuffer++)); }/********************************************************** * 名稱: main()函數 * 功能: 上位機接收的數據開頭兩個字符為0x10,0x11, * 則原樣輸出,否次輸出0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 * 入口參數: *buffer 存放一幀數據 * 出口參數: 無 **********************************************************/int main (void) { uint8 send_buffer[8] ={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27}; //定義發送幀緩沖區UART0_Init(115200);Interrupt_Init();while(1){if(1 == rcv_new) // 是否已經接收到8 Bytes的數據{ rcv_new = 0; // 清除標志if(0x10 ==recver_buffer[0] && 0x11 == recver_buffer[1]){UART0_SendBuf(send_buffer);}else{UART0_SendBuf(recver_buffer);}} } return 0; }


二.用中斷編寫發送函數
1.中斷初始化

同上和用中斷接收函數時的中斷初始化是一樣的
2.串口初始化
?1>串口初始化流程:
l ?設置I/O引腳連接到UART0
l ?置位除數鎖存位,配置UART0幀格式
l ?根據波特率計算分頻值
l ?設置波特率
l ?清除除數鎖存位,并設置工作模式
l ?使能FIFO,并使TxFIFO復位
l ?使能THRE中斷
? 2>串口初始化函數:void ? UART0_Init(uint32 bps)

3.中斷服務函數:
? 1>中斷服務函數流程:
l ?清除串口中斷標識寄存器
l ?清除中斷控制標識寄存器
? 2>中斷發送服務函數程序:void ? __irq IRQ_UART0(void)

4.用串口中斷發送函數的總程序:通過上位機給串口發送8字節數據,ARM2200接收到串口數據后,用中斷方式把數據又發送回上位機。

#include "config.h" uint8 recver_buffer[8]; uint8 rcv_new; /**************************************************************************** * 名稱: UART0_Init * 功能: UART0初始化 通訊波特率115200,8位數據位,1位停止位,無奇偶校驗 * 使能TxFIFO,和THRE中斷 * 入口參數: bps 串口波特率 * 出口參數: 無 ****************************************************************************/ void UART0_Init(uint32 bps) {uint16 Fdiv;PINSEL0 = (PINSEL0 & ~(0xf) | 0x05) ; //設置UART0的引腳U0LCR = 0x83; //置位除數鎖存位,配置UART0幀格式Fdiv = (Fpclk>>4)/bps; //根據波特率計算分頻值U0DLM = Fdiv>>8; //設置波特率U0DLL = Fdiv%256;U0LCR = 0x03; // 清除除數鎖存位,并設置工作模式U0FCR = 0x05; // 使能TxFIFO,并使TxFIFO復位U0IER = 0x02; // 使能THRE中斷} /**************************************************************************** * 名 稱: UART0_Exception * 功 能: 串口發送中斷 * 入口參數: 無 * 出口參數: data 發送的數據 ****************************************************************************/ void __irq IRQ_UART0(void) { uint32 data;data = U0IIR; //清除中斷表示寄存器標志VICVectAddr = 0; //清除中斷} /********************************************************** * 名稱: Interrupt_Init * 功能: 初始化串口中斷,給串口中斷選擇為向量中斷, * 分配向量通道號1給串口 * 入口參數: 無 * 出口參數: 無 **********************************************************/ void Interrupt_Init (void) {VICIntSelect = 0x00000000; // 設置所有通道為IRQ中斷VICVectCntl0 = 0x26; // UART0中斷通道分配到IRQ slot 0,即優先級最高VICVectAddr0 = (int)IRQ_UART0; // 設置UART0向量地址VICIntEnable = 0x00000040; // 使能UART0中斷} /********************************************************** * 名 稱: UART0_RcvByte * 功 能: 用查詢方式接收一字節的數據 * 入口參數: 無 * 出口參數: data 要接收的數據 **********************************************************/ uint8 UART0_RcvByte(void) {uint8 rcv_data ;while((U0LSR&0X01)==0); //等待數據到達rcv_data = U0RBR; //從U0RBR中讀出接收到的數據return rcv_data; //返回接收到的數據} /********************************************************** * 名稱: UART0_RecBuf() * 功能: 接收串口發送過來的幀數據, * 入口參數: *buffer 存放一幀數據 * 出口參數: 無 **********************************************************/ void UART0_RecBuf (uint8 *buffer) {uint8 *pbuffer;uint8 i;for(pbuffer = buffer, i = 0;i < 8; i++){*(pbuffer++) = UART0_RcvByte();} } /********************************************************** * 名稱: main()函數 * 功能: 上位機接收的數據開頭兩個字符為0x10,0x11, * 則原樣輸出,否次輸出0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 * 入口參數: *buffer 存放一幀數據 * 出口參數: 無 **********************************************************/int main (void) { uint8 i; uint8 send_buffer[8] ={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27}; //定義發送幀緩沖區UART0_Init(115200);Interrupt_Init();while(1){UART0_RecBuf(recver_buffer); //接收8字節數據if(0x10 ==recver_buffer[0] && 0x11 == recver_buffer[1]){ for(i = 0;i < 8 ;i++){U0THR = send_buffer[i]; //用中斷發送每次8字節} }else{for(i = 0;i < 8;i++) //用中斷發送每次8字節{U0THR = recver_buffer[i];}} } return 0; }

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的UART0串口编程(三):中断方式的串口编程;用中断编写发送函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 无码少妇一区二区 | 国产专区自拍 | 中国在线观看免费视频 | 国产乱子伦精品无码码专区 | 免费在线看黄色片 | 在线观看亚洲一区二区 | 又污又黄的网站 | 久久久久综合网 | 一区二区免费在线观看视频 | av成人亚洲| 青青成人在线 | 一区二区三区av夏目彩春 | 国产福利视频一区二区 | 伊人精品在线视频 | 福利视频在线播放 | 日本黄色网络 | 韩国日本美国免费毛片 | 日韩av不卡在线 | 青青草原综合久久大伊人精品 | 操操操操操操 | 小柔的淫辱日记(1~7) | 久久亚洲综合 | 二级毛片 | 亚洲骚图| av手机在线免费观看 | 成人免费无码大片a毛片抽搐色欲 | 暖暖日本在线 | 久久女女 | jizzjizz8| 夜夜草导航| 韩国一区二区三区四区 | www.插插插.com| 午夜av大片 | 婷婷色站| 国产精品自拍网站 | 污视频网站在线观看 | fc2ppv色の美マンに中出し | 福利视频网址 | 黄色日批| 日韩av成人在线观看 | 国产成人一级片 | 欧美高清一区二区三区四区 | 一级淫片a| 久久人成 | 国产日韩欧美二区 | 91手机视频在线观看 | 激情综合啪啪 | 国产精品久久国产 | 久久久99久久 | 97国产成人 | 欧美激情性做爰免费视频 | 亚洲欧美精品在线观看 | 欧美一区二区国产 | 农村搞破鞋视频大全 | 亚洲午夜久久 | 日韩黄色一级视频 | 在线看国产视频 | 精品国产一二三 | 国产999 | 伊人色在线视频 | 狠狠躁夜夜躁人爽 | 小说肉肉视频 | 欧美激情网站 | 日韩精品一区在线 | 国产黄 | 欧美黄色一级 | 亚洲经典在线观看 | 免费人成在线 | 国家队动漫免费观看在线观看晨光 | 精品视频久久久久久 | 免费av动漫 | 久久久久人妻一区 | 美女被艹视频网站 | 欧美视频 | 波多野结衣操 | 欧美精品v国产精品v日韩精品 | 无码人妻精品一区二区中文 | 欧美日本高清视频 | 少女忠诚电影高清免费 | 久久久成人精品 | 成年人看的视频网站 | 久久久久久午夜 | 日韩精品免费一区二区 | 国产日韩第一页 | 99riav国产| 熟女视频一区二区三区 | 久草91| 日韩在线一二三 | 亚洲国产精品久久久久爰性色 | 51妺嘿嘿午夜福利 | 久草福利在线视频 | 日韩三级一区二区三区 | 亚洲av熟女高潮一区二区 | 青青青在线视频免费观看 | 性欧美videossex精品 | 国产日韩精品电影 | 欧美日韩一卡 | 欧美一级片观看 | 亚洲最大av |