MSP430 中断服务
- 格式:pdf
- 大小:98.36 KB
- 文档页数:4
MSP430I/O口中断引脚设置PxDIR输入/输出方向寄存器PxIN输入寄存器PxOUT输出寄存器PxIFG中断标志寄存器PxIE中断使能寄存器PxSEL功能选择寄存器(1)若使用P1口的部分引脚作为中断方式,在开总中断之前务必设置好P1IFG、P1IES、P1IE寄存器的相应位,并确保相应引脚为输入方向。
(2)为了尽量降低功耗,对连接引脚应设定为IO功能并设为输出。
(3)中断标志需要软件清除!可以用软件置位产生中断。
MSP430的IO中断由P1口和P2口输入变化的电平触发,P1和P2各有八个输入IO,P1的八个IO共用一个中断向量,P2的八个IO共用另一个中断向量。
在中断服务程序中判断到底是哪个IO口触发中断。
#include <msp430g2553.h>void Key_init(void){P1REN |= BIT3; //打开上拉,电路板上没有上拉电阻,触发边沿是从高电平到低电平P1IES |= BIT3; //选择触发边沿,下降沿触发P1IE |= BIT3; //打开P1.3的中断P1IFG &= 0x00;}void main(void){WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗P1DIR |= BIT0; //P1.0管脚设置为输出P1OUT |= BIT0; //P1.0管脚输出低电平Key_init(); //调用IO中断初始化函数_EINT(); //开启总中断,这一步没有的话,所有的中断都不能触发while(1); //死循环}#pragma vector = PORT1_VECTOR //中断向量声明__interrupt void Key_interrput(void){unsigned int i;for(i=0;i<12000;i++); //消抖必不可少啊!!if(P1IFG&BIT3) //判断是不是P1.3这个IO口产生了中断{ //若产生中断P1IFG.3置1P1OUT ^= BIT0; //LED2取反P1IFG &= 0x00; //中断标志位需要软件清除!!!P1REN |= BIT3;}}。
MSP430的中断分为3种:1.系统复位、2.非屏蔽中断、3.可屏蔽中断。
系统复位指向中断向量表(表3-11)的最高地址0xFFFE。
非屏蔽中断和可屏蔽中断根据能否被SR寄存器中的全局中断使能位GIE禁用来区分,非屏蔽中断不受GIE的控制,具备独立的中断使能;可屏蔽中断除了受本身的中断使能控制,还接受GIE控制。
1. 在MSP430中@非屏蔽中断主要有3个,分别是来自MSP430外部管脚NMI的触发FLASH非法访问振荡器错误非屏蔽中断都指向中断向量表中的0xFFFC地址。
2. MSP430具备大量的@可屏蔽中断,定时器、ADC、DMA、UART、WDT、I/O、比较器等都具备中断功能。
不同的可屏蔽中断优先级可根据中断向量表决定。
可屏蔽中断的中断向量表从0xFFFA地址开始向低地址扩展,地址越高的中断向量表所对应的中断优先级越高。
3. 每个中断向量在中断向量表里面占据一个2Byte空间的表项,这个2Byte的空间用来存储对应中断服务函数的首地址,CPU根据中断向量表里的地址跳转到中断服务函数。
仔细观察中断向量表可以看到,一些中断向量对应于多个中断源。
例如,地址为0xFFF8的Timer1_A3中断,当TA1CCR1中断标志位CCIFG置位或者TAIFG置位都会跳转到该向量。
又如具备中断功能的P1和P2端口,端口中的任意一个管脚发生中断都会跳转到对应的中断向量。
这种中断就叫做多源中断。
对于多源中断,中断源中任意一个中断发生都会跳转到公用的中断向量表项,这个时候需要通过中断标志位区别具体的中断源。
有了这些中断向量表的基础知识,下面介绍中断的处理过程,包括中断的接收和退出过程。
4. 微控制器使用过程中一些突发的程序跑飞问题,很多时候都是由于没有正确地处理中断造成的。
5. 中断发生的先决条件是对应中断使能位使能,@非屏蔽中断要求其独立的中断使能开启;@可屏蔽中断要求全局中断使能和自身中断使能同时开启。
6. 当中断请求到达,CPU从接受中断请求到开始执行中断服务函数的第一条指令需要5~6个CPU周期。
系统复位、中断及工作模式-利尔达MSP430培训资料系统复位、中断及工作模式嵌入式研发中心复位电路的结构POR(Power-on reset)的产生:上电 RST出现低电平 SVS产生复位动作 PUC(Power-up clear)的产生: POR信号 WDT时间溢出看门狗密钥错误 FLASH操作密钥错误 BOR(Brownout Reset)的产生: BOR 模块产生 PUC BOR PORBOR时序POR和BORBOR: MCLK< 4Mhz Brown-out!系统复位后的状态RSR/NMI为复位状态 IO口为输入状态各模块和寄存器恢复为初始化的状态状态寄存器SR复位看门狗WDT为看门狗状态 FFFE的内容装入PC指针软件必须完成的工作初始化堆栈指针SP,一般为RAM的顶端根据应用的需要,初始化WDT 对模块初始化特别注意:看门狗、晶振失败、FLASH写入失败都可以引起 RESET复位电路的设计1. RESET脚直接通过电阻上拉----不建议采用此方式2. RESET脚采用RC复位电路3. RESET脚采用电压监控芯片适用于MSP430没有BOR电路的芯片可以确保用户控制器中满足所有的工作电压条件MCU才启动4. MSP430F20xx的RESET与SBW共用,电容不要过大Device Pins Flash/RA Timers Communicatio BOR Features M n F11x1 20 4k/256 A3 Comp_A 8k/256 A3 ADC10 F11x2 20 F12x 28 8k/256 A3 Comp_A USART F12x2 28 8k/256 A3 USART ADC10 F13x 64 16k/512 A3,B3 USART ADC12 F14x 64 60k/2k A3,B7(2)USART ADC12, MPY 64 32k/1k A3,B3 USART, I2C ADC12, (2)DAC12, (3)DMA F15x F16x 64 60k/10k A3,B7 (2)USART, ADC12, (2)DAC12, (3)DMA I2C All devices include watchdog timer (WDT) and basic clock system (BCS)MSP430中断种类系统复位 POR、PUC、BOR和SVS 非屏蔽中断NMI 晶振失败 FLASH失败可屏蔽中断 TA、BT、COMP、UART等中断矢量结构中断进入进入中断需要6个指令周期1. 当前运行的指令完成,PC指向下一条指令 2. PC压栈 3. SR压栈 4. 选择高优先级中断 5. 单元中断中断标志清除,多元中断需要软件清除 6. 除SCG0外,SR被清除,如果是低功耗,退出低功耗,GIE的清除关闭可屏蔽中断7.装载PC指针中断前中断后特别注意:进入中断后,SP指针指向堆栈中的SR. 可以在中断程序中修改0(SP)内容改变中断返回后 SR状态。
MSP430单片机入门例程MSP430单片机是一款低功耗、高性能的16位单片机,广泛应用于各种嵌入式系统。
下面是一个简单的MSP430单片机入门例程,可以让大家初步了解MSP430单片机的基本使用方法。
所需材料:1、MSP430单片机开发板2、MSP430单片机编译器3、MSP430单片机调试器4、电脑和相关软件步骤:1、安装MSP430单片机编译器首先需要安装MSP430单片机的编译器,该编译器可以将C语言代码编译成MSP430单片机可以执行的机器码。
在安装编译器时,需要选择与您的单片机型号匹配的编译器。
2、编写程序下面是一个简单的MSP430单片机程序,可以让LED灯闪烁:c本文include <msp430.h>int main(void)本文P1DIR |= 0x01; //设置P1.0为输出while(1){P1OUT ^= 0x01; //反转P1.0的状态,LED闪烁__delay_cycles(); //延时一段时间,控制闪烁频率}本文上述程序中,首先定义了P1DIR寄存器,将P1.0设置为输出。
然后进入一个无限循环,在循环中反转P1.0的状态,使LED闪烁。
使用__delay_cycles()函数实现延时,控制LED闪烁频率。
3、编译程序使用MSP430单片机编译器将程序编译成机器码,生成可执行文件。
在编译时,需要注意选择正确的编译器选项和单片机型号。
4、调试程序使用MSP430单片机调试器将可执行文件下载到单片机中,并使用调试器进行调试。
在调试时,可以观察单片机的输出口状态和LED灯的闪烁情况,确保程序正常运行。
随着嵌入式系统的发展,MSP430单片机作为一种低功耗、高性能的微控制器,在各种应用领域中得到了广泛的应用。
为了更好地理解和应用MSP430单片机,我在学习过程中积累了一些经验,现在分享给大家。
MSP430单片机是一种超低功耗的微控制器,由德州仪器(Texas Instruments)推出。
最近在学习和实践的过程中接触到了线程的概念。
当你需要处理一大堆数据或者等待一个事件发生时候,系统其实并不需要等在那里,只需建立一个线程,适时的让它在后台运行,处理这些很占用系统的事件。
我想这与中断的功能很是相似,有些时候你让程序卡在那里仅仅是为了等待一个参数的改变,而这个参数完全可以在中断中实现修改,所以巧妙的使用中断对于高效的程序是必须的。
MSP430提供了3类中断:系统复位;非可屏蔽中断;可屏蔽中断。
下表列出了三种中断各自的中断源:MSP430中断优先级结构图如上图所示。
各模块的中断优先级由模块连接链决定,越接近CPU/NMIRS的模块,其中断优先级越高。
上图给出了中断的执行过程,相信大家可以在任何其他的书本中找到类似的流程图。
中断发生,全局中断开启,并且允许相应此中断,此时需要等待当前指令完成。
保存短点和寄存器值。
然后清除寄存器的值以及中断标志位,如果同时有多个中断发生则选择优先级最高的执行,进入中断服务子程序,执行完后,恢复断点,继续执行主程序。
通过这种前后台程序的切换控制程序运行,得到高效率。
下面让我们来看一个4x4键盘的例子。
我们通过中断的方式来感知键盘的操作,通过一个键盘扫描程序来确认按下的键,然后通过数码管动态的显示出来。
#include<msp430x24x.h>static int nRes;int nP10,nP11,nP12,nP13;static char LEDData[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8 e};void delay(int number){while(--number);}int KeyProcess(void){int nres=0;//P1.4输出低电平P1OUT = 0xe0;nP10 = P1IN&BIT0;if (nP10 == 0) nres = 13;nP11 = (P1IN & BIT1) >> 1; if (nP11 == 0) nres = 14;nP12 = (P1IN & BIT2) >> 2; if (nP12 == 0) nres = 15;nP13 = (P1IN & BIT3) >> 3; if (nP13 == 0) nres = 16;//P1.5输出低电平P1OUT = 0xd0;nP10 = P1IN&BIT0;if (nP10 == 0) nres = 9;nP11 = (P1IN & BIT1) >> 1; if (nP11 == 0) nres = 10;nP12 = (P1IN & BIT2) >> 2; if (nP12 == 0) nres = 11;nP13 = (P1IN & BIT3) >> 3;if (nP13 == 0) nres = 12;//P1.6输出低电平P1OUT = 0xb0;nP10 = P1IN&BIT0;if (nP10 == 0) nres = 5;nP11 = (P1IN & BIT1) >> 1;if (nP11 == 0) nres = 6;nP12 = (P1IN & BIT2) >> 2;if (nP12 == 0) nres = 7;nP13 = (P1IN & BIT3) >> 3;if (nP13 == 0) nres = 8;//P1.7输出低电平P1OUT = 0x70;nP10 = P1IN&BIT0;if (nP10 == 0) nres = 1;nP11 = (P1IN & BIT1) >> 1;if (nP11 == 0) nres = 2;nP12 = (P1IN & BIT2) >> 2;if (nP12 == 0) nres = 3;nP13 = (P1IN & BIT3) >> 3;if (nP13 == 0) nres = 4;while(!(nP10 && nP11 && nP12 && nP13 )) {P1OUT = 0x00; //恢复以前值//读取各个管脚的状态nP10 = P1IN&BIT0;nP11 = (P1IN&BIT1) >> 1; nP12 = (P1IN&BIT2) >> 2; nP13 = (P1IN&BIT3) >> 3; }return nres;}void display(int number){int tens,single;tens = number/10;single = number%10;P4OUT = LEDData[single]; P6OUT = 0x01;delay(100);P6OUT = 0x00;P4OUT = LEDData[tens];P6OUT = 0x02;delay(100);P6OUT = 0x00;}void main(){WDTCTL=WDTPW+WDTHOLD; //关闭看门狗//将P1口的所有的管脚在初始化的时候设置为输入方式P1DIR=0;//将P1口所有的管脚设置为一般I/O口P1SEL=0;//将P1.4、P1.5、P1.6、P1.7设置为输出方向P1DIR |= BIT4+BIT5+BIT6+BIT7;//输出低电平P1OUT = 0x00;P2DIR |= BIT0+BIT1+BIT2+BIT3; // when there is a interrupt there be a led indicate P2OUT = 0x00;P4DIR |= 0xff; // P4、P5口用于输出字型码//P5DIR |= 0xff;P6DIR |= BIT0+BIT1; // P6.0 P6.1用于片选P1IE |= BIT0;P1IE |= BIT1;P1IE |= BIT2;P1IE |= BIT3;P1IES |= (BIT0+BIT1+BIT2+BIT3);// pattern of the trigger_EINT();nRes=0;while (1){display(nRes);}}#pragma vector= PORT1_VECTOR __interrupt void Port_1(void){P1OUT = 0x00;nRes=KeyProcess();P1IFG = 0x00;}。
MSP430键盘程序[中断方式]// 此示例程序为中断方式,得到键盘的键值,存放在队列keybuff[10]中// 此示例程序没有显示,// 键盘的按键按下引起P1口的中断服务程序,得到键盘的键值,保存到键值队列// 在其他的中断服务程序中通过键值队列中的数据引导程序的流程#include <msp430x14x.h>unsigned char keybuff[10];unsigned char keypoint=0;void delay(int v){while(v!=0)v--;}unsigned char key(void){unsigned char x=0xff;P1DIR=0X0F;P1OUT=0X01; //扫描第一行if((P1IN&0X70)==0X10)x=0;elseif((P1IN&0X70)==0X20)x=1;elseif((P1IN&0X70)==0x40)x=2;else{P1OUT=0X2; //扫描第二行if((P1IN&0X70)==0X10)x=3;elseif((P1IN&0X70)==0X20)x=4;elseif((P1IN&0X70)==0x40)x=5;else{P1OUT=0X4; //扫描第三行if((P1IN&0X70)==0X10)x=6;elseif((P1IN&0X70)==0X20)x=7;elseif((P1IN&0X70)==0x40)x=8;else{P1OUT=8; //扫描第四行if((P1IN&0X70)==0X10)x=9;elseif((P1IN&0X70)==0X20)x=10;elseif((P1IN&0X70)==0x40)x=11;}}}return(x);}unsigned char keyj(void){unsigned char x;P1DIR=0x0f;P1OUT=0x0f; //键盘硬件:P10--P13为行线,最上面一根为P10x=(P1IN&0X70); // P14--P16为列线,最左边一根为P14,列线下拉 return(x); // 无按键,返回 0?; 有按键返回非0}interrupt[PORT1_VECTOR] void port1key(void){if(keyj()!=0X00){delay(300) ; //消抖动if(keyj()!=0X0){keybuff[keypoint]=key(); //按键见键值保存到队列keypoint++; //if(keypoint==10)keypoint=0;}}P1OUT=0X0F;P1IFG=0X0; //清除中断标志}void main(void){WDTCTL = WDTPW + WDTHOLD; /* // Stop WDT */P1DIR=0XF;P1OUT=0XF;P1IES=0X0;P1IE=0X70; //列线上升沿允许P1中断_EINT(); /*/ Enable interrupts */while(1){LPM0;_NOP();}}。
msp430简介MSP430是德州公司新开发的一类具有16位总线的带FLASH 的单片机,由于其性价比和集成度高,受到广大技术开发人员的青睐.它采用16位的总线,外设和内存统一编址,寻址范围可达64K,还可以外扩展存储器.具有统一的中断管理,具有丰富的片上外围模块,片内有精密硬件乘法器、两个16位定时器、一个14路的12位的模数转换器、一个看门狗、6路P口、两路USART通信端口、一个比较器、一个DCO内部振荡器和两个外部时钟,支持8M 的时钟.由于为FLASH型,则可以在线对单片机进行调试和下载,且JTAG口直接和FET(FLASH EMULATION TOOL)的相连,不须另外的仿真工具,方便实用,而且,可以在超低功耗模式下工作对环境和人体的辐射小,测量结果为100mw左右的功耗(电流为14mA左右),可靠性能好,加强电干扰运行不受影响,适应工业级的运行环境,适合与做手柄之类的自动控制的设备.我们相信MSP430单片机将会在工程技术应用中得以广泛应用,而且,它是通向DSP系列的桥梁,随着自动控制的高速化和低功耗化, MSP430系列将会得到越来越多人的喜爱.一、IO口(一)、P口端口寄存器:1、PxDIR 输入/输出方向寄存器(0:输入模式 1:输出模式)2、PxIN 输入寄存器输入寄存器是只读寄存器,用户不能对其写入,只能通过读取该寄存器的内容知道I/O口的输入信号。
3、PxOUT 输出寄存器寄存器内的内容不会受引脚方向改变的影响。
4、PxIFG 中断标志寄存器(0:没有中断请求 1:有中断请求)该寄存器有8个标志位,对应相应的引脚是否有待处理的中断请求;这8个中断标志共用一个中断向量,中断标志不会自动复位,必须软件复位;外部中断事件的时间必须>=1.5倍的MCLK的时间,以保证中断请求被接受;5、PxIES 中断触发沿选择寄存器(0:上升沿中断 1:下降沿中断)6、PxSEL 功能选择寄存器(0:选择引脚为I/O端口 1:选择引脚为外围模块功能)7、PxREN 上拉/下拉电阻使能寄存器(0:禁止 1:使能)(二)、常用特殊P口:1、P1和P2口可作为外部中断口。
MSP430单片机之中断服务430的中断是按照下图1的优先级顺序定义的,有三种中断:1.系统重置、2.不可屏蔽中断(NMI)、3.可屏蔽中断。
图1.中断优先级部分具体的中断优先级由高到低为:PORT2_VECTOR (1 * 2u) /* 0xFFE2 Port 2 */PORT1_VECTOR (4 * 2u) /* 0xFFE8 Port 1 */TIMERA1_VECTOR (5 * 2u) /* 0xFFEA Timer A CC1-2, TA */TIMERA0_VECTOR (6 * 2u) /* 0xFFEC Timer A CC0 */ADC_VECTOR (7 * 2u) /* 0xFFEE ADC */USART0TX_VECTOR (8 * 2u) /* 0xFFF0 USART 0 Transmit */USART0RX_VECTOR (9 * 2u) /* 0xFFF2 USART 0 Receive */WDT_VECTOR (10 * 2u) /* 0xFFF4 Watchdog Timer */COMPARATORA_VECTOR (11 * 2u) /* 0xFFF6 Comparator A */TIMERB1_VECTOR (12 * 2u) /* 0xFFF8 Timer B CC1-2, TB */TIMERB0_VECTOR (13 * 2u) /* 0xFFFA Timer B CC0 */NMI_VECTOR (14 * 2u) /* 0xFFFC Non-maska××e */RESET_VECTOR (15 * 2u) /* 0xFFFE Reset [Highest Priority] */其中可屏蔽中断分为系统NMI(SNMI)和用户NMI(UNMI),一般来说,不可屏蔽中断不受GIE标志位的影响。
用户不可屏蔽中断的中断源为NMIIE、ACCIE和OFIE,当响应用户不可屏蔽中断后,其他不可屏蔽中断就自动被禁止,以防止同级别的中断发生产生中断嵌套。
[1] 中断服务程序的格式
// P2 中断服务子程序
#pragma vector = PORT2_VECTOR
__interrupt void P2_IRQ(void)
{
switch(P1IFG)
{
case 0x01: // 引脚0
case 0x02: // 引脚1
case 0x04: // 引脚2
case 0x08: // 引脚3
case 0x10: // 引脚4
case 0x20: // 引脚5
case 0x40: // 引脚6
case 0x80: // 引脚7
}
}
中断服务程序最主要的是中断向量的设置
[2] 用P2.0~P2.3 的引脚中断,控制P4.0~P4.3 的LED闪烁
设置P2.0~P2.3 为输入状态
设置P2.0~P2.3 开中断
设置P2.0~P2.3 中断为上升沿中断
开全局中断_EINT();
设置P4.0~P4.3 为输出模式
写P2 中断服务子程序,如果某引脚有中断,则改变相对应的LED状态。
实验注意事项
[1] 在中断服务程序里面不要占用大量的时间,如果有大量的数据需要处理,则可以使
用在中断服务程序中设置标志变量,然后在主程序里面判断标志变量值,然后处理的方法。
[2] 中断服务程序只有在模块中断允许开启和全局中断开启时才有效
[3] 有的多个中断源使用一个中断向量,则需要在进中断的时候用switch~case语句判断
相关寄存器到底是哪个中断源发出的中断请求。
[4] I/O 口里面只有P1和P2口能响应中断,设计硬件电路的时候需要注意。
第3讲MSP430中断系统一、MSP430的中断系统简介 二、MSP430的中断系统实验一、MSP430的中断系统1、中断的概念 2、MSP430的中断源类型 3、MSP430x169的中断向量表、中断优先级 4、可屏蔽中断响应过程 5、端口P1和P2外中断 6、可屏蔽中断程序设计1、中断的概念中断是暂停CPU正在运行的程序, 转去执行相应的中断服务程序,完 毕后返回被中断的程序继续运行的 现象和技术。
CPU执行流程无中断时 有中断时非预料 事件1中断服 务程序1非预料 事件 2中断服 务程序 22、 MSP430的中断源类型两种分类: 1) 按中断源的响应是否受控分类 2)按中断源来自MCU外部引脚还是内部分类1) 按中断源的响应是否受控分类 MSP430的中断源分为三大类型●系统复位中断 system reset(也称不可屏蔽中断,Nonmaskable interrupts) ——不能被总控位GIE和自己的分控位IE位屏蔽的中断●非屏蔽中断(Non)maskable interrupts——不能被总控位GIE屏蔽, 但能被自己的分控位IE位屏蔽的中断●可屏蔽中断maskable interrupts——能被总控位GIE和自己的分控位IE位屏蔽的中断状态寄存器SR (Status Register)15~9 保留 8 7 SCG1 6 SCG0 5 OSCOFF 4 CPUOFF 3 2 1 0VGIENZCGIE : 可屏蔽中断屏蔽位 (General Interrupt Enable Bit) 置位1: 允许所有可屏蔽中断 复位0: 禁止所有可屏蔽中断开/关总中断控制位指令(disable/enable general interrupt bit) 指令格式 _DINT( ); _EINT( ); 执行操作 V Z N C0→ GIE 1→ GIE* * * * #include "in430.h"#include “intrinsics.h”非屏蔽中断的控制机制(non)_maskable interruptindividual enable bitCPU 优先权裁决 CPU 中断响应中断请求 1--enable 0--disable 分控位可屏蔽中断的控制机制(分控位、总控位)maskable interruptindividual enable bitGIECPU 优先权裁决 CPU 中断响应中断请求 1--enable 0--disable 分控位 1--enable 0--disable 总控位2) 按中断源来自MCU外部引脚还是内部分类由外部引脚(如RST/NMI)产生的中断, 为外中断, 由MCU内部模块产生的中断,称内中断RST/NMI P1.0~P1.7外中断内 中断MSP430F169的外中断和内中断外中断: 引脚RST/NMI、P1.0~P1.7、P2.0~P2.7产生的中断 内中断: 由MCU内部模块产生外中断内中断3、MSP430x169中断源、中断标志、中断向量地址 、 中断优先级(中断类型号) (MSP430F169.pdf P11)Interrupt SourcePower up, External Reset Watchdog, Flash memory NMI , Oscillator Fault, Flash memory access violation Timer_B7 Timer_B7 Comparator_A Watchdog timer USART0 receive USART0 transmit I2C transmit/receive/others ADC12 Timer_A3 Timer_A3 I/O port 1(8 flags) USART1 receive USART1 transmit I/O port 2(8 flags) DAC12 DMAInterrupt FlagWDTIFG, KEYV NMIFG,OFIFG,ACCVIFG TBCCR0 CCIFG TBCCR1 to TBCCR6 CCIFGs, TBIFG CAIFG WDTIFG URXIFG0 UTXIFG0 ADC12IFG TACCR0 CCIFG TACCR1 and TACCR2 CCIFGs, TAIFG P1IFG.0~P1IFG.7 URXIFG1 UTXIFG1 P2IFG.0~P2IFG.7 DAC12_0IFG, DAC12_1IFG, DMA0IFG~DMA2IFGSYSTEM InterruptReset (Non)maskable Maskable Maskable Maskable Maskable Maskable Maskable Maskable Maskable Maskable Maskable Maskable Maskable Maskable MaskableAddress0FFFEh 0FFFCh 0FFFAh 0FFF8h 0FFF6h 0FFF4h 0FFF2h 0FFF0h 0FFEEh 0FFECh 0FFEAh 0FFE8h 0FFE6h 0FFE4h 0FFE2h 0FFE0hPriority15(highest) 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0(lowest)作为中断申请的端口P1和P2引脚, 应设置下列相应寄存器:1)设置功能选择寄存器PxSEL.y对应位为0(基本I/O功能)2)设置方向选择寄存器PxDIR.y对应位为0(输入)3)设置PxIES.y选择中断源有效信号类型是上升还是下降沿4)设置PxIE.y打开分中断允许位5)设置GIE=1打开总中断允许位在中断程序中:1)由于端口的8个引脚共用一个中断向量,当有多个引脚做中断源时,需利用PxIFG判断产生中断的中断源引脚2) 在中断子程中应清除PxIFG相应的中断标志位206、 MSP430的可屏蔽中断程序设计1) 编程步骤 2) C语言中断程序举例1)编程步骤编程前应了解可屏蔽硬中断的响应过程, 了解有关的寄存器和引脚与中断响应过程的关系 a. 主程序 做好相关设置: 中断源发出中断申请时CPU能够响应的准备工作 b. 中断程序 处理与中断源有关的关键任务 c. 设置中断向量 根据中断源在中断向量表的相应位置,设置中断向量a. 主程序做好相关设置, 中断源发出中断申请时CPU能够响应的准备工作 开始 主 程 序 流 程 根据情况关闭分中断允 许或总中断允许 有关任务初始化 中断有关初始化 (中断源、边沿选择等) 清分中断标志 打开分中断允许 开总中断允许GIE=1 主程其它工作处理 (可用无限循环延时代替)b. 中断程序处理与中断源有关的关键任务 开始中 断 程 序 流 程C语言中断程序结构__interrupt void intName(void) { ...... ...... ...... } 1. 定义了一个函数名为intName的中断程序 2. 结构上与普通函数的区别是? 使用了关键字__interrupt 使得反汇编中断程序时, 返回的语句是RETI, 而不是RETc. 设置中断向量确定根据中断源确定中断类型号N, 将中断程序的入口地址放在中断向量表0FFE0h+N*2处中断源 上电,外部复位 看门狗复位 FLASH密码错 ... 引脚P1.0~P1.7 ... 引脚P2.0~P2.7中断标志向量地址优先级 中断类型号 15 ... 4 ... 1WDTIFG, KEYV0FFFEh... ... P1IFG.0~P1IFG.7 0FFE8h ... ... P1IFG.0~P1IFG.7 0FFE2h¾ 头文件 io430x16x.h和 msp430x16x.h 用符号表示各中断源在中断向量表的偏移地址// Interrupt Vectors (offset from 0xFFE0) #define DACDMA_VECTOR (0 * 2u) /* 0xFFE0 DAC/DMA */ #define PORT2_VECTOR (1 * 2u) /* 0xFFE2 Port 2 */ #define USART1TX_VECTOR (2 * 2u) /* 0xFFE4 USART 1 Transmit */ #define USART1RX_VECTOR (3 * 2u) /* 0xFFE6 USART 1 Receive */ #define PORT1_VECTOR (4 * 2u) /* 0xFFE8 Port 1 */ #define TIMERA1_VECTOR (5 * 2u) /* 0xFFEA Timer A CC1‐2, TA */ #define TIMERA0_VECTOR (6 * 2u) /* 0xFFEC Timer A CC0 */ #define ADC12_VECTOR (7 * 2u) /* 0xFFEE ADC */ #define USART0TX_VECTOR (8 * 2u) /* 0xFFF0 USART 0 Transmit */ #define USART0RX_VECTOR (9 * 2u) /* 0xFFF2 USART 0 Receive */ #define WDT_VECTOR (10 * 2u) /* 0xFFF4 Watchdog Timer */ #define COMPARATORA_VECTOR (11 * 2u) /* 0xFFF6 Comparator A */ #define TIMERB1_VECTOR (12 * 2u) /* 0xFFF8 Timer B CC1‐6, TB */ #define TIMERB0_VECTOR (13 * 2u) /* 0xFFFA Timer B CC0 */ #define NMI_VECTOR (14 * 2u) /* 0xFFFC Non‐maskable */ #define RESET_VECTOR (15 * 2u) /* 0xFFFE Reset [Highest Priority] */C语言程序设置中断向量方法在中断程序前使用#pragma vector=偏址 语句, 将中断程序的入口地址放入到FFE0+偏址的中断向量表中 #pragma vector=N*2 //使用中断类型号计算偏址 __interrupt void intName(void) { ...... } #pragma vector=PORT1_VECTOR //使用符号表示的中断偏址 __interrupt void intName(void) { ...... }1. 主程序可 屏 蔽 中 断 程 序 设 计开始 据情况关闭分中断允许 或总中断允许 有关任务初始化 中断有关初始化 (中断源、边沿选择等) 清分中断标志 打开分中断允许 开总中断允许GIE=1 主程其它工作处理 (可用无限循环延时代替)开始3. 设置中断向量 根据中断源在 中断向量表相应位置 设置中断向量例: 中断编程举例 (以P1.0上的中断为例)用C语言编写程序, 以中断方式响应P1.0上的下降沿, 每来一个下降沿, 使 P3.6 的输出翻转一次 MSP430F169 P3.6P1.0中断请求C语言: 开/关总中断控制位函数(disable/enable general interrupt bit)函数名称__disable_interrupt( ) __ensable_interrupt( )功能0→ GIE 1→ GIE包含在intrinsics.h intrinsics.hintrinsics.h 文件中:声明了一些包含在IAR 编译器的内部函数,方便用户使用 如: __intrinsic void __enable_interrupt(void); __intrinsic void __disable_interrupt(void);可通过查看EW430安装目录下\430\doc\Help430Compiler.chm 了解这些内部函数实现的功能利用安装目录\430\doc\Help430Compiler.chm 了解这些内部函数实现的功能用C语言编写中断程序方法11. 包含intrinsics.h文件中 2. 使用__disable_interrupt( ) 和__enable_interrupt( ) #include "io430.h" #include "intrinsics.h" int main( void ) { //Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; __disable_interrupt(); //关总中断控制(非必要) …… //主程序初始化准备工作 …… __enable_interrupt(); //开总中断控制 while(1){ }; //主程序循环 } #pragma vector=数字或符号表示的偏址 //中断向量设置 __interrupt void port_int(void) //中断子程 { …… }头文件 in430.h(注意不是io430.h)…… #include "intrinsics.h " …… /*Deprecated, please use "__disable_interrupt" instead. */ #define _DINT( ) __disable_interrupt() /* Deprecated, please use "__enable_interrupt" instead. */ #define _EINT( ) __enable_interrupt() /* Deprecated, please use "__no_operation" instead. */ #define _NOP( ) __no_operation() ......用C语言编写中断程序方法21. 包含in430.h文件 2. 使用DINT( ) 和EINT ( ) #include "io430.h" #include "in430.h" int main( void ) { //Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; _DINT( ); //关总中断控制(非必要) …… //主程序初始化准备工作 …… _EINT( ); //开总中断控制 while(1){ }; //主程序循环 } #pragma vector=数字或符号表示的偏址//中断向量设置 __interrupt void port_int(void) //中断子程 { …… }头文件io430.h__no_init volatile union { unsigned char P1IFG; struct { unsigned char P1IFG_0 : 1 ; unsigned char P1IFG_1 : 1 ; unsigned char P1IFG_2 : 1 ; unsigned char P1IFG_3 : 1 ; unsigned char P1IFG_4 : 1 ; unsigned char P1IFG_5 : 1 ; unsigned char P1IFG_6 : 1 ; unsigned char P1IFG_7 : 1 ; } P1IFG_bit; } @ 0x0023; __no_init volatile union { unsigned char P1IES; struct {unsigned char P1IES_0 : 1 ; unsigned char P1IES_1 : 1 ; unsigned char P1IES_2 : 1 ; unsigned char P1IES_3 : 1 ; unsigned char P1IES_4 : 1 ; unsigned char P1IES_5 : 1 ; unsigned char P1IES_6 : 1 ; unsigned char P1IES_7 : 1 ; } P1IES_bit; } @ 0x0024;可用字节或位域方式对PxIFG和PxIE进行操作P1IFG_bit.P1IFG_0 = 0; P1IE_bit.P1IE_0 = 1; //清P1.0中断标志 //打开P1.0中断允许#include "io430.h" #include "in430.h" int main( void ) { WDTCTL = WDTPW + WDTHOLD; //关闭看门狗 _DINT(); //禁止可屏蔽中断 GIE=0 P1IE_bit.P1IE_0=0; // 关闭P1.0中断允许 P3SEL_bit.P3SEL_6=0; //设置P3.6为基本I/O功能 P3DIR_bit.P3DIR_6=1; //设置P3.6为输出 P3OUT_bit.P3OUT_6=0; //置P3.6输出初值为0 P1SEL_bit.P1SEL_0=0; //置P1.0作为基本I/O端口 P1DIR_bit.P1DIR_0=0; //置P1.0为输入 P1IES_bit.P1IES_0=1; //置P1.0下降沿作中断源 P1IFG_bit.P1IFG_0=0; //清P1.0中断标志 P1IE_bit.P1IE_0=1; //打开P1.0中断允许 _EINT(); //允许可屏蔽中断 GIE=1 while(1) { }; //主程循环 } #pragma vector=PORT1_VECTOR //置P1中断向量 __interrupt void port_int(void) //中断子程 { if (P1IFG_bit.P1IFG_0==1) //判断是否是P1IFG.0中断标志 { P3OUT_bit.P3OUT_6=~P3OUT_bit.P3OUT_6; //对P3.6取反 P1IFG_bit.P1IFG_0=0; //清P1.0中断标志 } }在EW430下 反汇编C程序代码: P1IFG_bit.P1IFG_0=0; → BIC.b #0x1, &P1IFG P1IE_bit.P1IE_0=1; → BIS.b #0x1, &P1IE _EINT(); → EINT在EW430下反汇编C中断程序代码:子程结尾为 RETI注意:● 若有多个中断同时请求, CPU先响应优先级最高的中断请求 ● 当中断源产生时, MSP430内部对应有一个标志被置位 中断程序之后, 应确保该标志的值已清零, 否则被当成又一次的中断申请 ● 对于单一中断标志的中断源请求, CPU会自动清零该中断标志 ● 对于有多个中断标志的中断源请求, 用户在中断子程用这些标志判断产生的具体子中断源, 中断标志的清零由用户在使用完后编程清零中断源 定时器A P1的8个引脚 ... P2的8个引脚 中断标志 TACCR1 to TACCR2 CCIFGs, TAIFG (3) P1IFG.0~P1IFG.7 (8) ... P1IFG.0~P1IFG.7 (8) 向量地址 优先级,类型号 0FFEAh 5 0FFE8h ... 0FFE2h 4 ... 1以中断方式响应P1端口上8个按键(上升沿)。
当系统时钟发生器基本功能建立之后,CPU内状态寄存器SR的SCG1,SCG0,CPUOFF,OSCOFF位是重要的低功耗控制位。
只要任意中断被响应,上述控制位就被压入堆栈保存,中断处理之后,又可恢复先前的工作方式。
在中断处理子程序执行期间,通过间接访问堆栈数据,可以操作这些控制位;这样允许程序在中断返回(RETI) 后,以另一种功耗方式继续运行。
各控制位的作用如下:SCG1:复位,使能SMCLK;置位,禁止SMCLK。
SCG0:复位,激活直流发生器,只有SCG0置位,并且DCOCLK没有被用作MCLK或SMCLK时,直流发生器才能被禁止。
OSCOFF:复位,激活LFXT1,只有当OSCOFF被置位并且LFXT1CLK不用于MCLK或SMCLK时,FLXT1才能被禁止;当使用晶体振荡器关闭选项OSCOFF时,需要考虑晶体振荡器的启动设置时间CPUOFF:复位,激活MCLK;置位,关闭MCLK。
控制位SCG1、SCG0、CPUOFF、OSCOFF可由软件配制成六种不同的工作模式:工作模式控制位 CPU状态、振荡器及时钟SCG1=0 CPU活动SCG0=0 MCLK活动AM CPUOFF=0 SMCLK活动OSCOFF=0 ACLK活动SCG1=0 CPU禁止LPM0 SCG0=0 MCLK禁止OSCOFF=0 SMCLK活动CPUOFF=1 ACLK活动SCG1=0 CPU禁止MCLK禁止LPM1 SCG0=1 如果DCOCLK位用作MCLK或SMCLK,则直流发生器禁止,否则,仍然活动OSCOFF=0 SMCLK活动CPUOFF=1 ACLK活动SCG1=1 CPU禁止如果DCO未被用作MCLK或SMCLK,自动禁止SCG0=0 MCLK禁止LPM2 OSCOFF=0 SMCLK禁止CPUOFF=1 ACLK活动SCG1=1 CPU禁止DCO被禁止,直流发生器被禁止SCG0=1 MCLK禁止LPM3 OSCOFF=0 SMCLK禁止CPUOFF=1 ACLK活动SCG1=1 CPU禁止SCG0=1 DCO被禁止,直流发生器被禁止LPM4 OSCOFF=1 所有振荡器停止工作MCLK、SMCLK禁止CPUOFF=1 ACLK禁止低功耗的设计技巧问题1.LPM4:在振荡器关闭模式期间,处理机的所有部件工作停止,此时的电流消耗最小。
1、MSP430本身是关闭终中断的,只有当你在一个中断服务程序中再次开总中断GIE时,这时中断嵌套式打
开了的。
2、当进入中断程序时,只要不在中断中再次开中断,则总中断是关闭的,此时来中断不管是比当前
中断的优先级高还是低都不执行;(只要不在中断服务程序中开启总中断GIE,则中断是不会被暂停的)
3、若在中断A中开了总中断,则可以响应后来的中断B(不管B的优先级比A 高还是低),B执行完再
继续执行A。
注意:进入中断B后总中断同样也会关闭,如果B中断程序执行时需响应中断C,则此时
也要开总中断,若不需响应中断,则不用开中断,B执行完后跳出中断程序进入A程序时,总中断会
自动打开;
可以这样表示:
A(正在执行的中断服务程序,同时它开了总中断GIE)——B中断来了则A暂停,开始响应B(B也又
开了总中断GIE)——C中断来了则B也暂停,开始响应C,这样如此下去D——E——F——。
会这
样一直嵌套下去直到堆栈溢出系统复位。
所以不是无限制的嵌套。
4、如果中断嵌套时同时来了多个中断,则按照中断优先级依次执行,再返回以前的中断执行。
5、对于单源中断,只要响应中断,系统硬件自动清中断标志位,对于TA/TB定时器的比较/捕获中断,只要
访问TAIV/TBIV,标志位倍被自动清除。
对于多源中断要手动清标志位,比如
P1/P2口中断,要手工清除相
应的标志,如果在这种中断时,开总中断GIE,而在打开中断前没有清标志,就会有相同的中断不断嵌
入,而导致堆栈溢出引起复位,所以在这类中断中必须先清标志再打开中断开关.。
MSP430 编程点滴
做了好一段时间的msp430 单片机的编程,随意想一点点东西写下来,
也算是给岁月增加一圈年轮。
我做msp430 的编程使用IAR,用C 语言来
说。
在调试和编程中经常遇到一些个问题,如下:
1、中断
中断是单片机很重要的一个问题,也是难处理的一个问题。
在调试中经常
遇到问题。
1)打开了中断开关,但是忘了写中断服务程序,此时如有产生了中断就会
导致程序跑飞。
此问题遇到了几次,都是一时疏忽,造成了很大的麻烦。
2)外设与CPU 是并行运行的,采用中断的方式控制外设时,需要考虑主程
序可能要等待外设中断。
Uart_Send(CustomerCounter,CustomerCounterRow*(AddrMap[0]while(TxSendSt atus == TXSEND_DATA);
/ /清零
CustomerCounterRow = 0;。
中断系统中断的优先级是固定的。
中断优先级的是以模块的在链接所处的位置决定的。
越靠近CPU/NMIRS,模块的优先级越高。
中断优先级决定了,当系统有多个中断等待处理时,先处理哪一个中断。
有三种中断类型:系统中断不可屏蔽中断可屏蔽中断不可屏蔽中断(NMI)不可屏蔽中断不能被总中断使能位(GIE)所屏蔽,而由单独的中断使能位(NMIIE, ACCVIE,OFIE)来控制的。
当接收到不可屏蔽中断中断时,所有的不可屏蔽中断使能位会被自动复位。
程序从不可屏蔽中断的中断向量0FFFCH存储的地址开始运行。
用户软件必须设置所需的不可屏蔽的中断使能位,以便不可屏蔽中断能够再次响应。
不可屏蔽的中断源有以下三种:1. 当配置为NMI模式时,RST/NMI引脚的一个边沿2. 振荡器失效3. 错误使用FLASHRST/NMI引脚上电时,RST/NMI引脚配置为复位模式。
在看门狗控制寄存器WDTCTL中选择RST/NMI引脚的功能。
如果RST/NMI引脚被设置为复位功能,RST/NMI引脚处于低电平时CPU将一直保持复位状态。
当转为高电平时,CPU从存储在复位向量OFFFEH中的地址开始运行,RSTIFG将被置位。
如果RST/NMI引脚被用户软件配置为不可屏蔽中断时,如果NMIIE位被置位时,由WDTNMIES选择的信号边沿到来产生NMI中断。
RST/NMI的标志位NMIIFG将会被置1。
注释1:RST/NMI保持低电平在配置为NMI模式时,产生一个NMI事件的信号不会拉低RST/NMI引脚的电平。
如果其他的信号源产生一个PUC时,NMI信号是低电平,设备将处于复位状态,因为一个PUC 信号使RST/NMI引脚变为复位模式。
注释2:修改WDTNMIES当选择了NMI模式,WDTNMIES位改变了,NMI是否产生将依据于实际的RST/NMI 引脚的电平。
在系统被设置为NMI模式前,如果NMI的边沿选择位改变早于选择NMI模式,不产生NMI。
msp430中断(不可屏蔽中断NMI)中断系统中断的优先级是固定的。
中断优先级的是以模块的在链接所处的位置决定的。
越靠近CPU/NMIRS,模块的优先级越高。
中断优先级决定了,当系统有多个中断等待处理时,先处理哪一个中断。
有三种中断类型:系统中断不可屏蔽中断可屏蔽中断不可屏蔽中断(NMI)不可屏蔽中断不能被总中断使能位(GIE)所屏蔽,而由单独的中断使能位(NMIIE, ACCVIE,OFIE)来控制的。
当接收到不可屏蔽中断中断时,所有的不可屏蔽中断使能位会被自动复位。
程序从不可屏蔽中断的中断向量0FFFCH存储的地址开始运行。
用户软件必须设置所需的不可屏蔽的中断使能位,以便不可屏蔽中断能够再次响应。
不可屏蔽的中断源有以下三种:1. 当配置为NMI模式时,RST/NMI引脚的一个边沿2. 振荡器失效3. 错误使用FLASHRST/NMI引脚上电时,RST/NMI引脚配置为复位模式。
在看门狗控制寄存器WDTCTL中选择RST/NMI引脚的功能。
如果RST/NMI引脚被设置为复位功能,RST/NMI引脚处于低电平时CPU将一直保持复位状态。
当转为高电平时,CPU从存储在复位向量OFFFEH中的地址开始运行,RSTIFG将被置位。
如果RST/NMI引脚被用户软件配置为不可屏蔽中断时,如果NMIIE位被置位时,由WDTNMIES选择的信号边沿到来产生NMI中断。
RST/NMI的标志位NMIIFG将会被置1。
注释1:RST/NMI保持低电平在配置为NMI模式时,产生一个NMI事件的信号不会拉低RST/NMI引脚的电平。
如果其他的信号源产生一个PUC时,NMI信号是低电平,设备将处于复位状态,因为一个PUC 信号使RST/NMI引脚变为复位模式。
注释2:修改WDTNMIES当选择了NMI模式,WDTNMIES位改变了,NMI是否产生将依据于实际的RST/NMI 引脚的电平。
在系统被设置为NMI模式前,如果NMI的边沿选择位改变早于选择NMI模式,不产生NMI。
当系统时钟发生器基本功能建立之后,CPU内状态寄存器SR的SCG1,SCG0,CPUOFF,OSCOFF位是重要的低功耗控制位。
只要任意中断被响应,上述控制位就被压入堆栈保存,中断处理之后,又可恢复先前的工作方式。
在中断处理子程序执行期间,通过间接访问堆栈数据,可以操作这些控制位;这样允许程序在中断返回(RETI) 后,以另一种功耗方式继续运行。
各控制位的作用如下:
SCG1:复位,使能SMCLK;置位,禁止SMCLK。
SCG0:复位,激活直流发生器,只有SCG0置位,并且DCOCLK没有被用作MCLK或SMCLK时,直流发生器才能被禁止。
OSCOFF:复位,激活LFXT1,只有当OSCOFF被置位并且LFXT1CLK不用于MCLK或SMCLK时,FLXT1才能被禁止;当使用晶体振荡器关闭选项OSCOFF时,需要考虑晶体振荡器的启动设置时间
CPUOFF:复位,激活MCLK;置位,关闭MCLK。
控制位SCG1、SCG0、CPUOFF、OSCOFF可由软件配制成六种不同的工作模式:工作模式控制位 CPU状态、振荡器及时钟
SCG1=0 CPU活动
SCG0=0 MCLK活动
AM CPUOFF=0 SMCLK活动
OSCOFF=0 ACLK活动
SCG1=0 CPU禁止
LPM0 SCG0=0 MCLK禁止
OSCOFF=0 SMCLK活动
CPUOFF=1 ACLK活动
SCG1=0 CPU禁止
MCLK禁止
LPM1 SCG0=1 如果DCOCLK位用作MCLK或SMCLK,则直流发生器禁止,
否则,仍然活动
OSCOFF=0 SMCLK活动
CPUOFF=1 ACLK活动
SCG1=1 CPU禁止
如果DCO未被用作MCLK或SMCLK,自动禁止
SCG0=0 MCLK禁止
LPM2 OSCOFF=0 SMCLK禁止
CPUOFF=1 ACLK活动
SCG1=1 CPU禁止
DCO被禁止,直流发生器被禁止
SCG0=1 MCLK禁止
LPM3 OSCOFF=0 SMCLK禁止
CPUOFF=1 ACLK活动
SCG1=1 CPU禁止
SCG0=1 DCO被禁止,直流发生器被禁止LPM4 OSCOFF=1 所有振荡器停止工作
MCLK、SMCLK禁止
CPUOFF=1 ACLK禁止
低功耗的设计技巧问题
1.LPM4:在振荡器关闭模式期间,处理机的所有部件工作停止,此时的电流消耗最小。
此时只有在系统上电电路检测到低点电平或任一请求异步响应中断的外部中断事件时才会从新工作。
因此在设计应含有可能需要用到的外部中断才采用这种模式,否则发生不可预料的结果。
2.LPM3:在DC发生关闭期间,只有晶振是活动的。
但此时设置基本时序条件的DC发生器的DC电流被关闭。
由于此电路的高阻设计,使功耗被抑制。
当从DC关闭到启动DC需要一段时间(ns~us)
3.LPM2:在此期间晶振和DC发生器是工作的,所以可以实现快速启动
4.LPM1:在此期间振荡器已经工作,所以不存在启动延时问题
_BIS_SR(LPM3_bits) _BIC_SR_IRQ(LPM3_bits)
LPM3 LPM3_EXIT
系统响应中断过程:
1.硬件自动中断服务
a.PC入栈
b.SR入栈
c.中断向量赋给PC
d.GIE、SCG1、CPOOFF和OSCOFF清楚
e.IFG标志位清除(单源中断标志比如WDTIFG)
2.执行中断处理子程序
3.执行RETI指令
4.SR出栈
5.PC出栈
低功耗应用
void main(void)
{
WDTCTL=WDT_ADLY_1000;
IE1 | = WDTIE;
P1DIR | = 0X01;
_EINT();
for(;;)
{
LPM3;
_NOP();
}
}
interrupt[WDT_VECTOR] watchdog_timer(void) {
P1OUT ^ = 0X01;
}。