考虑一个简单的数字手表,它的编程功能只是向您显示时间,现在假设您想更改其时区。你会怎么做?您只需按下一个按钮即可更改菜单,使您可以更改时区。在这里,系统无法预测您的外部中断对其计时过程的影响,也无法要求您等待,因为它正忙于增加手表的秒数。这是中断派上用场的地方。
中断不必总是外部的。它也可以是内部的。嵌入式中断中的大多数时间也可以促进CPU的两个外设之间的通信。考虑到预设的计时器被重置,并且当时间达到计时器寄存器中的值时触发中断。中断处理程序可用于启动其他外设,例如DMA。
在本教程中,我们使用了MSP430上的外部中断来切换不同的LED。当使用按钮通过状态改变给出外部中断时,控制权被转移(抢占)到ISR,并且它是有需要的。要了解诸如MSP430G2启动板的CCS环境设置之类的基础知识,请遵循使用CCS的MSP430入门链接,因为在本教程中我们不会对此进行详细介绍。也可以通过以下链接查看使用Energia IDE和CCS的其他基于MSP430的教程。
为什么我们需要中断?
需要中断以节省嵌入式系统中的轮询开销。当需要通过抢占当前正在运行的任务来执行优先级更高的任务时,将调用它们。它还可以用于将CPU从低功耗模式唤醒。当外部信号通过GPIO端口的边沿转换唤醒时,将执行ISR,CPU再次返回低功耗模式。
MSP430中的中断类型
MSP430中的中断分为以下几种类型:
- 系统重置
- 不可屏蔽中断
- 可屏蔽中断
- 向量中断和非向量中断
系统重置:
它可能是由于电源电压(Vcc)和RST / NMI引脚上的低信号(选择了复位模式)引起的,也可能是由于看门狗定时器溢出和违反安全密钥的原因而发生的。
不可屏蔽中断:
这些中断不能被CPU指令屏蔽。一旦启用了通用中断,就不能将不可屏蔽中断从处理中转移。这是由振荡器故障和手动赋予RST / NMI的边沿(在NMI模式下)之类的源产生的。
可屏蔽中断:
如果发生中断,并且可以通过CPU指令屏蔽该中断,则该中断为可屏蔽中断。他们不必总是外部的。它们还取决于外围设备及其功能。此处使用的外部端口中断属于此类别。
向量中断和非向量中断:
向量化:在这种情况下,中断设备通过传递中断向量地址为我们提供了中断源。在这里,ISR的地址是固定的,控制权被转移到该地址,而ISR负责其余的工作。
非向量: 这里所有的中断都有共同的ISR。当来自非向量源的中断发生时,控制权转移到所有非向量中断共享的公共地址。
MSP430中的中断程序控制
发生中断时,MCLK变为ON,并且CPU从OFF状态被调用回。中断发生后,由于程序控制权被转移到ISR地址,因此程序计数器和状态寄存器中的值将移入堆栈。
连续清除状态寄存器,从而清除GIE并终止低功耗模式。通过将中断向量地址放在程序计数器中,可以选择并执行优先级最高的中断。在获得MSP430 GPIO中断示例代码之前,了解其中涉及的端口寄存器的工作非常重要。
MSP430上用于GPIO控制的端口寄存器:
PxDIR:它是端口方向控制寄存器。它允许程序员通过写入0或1专门选择其功能。如果将某个引脚选择为1,则它将用作输出。将端口1视为8位端口,如果将引脚2和3分配为输出端口,则必须将P1DIR寄存器设置为0x0C。
PxIN:这是只读寄存器,可以使用该寄存器读取端口中的当前值。
PxOUT:该特定寄存器可用于直接将值写入端口。仅当上拉/下拉寄存器被禁用时才有可能。
PxREN:这是一个8位寄存器,用于启用或禁用上拉/下拉寄存器。当PxREN和PxOUT寄存器中的某个引脚都设置为1时,该特定引脚将被上拉。
红外 |
PxREN |
输出端 |
I / O配置 |
0 |
0 |
X |
禁用电阻输入 |
0 |
1个 |
0 |
输入启用内部下拉 |
0 |
1个 |
1个 |
输入启用内部上拉 |
1个 |
X |
X |
输出– PxREN无效 |
PxSEL和PxSEL2:由于MSP430中的所有引脚都是多路复用的,因此必须在使用前选择特定功能。当特定引脚的PxSEL和PxSEL2寄存器都设置为0时,则选择通用I / O。当PxSEL设置为1时,将选择主要外设功能,依此类推。
PxIE:启用或禁用端口x中特定引脚的中断。
PxIES:选择产生中断的边沿。对于0,选择上升沿,对于1,选择下降沿。
MSP430测试GPIO中断的电路
下面显示了用于测试我们的MSP430中断示例代码的MSP430电路。
电路板的接地用于将LED和按钮都接地。按钮的对角线相对的侧面是常开端子,当按钮被按下时会连接。在LED之前连接一个电阻,以避免LED消耗大量电流。通常,使用100ohm – 220ohm范围内的低电阻。
我们使用3种不同的代码来更好地了解端口中断。前两个代码使用与电路图1相同的电路。让我们深入研究代码。建立连接后,我的设置如下所示。
对MSP430进行中断编程
完整的MSP430中断程序可在本页底部找到,代码说明如下。
下面的行使看门狗定时器停止运行。看门狗定时器通常执行两个操作。一种是通过重置控制器来防止控制器陷入无限循环,另一种是它使用内置计时器触发周期性事件。当微控制器被重置(或加电)时,它处于定时器模式,并且倾向于在32毫秒后重置MCU。此行阻止控制器执行此操作。
WDTCTL = WDTPW + WDTHOLD;
将P1DIR寄存器的值设置为0x07,可以将pin0,pin1和pin2的方向设置为输出。将P1OUT设置为0x30可以将其配置为在引脚4和引脚5上使能内部上拉电阻的输入。将P1REN设置为0x30可以在这些引脚上进行内部上拉。P1IE使能中断,其中P1IES选择从高到低的跳变作为这些引脚上的中断沿。
P1DIR-= 0x07; P1OUT = 0x30; P1REN-= 0x30; P1IE-= 0x30; P1IES-= 0x30; P1IFG&=〜0x30;
下一行启用低功耗模式并启用状态寄存器中的GIE,以便可以接收中断。
__bis_SR_register(LPM4bits + GIE)
使用宏将程序计数器设置为端口1向量的地址。
PORT1_VECTOR 。 #pragma vector = PORT1_VECTOR __interrupt void Port_1(void)
以下代码逐一切换连接到引脚0,引脚1,引脚2的每个LED。
if(count%3 == 0) { P1OUT ^ = BIT1; P1IFG&=〜0x30; 数++; } else if(count%3 == 1) { P1OUT ^ = BIT1; P1IFG&=〜0x30; 数++; } else { P1OUT ^ = BIT2; P1IFG&=〜0x30; 数++; }
电路图2:
同样,让我们尝试使用其他引脚更好地理解该概念。因此,此处的按钮连接到引脚2.0而不是引脚1.5。修改后的电路如下。同样,该电路用于测试MSP430按钮中断程序。
此处端口2用于输入。因此必须使用不同的中断向量。P1.4和P2.0接受输入。
由于端口2仅用于输入,因此P2DIR设置为0。要在启用内部上拉电阻的情况下将端口2的pin0设置为输入,必须将寄存器P2OUT和P2REN设置为1。在端口2的引脚0上中断并选择中断的边沿,将P2IE和P2IES的值设置为1。要重置端口2中的标志,P2IFG被清除,以便可以在端口2上再次设置该标志。发生中断。
P2DIR-= 0x00; P2OUT = 0x01; P2REN-= 0x01; P2IE-= 0x01; P2IES-= 0x01; P2IFG&=〜0x01;
当中断源来自端口1时,连接到端口1的引脚1的LED发光。当中断源属于端口2时,连接到端口1的引脚2的LED发光。
#pragma vector = PORT1_VECTOR __interrupt void Port_1(void) { P1OUT ^ = BIT1; P1IFG&=〜0x10; for(i = 0; i <20000; i ++) { } P1OUT ^ = BIT1; } #pragma vector = PORT2_VECTOR __interrupt void Port_2(void) { P1OUT ^ = BIT2; P2IFG&=〜0x01; for(j = 0; j <20000; j ++) { } P1OUT ^ = BIT2; }
从CCS上载程序到MSP430
要将项目加载到启动板并对其进行调试,请选择项目,然后单击工具栏中的调试图标。或者,按F11或单击RunàDebug进入调试模式。
进入调试模式后,按绿色运行按钮可自由运行MCU中已加载的代码。现在,当按下按钮时,边沿的变化会触发中断,从而提示LED状态的变化。
MSP430上的中断程序
成功上传代码后,我们只需使用按钮即可对其进行测试。每当使用按钮发出中断时,LED模式就会根据我们的程序而改变。
完整的工作可以在下面的视频链接中找到。希望您喜欢本教程并学到了一些有用的东西。如果您有任何疑问,请将其留在评论部分或将我们的论坛用于其他技术问题。