加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

【第八讲】TMS320F28335开发板之PIE模块

(2016-04-06 16:21:43)
标签:

教程

软件

仿真软件

分类: DSP

前面几讲我们分别介绍了有关DSP的特点和发展,还有相关实验步骤。但是只学会那些只是最基础需要了解的,真正想要让DSP按照我们的意愿去工作我们还要努力,最起码我们还要深入DSP内部,了解DSP如何实现各种功能,DSP实现每个功能都有一个相应的模块,每个模块负责自己的功能,这就是我们接下来要学习的。

今天我们首先要讲解的是PIE模块(外部中断扩展模块):本讲看完建议结合【第十五讲】TMS320F28335开发板之外部中断(PIE模块补充篇)

1.中断响应过程

TMS320F28335内部有16根中断线,其中包括2根不可屏蔽中断(NMI)和14根可屏蔽中断。可屏蔽中断通过相应中断使能寄存器可以使能或者禁止中断。

外部中断源:DSP芯片IO引脚上的电平变化触发中断;

内部中断源:DSP内部CPU和各个外设模块产生的中断。

在2833X处理器中,定时器1定时器2预留给实时操作系统使用,其中断分配给INT13INT14(系统规定,不需要也不能后续更改);两个不可屏蔽中断各自占用独立的专用中断;剩下12个可屏蔽中断直接接在PIE模块(外部中断扩展模块),供给外部中断和处理器内部外设单元使用。这些中断源被分成8组,每组中断都分别连接至12个CPU核中断(INT1~INT12)中的一个,所以PIE模块支持96个独立的中断源。96个中断都对应有各自的中断向量表,这些向量表存储在特定的RAM模块并且可以后续根据需要更改。CPU响应中断时可自动获取相应的中断向量。在PIE模块中,每个中断都可以独立使能或者禁止。

采用PIE模块的原因在于:由于众多的外设,每个外设在相应事件发生时都可以产生一个或者多个中断,但CPU无法及时处理这么多的外设中断请求,因此用PIE模块作为控制器来仲裁来自外设和外部引脚的中断请求。

PIE向量表用来存储系统中每个中断服务(ISR)的入口地址,每个中断源都有一个中断向量。在设备初始化时就要设置好中断向量表。

http://s6/middle/0034sXQLzy70HrDLWkZ55&690首先解释几个名词:

IFR:中断标志寄存器    IER:中断使能寄存器

PIEIFR:PIE中断标志寄存器    PIEIER:PIE中断使能寄存器

INTx.y:表示中断,从(INT1.1~INT1.8)——(INT12.1~INT12.8)共96个中断源

(当中断发生时,CPU可以通过这些寄存器的内容进行解码来判断响应哪一个中断。PIE模块根据寄存器PIEIERx和PIEIFRx的当前值来解码、确定CPU所需要的中断向量地址。CPU进入中断后会自动清除PIEIFRx.y位。需要注意的是,PIEIERx寄存器用来决定哪一个中断向量被用来作为跳转地址,所以在清除PIEIERx.y时必须谨慎。)

从图中可以看出:

PIE模块将外设或外部引脚的每8个中断复用一个CPU级(外设级)中断信号。PIE模块将所有中断源分成12组。在同一个PIE分组的将共用一个CPU中断,例如PIE分组1(INT1.y)中的中断共用INT1(CPU中断1),PIE分组12(INT12.y)中的中断共用INT12(CPU中断12)。对于直接连到CPU级的中断源不需要与其他中断源复用。例如,定时器1和定时器2的专用中断INT13和INT14.

对于同一分组的中断在PIE模块中有其相应的PIEIFRx.y和PIEIERx.y(x:1~12 y:1~8),其中x表示第x组,y表示第y个中断。另外,每组中断还对应一个中断应答位PIEACKxx:1~12

