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

新聞中心

EEPW首頁 > 嵌入式系統 > 設計應用 > ARM中斷方式串口編程

ARM中斷方式串口編程

作者: 時間:2016-11-09 來源:網絡 收藏
串口編程(UART0)之中斷方式

---------------------------------------------------------

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

from:blog.csdn.net/tigerjb

Email:jibo.tiger@gmail.com

---------------------------------------------------------

三.中斷方式的串口編程

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)。

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

lU0IER可以控制UART0的4個中斷源。

4>UART0有4個中斷源:

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

(1)優先級最高

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

l幀錯誤(FE)

l溢出錯誤(OE)

l奇偶錯誤(PE)

l間隔中斷(BI)

注:

Ø可以通過查看U0LSR[4:1]中的值看到產生該中斷的錯誤條件

Ø讀取U0LSR寄存器時清除該中斷。

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

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

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

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

l中斷過程:

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

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

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

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

(1)優先級為2.

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

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

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

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

(5)中斷過程:

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

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

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

注:

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

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

D.THRE(發送)中斷

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

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

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

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

(because:如果發送移位寄存器為空,那么寫入發送FIFO的數據將直接進入發送移位寄存器。此時發送FIFO仍然為空,如果立即產生THRE中斷,就會影響緊接著寫入發送FIFO的數據。

所以在發送完該一個字節以及一個停止位后,才產生THRE中斷。

l如果在發送FIFO中有過兩個字節以上的數據,但是現在發送FIFO為空時,將立即觸發THRE中斷。

l當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>中斷串口初始化需要配置的寄存器

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

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

lU0IER(中斷使能寄存器):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>串口初始化程序:

*

*作者:tiger-john

*時間:2011年1月18日

*名稱:UART0_Init

*功能:UART0初始化通訊波特率115200,8位數據位,1位停止位,無奇偶校驗

*接收FIFO觸發點為8字節,使能RDR(接收數據)中斷

*入口參數:bps串口波特率

*出口參數:無

/

voidUART0_Init(uint32 bps)

{

uint16Fdiv;

PINSEL0 = (PINSEL0 & ~(0xf) | 0x05) ;//設置UART0的引腳

U0LCR = 0x83;//置為除數鎖存位,進行配置

Fdiv = (Fpclk>>4)/bps;

U0DLM = Fdiv>>8;

U0DLL = Fdiv%256;

U0LCR = 0x03;//清除除數鎖存位,并設置工作模式

U0FCR = 0x81;//使能FIFO,并設置觸發點為8字節

U0IER = 0x01;//允許RBR中斷,即接收中斷

}

5.中斷初始化

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

1>中斷初始化流程:

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

l分配中斷通道

l設置UART0向量地址

l使能UART0中斷

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

3>中斷初始化程序:

/

*作者:tiger-john

*時間:2011年1月18日

*名稱:Interrupt_Init

*功能:初始化串口中斷,給串口中斷選擇為向量中斷,分配向量通道號1給串口

*入口參數:無

*出口參數:無

/

void Interrupt_Init (void)

{

VICIntSelect = 0x00000000;//設置所有通道為IRQ中斷

VICVectCntl1 = (0x20 | 6);// UART0中斷通道分配到IRQ slot 1

VICVectAddr1 = (uint32)UART0_Exception; //設置UART0向量地址

VICIntEnable = 1 << 6;//使能串口中斷

}

6.用中斷編寫接收函數

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>中斷服務函數程序:

/* *名稱:IRQ_UART0()

*功能:串口UART0中斷接收8個字節的數據

*入口參數:無

*出口參數:無

/

uint8rcv_buf[8];// UART0數據接收緩沖區

void__irq IRQ_UART0(void)

{uint8i;

uint32 data;

data = U0IIR;//清除中斷表示寄存器標志

VICVectAddr = 0;//清除中斷

for(i=0; i<8; i++)

{

rcv_buf[i] = U0RBR;//讀取FIFO的數據

}

}

7.看一個總程序:

view plaincopy to clipboardprint?
  1. /Copyright(c)
  2. 西安郵電學院
  3. graduateschool
  4. XNMS實驗室
  5. Author:冀博
  6. Time:2011年1月20日
  7. http://blog.csdn.net/tigerjb
  8. --------------FileInfo-------------------------------------------------------------------------------
  9. Filename:UART0_while
  10. LastmodifiedDate:2011-01-20
  11. LastVersion:1.0
  12. Descriptions:通過上位機給串口發送8字節數據,ARM2200接收到串口數據后,把數據又發送回上位機
  13. ------------------------------------------------------------------------------------------------------*/
  14. /
  15. Modifiedby:TIGER0-JOHN
  16. Modifieddate:2011-1-21
  17. Version:2.0
  18. Descriptions:測試成功
  19. 在用中斷的時候在Startup.S文件中的InitStack子程序中,修改設置
  20. 系統模式堆棧處的代碼為"MSRCPSR_c,#0x5f"
  21. 測試成功,在上面上發送16進制數時,每個之間用空格隔開
  22. 不加前綴
  23. /
  24. #include"config.h"
  25. uint8recver_buffer[8];
  26. uint8rcv_new;
  27. /
  28. *名稱:UART0_Init()
  29. *功能:UART0初始化(通訊波特率115200,8位數據位,
  30. 1位停止位,無奇偶校驗)
  31. *入口參數:bps串口波特率
  32. *出口參數:無
  33. /
  34. voidUART0_Init(uint32bps)
  35. {
  36. uint16Fdiv;
  37. PINSEL0=0x00000005;//設置串口引腳
  38. U0LCR=0x83;//置為除數鎖存位,進行配置
  39. Fdiv=(Fpclk>>4)/bps;//設置波特率
  40. U0DLM=Fdiv>>8;
  41. U0DLL=Fdiv&0xff;
  42. U0LCR=0x03;//清除除數鎖存位,并設置工作模式模式
  43. U0FCR=0x81;//使能FIFO,并設置觸發點為8字節
  44. U0IER=0x01;//允許RBR中斷,即接收中斷
  45. }
  46. /*
  47. *名稱:IRQ_UART0
  48. *功能:串口UART0中斷接收8個字節的數據
  49. *入口參數:無
  50. *出口參數:無
  51. /
  52. void__irqIRQ_UART0(void)
  53. {uint8i;
  54. if(0x04==(U0IIR&0x0F))
  55. {
  56. rcv_new=1;//設置接收到新的數據標志,并清除中斷標志位
  57. for(i=0;i<8;i++)
  58. {
  59. recver_buffer[i]=U0RBR;//讀取FIFO的數據
  60. }
  61. VICVectAddr=0;
  62. }//清除中斷
  63. }
  64. /
  65. *名稱:Interrupt_Init
  66. *功能:初始化串口中斷,給串口中斷選擇為向量中斷,
  67. *分配向量通道號1給串口
  68. *入口參數:無
  69. *出口參數:無
  70. /
  71. voidInterrupt_Init(void)
  72. {
  73. VICIntSelect=0x00000000;//設置所有通道為IRQ中斷
  74. VICVectCntl0=0x26;//UART0中斷通道分配到IRQslot0,即優先級最高
  75. VICVectAddr0=(int)IRQ_UART0;//設置UART0向量地址
  76. VICIntEnable=0x00000040;//使能UART0中斷
  77. }
  78. /
  79. *名稱:UART0_SendByte
  80. *功能:向串口發送字節數據,并等待發送完畢。
  81. *入口參數:data要發送的數據
  82. *出口參數:無
  83. /
  84. voidUART0_SendByte(uint8data)
  85. {
  86. U0THR=data;
  87. while(0==(U0LSR&0x40));
  88. }
  89. /
  90. *名稱:UART0_SendBuf()
  91. *功能:通過串口發送一幀數據
  92. *入口參數:*buffer存放一幀數據
  93. *出口參數:無
  94. /
  95. voidUART0_SendBuf(uint8*buffer)
  96. {
  97. uint8*pbuffer;
  98. uint8i;
  99. for(pbuffer=buffer,i=0;i<8;i++)
  100. UART0_SendByte(*(pbuffer++));
  101. }
  102. /
  103. *名稱:main()函數
  104. *功能:上位機接收的數據開頭兩個字符為0x10,0x11,
  105. *則原樣輸出,否次輸出0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
  106. *入口參數:*buffer存放一幀數據
  107. *出口參數:無
  108. /
  109. intmain(void)
  110. {
  111. uint8send_buffer[8]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27};//定義發送幀緩沖區
  112. UART0_Init(115200);
  113. Interrupt_Init();
  114. while(1)
  115. {
  116. if(1==rcv_new)//是否已經接收到8Bytes的數據
  117. {
  118. rcv_new=0;//清除標志
  119. if(0x10==recver_buffer[0]&&0x11==recver_buffer[1])
  120. {
  121. UART0_SendBuf(send_buffer);
  122. }
  123. else
  124. {
  125. UART0_SendBuf(recver_buffer);
  126. }
  127. }
  128. }
  129. return0;
  130. }
  131. /*
  132. EndOfFile
  133. /

四.用中斷編寫發送函數

1.中斷初始化

同上和用中斷接收函數時的中斷初始化是一樣的

2.串口初始化

1>串口初始化流程:

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

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

l根據波特率計算分頻值

l設置波特率

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

l使能FIFO,并使TxFIFO復位

l使能THRE中斷

2>串口初始化函數:

/

*名稱:UART0_Init

*功能:UART0初始化通訊波特率115200,8位數據位,1位停止位,無奇偶校驗

*使能TxFIFO,和THRE中斷

*入口參數:bps串口波特率

*出口參數:無

/

voidUART0_Init(uint32 bps)

{

uint16Fdiv;

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中斷

}

3中斷服務函數:

1>中斷服務函數流程:

l清除串口中斷標識寄存器

l清除中斷控制標識寄存器

2>中斷發送服務函數程序:

/

*名稱:UART0_Exception

*功能:串口發送中斷

*入口參數:無

*出口參數:data發送的數據

/

void__irq IRQ_UART0(void)

{

uint32 data;

data = U0IIR;//清除中斷表示寄存器標志

VICVectAddr = 0;//清除中斷

}

4.用串口中斷發送函數的總程序:

view plaincopy to clipboardprint?
  1. /Copyright(c)
  2. 西安郵電學院
  3. graduateschool
  4. XNMS實驗室
  5. Author:冀博
  6. Time:2011年1月20日
  7. http://blog.csdn.net/tigerjb
  8. --------------FileInfo-------------------------------------------------------------------------------
  9. Filename:UART0_while
  10. LastmodifiedDate:2011-01-20
  11. LastVersion:1.0
  12. Descriptions:通過上位機給串口發送8字節數據,ARM2200接收到串口數據后,用中斷方式把數據又發送回上位機
  13. ------------------------------------------------------------------------------------------------------*/
  14. /
  15. Modifiedby:TIGER0-JOHN
  16. Modifieddate:2011-1-21
  17. Version:2.0
  18. Descriptions:測試成功
  19. 在用中斷的時候在Startup.S文件中的InitStack子程序中,修改設置
  20. 系統模式堆棧處的代碼為"MSRCPSR_c,#0x5f"
  21. 測試成功,在上面上發送16進制數時,每個之間用空格隔開
  22. 不加前綴
  23. /
  24. #include"config.h"
  25. uint8recver_buffer[8];
  26. uint8rcv_new;
  27. /
  28. *名稱:UART0_Init
  29. *功能:UART0初始化通訊波特率115200,8位數據位,1位停止位,無奇偶校驗
  30. *使能TxFIFO,和THRE中斷
  31. *入口參數:bps串口波特率
  32. *出口參數:無
  33. /
  34. voidUART0_Init(uint32bps)
  35. {
  36. uint16Fdiv;
  37. PINSEL0=(PINSEL0&~(0xf)|0x05);//設置UART0的引腳
  38. U0LCR=0x83;//置位除數鎖存位,配置UART0幀格式
  39. Fdiv=(Fpclk>>4)/bps;//根據波特率計算分頻值
  40. U0DLM=Fdiv>>8;//設置波特率
  41. U0DLL=Fdiv%256;
  42. U0LCR=0x03;//清除除數鎖存位,并設置工作模式
  43. U0FCR=0x05;//使能TxFIFO,并使TxFIFO復位
  44. U0IER=0x02;//使能THRE中斷
  45. }
  46. /
  47. *名稱:UART0_Exception
  48. *功能:串口發送中斷
  49. *入口參數:無
  50. *出口參數:data發送的數據
  51. /
  52. void__irqIRQ_UART0(void)
  53. {
  54. uint32data;
  55. data=U0IIR;//清除中斷表示寄存器標志
  56. VICVectAddr=0;//清除中斷
  57. }
  58. /
  59. *名稱:Interrupt_Init
  60. *功能:初始化串口中斷,給串口中斷選擇為向量中斷,
  61. *分配向量通道號1給串口
  62. *入口參數:無
  63. *出口參數:無
  64. /
  65. voidInterrupt_Init(void)
  66. {
  67. VICIntSelect=0x00000000;//設置所有通道為IRQ中斷
  68. VICVectCntl0=0x26;//UART0中斷通道分配到IRQslot0,即優先級最高
  69. VICVectAddr0=(int)IRQ_UART0;//設置UART0向量地址
  70. VICIntEnable=0x00000040;//使能UART0中斷
  71. }
  72. /
  73. *名稱:UART0_RcvByte
  74. *功能:用查詢方式接收一字節的數據
  75. *入口參數:無
  76. *出口參數:data要接收的數據
  77. /
  78. uint8UART0_RcvByte(void)
  79. {
  80. uint8rcv_data;
  81. while((U0LSR&0X01)==0);//等待數據到達
  82. rcv_data=U0RBR;//從U0RBR中讀出接收到的數據
  83. returnrcv_data;//返回接收到的數據
  84. }
  85. /
  86. *名稱:UART0_RecBuf()
  87. *功能:接收串口發送過來的幀數據,
  88. *入口參數:*buffer存放一幀數據
  89. *出口參數:無
  90. /
  91. voidUART0_RecBuf(uint8*buffer)
  92. {
  93. uint8*pbuffer;
  94. uint8i;
  95. for(pbuffer=buffer,i=0;i<8;i++)
  96. {
  97. *(pbuffer++)=UART0_RcvByte();
  98. }
  99. }
  100. /
  101. *名稱:main()函數
  102. *功能:上位機接收的數據開頭兩個字符為0x10,0x11,
  103. *則原樣輸出,否次輸出0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27
  104. *入口參數:*buffer存放一幀數據
  105. *出口參數:無
  106. /
  107. intmain(void)
  108. {
  109. uint8i;
  110. uint8send_buffer[8]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27};//定義發送幀緩沖區
  111. UART0_Init(115200);
  112. Interrupt_Init();
  113. while(1)
  114. {
  115. UART0_RecBuf(recver_buffer);//接收8字節數據
  116. if(0x10==recver_buffer[0]&&0x11==recver_buffer[1])
  117. {
  118. for(i=0;i<8;i++)
  119. {
  120. U0THR=send_buffer[i];//用中斷發送每次8字節
  121. }
  122. }
  123. else
  124. {
  125. for(i=0;i<8;i++)//用中斷發送每次8字節
  126. {
  127. U0THR=recver_buffer[i];
  128. }
  129. }
  130. }
  131. return0;
  132. }
  133. /*
  134. EndOfFile
  135. /



評論


技術專區

關閉