msp430的外中断归根到底 其实只需要两个部分的配置就可以了:
1. 引脚配置
2. 中断函数配置
一 引脚配置(以引脚P2.1为例)
P2DIR = 0x01;//配置为输入
P2IE |= 0x01;
P2IES |= 0x01;
其他寄存器可配置,可不配置。注意引脚功能选择为一般引脚,不是功能引脚。虽然引脚的配置很简单,但是只要出错,就无法产生中断。
二 中断函数配置
#pragma vector =PORT2_VECTOR
__interrupt void tangle_make(void)
{
//用户自定义函数
P2IFG = 0x00;
}
中断函数比较简单,只需要记得将中断标志位清0就可以了。
注意:引发外中断的外模块最好能够与系统的电源模块使用一个电源,使用其他电源供电会产生外中断频发状态。
2016年8月18号更新
最近一直卡在外中断和串口中断之间。自己在查看了一会原版的手册之后,发现以下几个问题。
Q1:在外中断程序中开总中断,有的时候总是莫名的卡死。
Q2:给外中断加上外部触发模块,比如红外,门磁等模块时,外中断总是不停的触发。
Q3:外中断触发后,程序还能运行,不过每到串口中断就需要外中断促进程序往下跑。
A1:这个问题涉及到中断嵌套问题。
对于多源中断,需要手动清除标志位。比如:P1、P2的中断,需要手动清楚相应的标志位。如果在这种中断中使用“_EINT();”,开中断,而在打开中断之前,没有进行原来中断标识位的清除工作,就会有相同的中断不断的进行嵌套。而导致堆栈溢出引起复位,所以在这类中断中,必须先清除标志位,再打开中断开关。要不然等着死机吧。
总之,就是说在开总中断之前,需要将多源中断标志位清掉。
A2:这个问题我到现在也不是很明白为什么会这样,不过我还是有几个经验可以写下来。
首先,必须保证硬件的正常,一般的红外模块不需要外加电阻什么的,可以直接接在IO口上。测量红外输出引脚的高低电平是不是正常的,高的时候是不是接近3v,低的时候是不是0v。(在3V情况下,低电平为0.9-1.3V,高电平为1.5-1.9V。1.3V-1.5V为不稳定状态。)
其次,并没有配置什么上拉下拉电阻。就是依照上面的3个寄存器配置的。可以用。(芯片是msp430f149)。
硬件没有问题,就是要用软件来解决了:
第一种方法:在外中断中关闭 外中断使能,然后在外部程序合适的地方再开启。
第二种方法:在外中断中 加入消抖,就可以了。至于为什么,我也不清楚。。
A3:这个问题我到现在也想不通,理不顺,如果有大神看到的话,请一定要留言告诉我。
/*********************2016.10.18更新***************/
在师兄的帮助下整个系统算是完成了。
更正一下上面的一些问题。
对于外部输入到芯片的引脚,首先值得质疑一下:这个输入引脚的状态到底能不能用万用表来测量。我这里给出的答案是不可取的。(感觉可以用示波器查看,原理的话不是很清楚)所以在写完代码后测试的时候,不应该靠万用表的数值来看是不是产生中断,万用表是不靠谱的,建议使用msp430的仿真器来查看,硬件仿真有时候可以解决很多问题。
下面说一下持续的调试过程中的问题和经验。PS:建议使用仿真器,可以大大提高一些自己不必要的考虑因素。前期自己用小灯来测试感觉真的是蠢的出血。
在调试过程中碰到的最大的问题其实是一般人都碰不到的:那就是考虑电流的问题,首先我的板子是自己焊接的,使用430f149驱动外接模块sim900a发送接受数据和继电器驱动锁开门,红外检测门的开关。整个系统使用同一个电源。发现在每次开门后都会自动的发送一个关门的指令。在经过上百次的测试和调试后,我提出可能是当锁开启的时候需要瞬间的电流,导致系统中其他部分的电流不够用,所以红外模块才会产生中断,导致每次都会产生一次关门的指令。
所以在以后的学习中,可以把电流的分流作为一个考虑的因素。
另外,外中断里的内容写的越少越好,buffer的清空,标志位的清空可以放在外中断函数外边实现,这个系统中我使用了P1口的6和7两个引脚来实现检测门的开关。(对于门的状态检测之前想了好多办法,最后采用了使用一个红外模块接到两个引脚上,两个引脚分别使用上升沿触发和下降沿触发,这样就可以检测到门的开和关了)
下面贴一下外中断的关键部分代码:
//****************************************
#pragma vector=PORT1_VECTOR
__interrupt void SIO_rx (void)
{
volatile unsigned int x;
/***************************/
if((P1IFG&0x80)== 0x80)
{
for (x = 0xff; x > 0; x--);
if(((P1IN&0x80)== 0x00))
{
P1IFG &= 0x7f;
_EINT();
IOinterruptClose();
closedoor = 1;
opendoor = 0;
}
}
/***************************/
if((P1IFG&0x40)== 0x40)
{
for (x = 0xff; x > 0; x--);
if((P1IN&0x40)== 0x40)
{
P1IFG &= 0xBf;
_EINT();
IOinterruptClose();
opendoor = 1;
closedoor = 0;
}
}
P1IFG &=0X00;
}
//********************代码贴完了^_^
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』