一旦外设向PIE请求中断时,PIE相应的中断标志位PIEIFRx.y就会置位,如果该组的中断使能位PIEIERx.y此时也置位,那PIE就会检查相应的PIEACKx位判断CPU是否准备好响应该组的中断。如果PIEACKx被置位(PIEACKx=1,CPU没有准备好响应该中断),则PIE将等待直到该位被清零(PIEACKx=0,CPU准备好响应该中断),然后发送中断请求至INTx,此时PIEACKx被硬件置位,以等待处理下一次中断。

**也许到现在有些人还不能很好理解上面那个图:中断的工作流程,下面我们用工程流图来直观的表示一下:

http://s6/middle/0034sXQLzy70HrE0brvb5&690

从这个流程图可以很清楚的看出来中断响应过程。

2.PIE寄存器(稍微介绍一下,需要具体的的请查阅手册)

 

  • PIE控制寄存器(PIECTRL):用户可以通过获取PIEVECT位的值来确定哪一个中断请求获取向量。
  • PIE中断应答寄存器(PIEACK):每一位代表相应一个PIE分组。当相应位为0,表示该位所在分组可以向CPU发送中断请求。向该位写0无效。
  • PIE中断标志寄存器(PIEIFRx,x=1~12)
  • PIE中断使能寄存器(PIEIERx,x=1~12)
  • CPU中断标志寄存器(IFR)
  • CPU中断使能寄存器(IER)
  • CPU调试中断使能寄存器(DBGIER) 很少用到
  • 外部中断控制寄存器(XINTnCR,n=1~7):2833x系列的期器件支持外部中断XINT1~XINT7,另外XINT13被复用为不可屏蔽中断。每一个外部中断都可以设置成上升沿、下降沿或上升沿及下降沿触发中断,也可以使能或禁止(包括NMI)。Ploarity位是中断极性位。该位用来确定外部引脚的上升沿或下降沿信号产生中断。
    • 00 下降沿产生中断;
    • 01 上升沿产生中断;
    • 10 下降沿产生中断;
    • 11 上升沿或下降沿产生中断。
  • 外部不可屏蔽中断控制寄存器(XNMICR):Ploarity位同上,Select位是INT13中断源选择位:0,定时器1中断源;1,XNMI_XINT13中断源
  • 外部中断1、2和不可屏蔽中断寄存器(XINT1CTR、XINT2CTR、XNMICTR):对于XINT1、XINT2和XNMI,分别具有一个16位的计数器,计数器的数值在检测到中断触发边沿时复位至0,可以用来记录中断发生的时间。
3.PIE中断向量表

********************************************************************************************************************

以上主要讲了硬件部分,下面我们就实验来讲一下软件编程问题:

1.Example_2833xCpuTimer.c 【CPU定时器中断实验】

按照前面所讲的实验的步骤来,加载Example_2833xCpuTimer项目,来观察软件内部中断响应是如何完成的。(以定时器0为例)下面给出相关函数,我也会将中断相关函数解释一下,目前能看懂就行,以后还要系统学习。

 

  1. // TI File $Revision: /main/14 $
  2. // Checkin $Date: April 21, 2008 15:41:07 $
  3. //###########################################################################
  4. //
  5. // FILE: Example_2833xCpuTimer.c
  6. //
  7. // TITLE: DSP2833x Device Getting Started Program.
  8. //
  9. // ASSUMPTIONS:
  10. //
  11. // This program requires the DSP2833x header files.
  12. //
  13. // Other then boot mode configuration, no other hardware configuration
  14. // is required.
  15. //
  16. //
  17. // As supplied, this project is configured for "boot to SARAM"
  18. // operation. The 2833x Boot Mode table is shown below.
  19. // For information on configuring the boot mode of an eZdsp,
  20. // please refer to the documentation included with the eZdsp,
  21. //
  22. // $Boot_Table:
  23. //
  24. // GPIO87 GPIO86 GPIO85 GPIO84
  25. // XA15 XA14 XA13 XA12
  26. // PU PU PU PU
  27. // ==========================================
  28. // 1 1 1 1 Jump to Flash
  29. // 1 1 1 0 SCI-A boot
  30. // 1 1 0 1 SPI-A boot
  31. // 1 1 0 0 I2C-A boot
  32. // 1 0 1 1 eCAN-A boot
  33. // 1 0 1 0 McBSP-A boot
  34. // 1 0 0 1 Jump to XINTF x16
  35. // 1 0 0 0 Jump to XINTF x32
  36. // 0 1 1 1 Jump to OTP
  37. // 0 1 1 0 Parallel GPIO I/O boot
  38. // 0 1 0 1 Parallel XINTF boot
  39. // 0 1 0 0 Jump to SARAM <- "boot to SARAM"
  40. // 0 0 1 1 Branch to check boot mode
  41. // 0 0 1 0 Boot to flash, bypass ADC cal
  42. // 0 0 0 1 Boot to SARAM, bypass ADC cal
  43. // 0 0 0 0 Boot to SCI-A, bypass ADC cal
  44. // Boot_Table_End$
  45. //
  46. // DESCRIPTION:
  47. //
  48. // This example configures CPU Timer0, 1, and 2 and increments
  49. // a counter each time the timers assert an interrupt.
  50. //
  51. // Watch Variables:
  52. // CpuTimer0.InterruptCount
  53. // CpuTimer1.InterruptCount
  54. // CpuTimer2.InterruptCount
  55. //
  56. //###########################################################################
  57. // $TI Release: DSP2833x/DSP2823x Header Files V1.20 $
  58. // $Release Date: August 1, 2008 $
  59. //###########################################################################
  60. #include "DSP28x_Project.h" // Device Headerfile and Examples Include File
  61. // Prototype statements for functions found within this file.
  62. interrupt void cpu_timer0_isr(void);     //这里是中断服务程序的声明;
  63. interrupt void cpu_timer1_isr(void); //注意前面要加上interrupt
  64. interrupt void cpu_timer2_isr(void); //才能将函数声明为中断函数 。
  65. void main(void) //以下是主函数;
  66. {
  67. // Step 1. Initialize System Control:
  68. // PLL, WatchDog, enable Peripheral Clocks
  69. // This example function is found in the DSP2833x_SysCtrl.c file.
  70. InitSysCtrl(); //系统初始化;
  71. // Step 2. Initalize GPIO:
  72. // This example function is found in the DSP2833x_Gpio.c file and
  73. // illustrates how to set the GPIO to it's default state.
  74. // InitGpio(); // Skipped for this example
  75. // Step 3. Clear all interrupts and initialize PIE vector table:
  76. // Disable CPU interrupts
  77. DINT; //关闭CPU中断;
  78. // Initialize the PIE control registers to their default state.
  79. // The default state is all PIE interrupts disabled and flags
  80. // are cleared.
  81. // This function is found in the DSP2833x_PieCtrl.c file.
  82. InitPieCtrl(); //PIE初始化;
  83. // Disable CPU interrupts and clear all CPU interrupt flags:
  84. IER = 0x0000; //中断使能寄存器初始化;
  85. IFR = 0x0000; //中断标志寄存器初始化;
  86. // Initialize the PIE vector table with pointers to the shell Interrupt
  87. // Service Routines (ISR).
  88. // This will populate the entire table, even if the interrupt
  89. // is not used in this example. This is useful for debug purposes.
  90. // The shell ISR routines are found in DSP2833x_DefaultIsr.c.
  91. // This function is found in DSP2833x_PieVect.c.
  92. InitPieVectTable(); //PIE中断向量表初始化;
  93. // Interrupts that are used in this example are re-mapped to
  94. // ISR functions found within this file.
  95. EALLOW; // This is needed to write to EALLOW protected registers //注意这里的EALLOW和
  96. PieVectTable.TINT0 = &cpu_timer0_isr; //EDIS是必须的,为了
  97. PieVectTable.XINT13 = &cpu_timer1_isr; //允许向受保护的寄存器
  98. PieVectTable.TINT2 = &cpu_timer2_isr; //写入中断服务程序的入 //口地址
  99. EDIS; // This is needed to disable write to EALLOW protected registers
  100. // Step 4. Initialize the Device Peripheral. This function can be
  101. // found in DSP2833x_CpuTimers.c
  102. InitCpuTimers(); // For this example, only initialize the Cpu Timers //初始化CPU定时器
  103. #if (CPU_FRQ_150MHZ)
  104. // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
  105. // 150MHz CPU Freq, 1 second Period (in uSeconds)
  106. ConfigCpuTimer(&CpuTimer0, 150, 1000000);
  107. ConfigCpuTimer(&CpuTimer1, 150, 1000000);
  108. ConfigCpuTimer(&CpuTimer2, 150, 1000000);
  109. #endif
  110. #if (CPU_FRQ_100MHZ)
  111. // Configure CPU-Timer 0, 1, and 2 to interrupt every second:
  112. // 100MHz CPU Freq, 1 second Period (in uSeconds)
  113. ConfigCpuTimer(&CpuTimer0, 100, 1000000);
  114. ConfigCpuTimer(&CpuTimer1, 100, 1000000);
  115. ConfigCpuTimer(&CpuTimer2, 100, 1000000);
  116. #endif
  117. // To ensure precise timing, use write-only instructions to write to the entire register. Therefore, if any
  118. // of the configuration bits are changed in ConfigCpuTimer and InitCpuTimers (in DSP2833x_CpuTimers.h), the
  119. // below settings must also be updated.
  120. CpuTimer0Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0 //这部分等讲到定时器再说
  121. CpuTimer1Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
  122. CpuTimer2Regs.TCR.all = 0x4001; // Use write-only instruction to set TSS bit = 0
  123. // Step 5. User specific code, enable interrupts:
  124. // Enable CPU int1 which is connected to CPU-Timer 0, CPU int13
  125. // which is connected to CPU-Timer 1, and CPU int 14, which is connected
  126. // to CPU-Timer 2:
  127. IER |= M_INT1; //使定时器0、1、2中断使能寄存器使能;
  128. IER |= M_INT13;
  129. IER |= M_INT14;
  130. // Enable TINT0 in the PIE: Group 1 interrupt 7
  131. PieCtrlRegs.PIEIER1.bit.INTx7 = 1; //PIE中断使能寄存器使能,即PIEIER1.7=1
  132. //之所以在这里没有定时器1和2的PIE中断使能寄存器,
  133. //因为它们的中断直接到CPU级而不经过PIE级
  134. // Enable global Interrupts and higher priority real-time debug events:
  135. EINT; // Enable Global interrupt INTM
  136. ERTM; // Enable Global realtime interrupt DBGM
  137. // Step 6. IDLE loop. Just sit and loop forever (optional):
  138. for(;;);
  139. }
  140. interrupt void cpu_timer0_isr(void) //定时器0的中断服务程序;
  141. {
  142. CpuTimer0.InterruptCount++;
  143. // Acknowledge this interrupt to receive more interrupts from group 1
  144. PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //中断应答位,想要了解PIEACK_GROUP1变量可以用
  145. //前面实验中提到的“Open Declaration”来查看定义
  146. //经查看这里的PIEACK_GROUP1用的宏定义
  147. }
  148. interrupt void cpu_timer1_isr(void)
  149. {
  150. CpuTimer1.InterruptCount++; //定时器0中断次数;
  151. // The CPU acknowledges the interrupt.
  152. EDIS;
  153. }
  154. interrupt void cpu_timer2_isr(void)
  155. { EALLOW;
  156. CpuTimer2.InterruptCount++;
  157. // The CPU acknowledges the interrupt.
  158. EDIS;
  159. }
  160. //===========================================================================
  161. // No more.
  162. //===========================================================================

好啦,这一节课讲了有关PIE模块的硬件部分和软件编程部分,这里只是初步讲解,实际用到时可以查阅相关资料。






0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有