msp430中断扫描键盘例程
MSP430单片机应用中键盘的软件设计

按键设计在行、 列线交叉上, 行列线分别连接到按键开关 的两端。当行线通过上拉电阻接 +5V 时, 被钳位在高电平状 态。 键盘中有无按键按下是由列线送人全扫描字, 行线读人行 线状态来判断的。 其方法是:先给列线的所有 珊 线均置成低 电平, 然后将行线电平状态读人累加器 A 中。如果有键按下, 总会有一根行线电平被拉至电平, 从而使行输人不全为 1。 键 盘中哪一个键按下是由列线逐列置低电平, 检查输人状态。 其 方法是:依次给列线送低电平, 然后检查所有行线状态, 如果 全为 1, 则所按下之键不在此列。而且是在与 0 电平行线相交 点上的那个键。 (2)键盘工作方式的选择 一般在实践应用中,由于应用系统在工作时并不经常需 要按键输人 , 所以为了提高 CPU 的工作效率, 可采用中断扫 描工作方式,即只有在键盘有按键按下时,才发中断请求, CPU 响应中断请求后, 转到中断服务程序, 进行键盘扫描, 识 别键码。 具体应用程序举例:(下面程序经过调试验证正确)下 面介绍通过 MSP430 的 P1 口接的 4*4=16 个按键 ( 编号为
l
P10UTI=BIT7;
if(PI IN&BITI)
e lse
if(Pl IN&B1 T4)
x=7;
void Comm- Sent(unsigned char Byte) { unsigned char i, a[3]二 , '430";
{
for(i=O ;i<3;i++)
{ TXBUFO =aa[i]; while((UTCTLO &0x01)二 =0);
x=2;
e lse
{
int i;
BCSCTLI &=- X'IS ;
msp430Led按键控制灯亮程序

1.Led灯控制程序#include "msp430g2553.h"void main( void ){// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD; //关闭看门狗//P1DIR = 0x41;//P1OUT = 0x41; //程序点亮led1//P1DIR |=BIT0+BIT6;//P1OUT |=BIT0+BIT6; //程序点亮led2P1DIR |=BIT0;P1OUT |=BIT0;P1DIR |=BIT6;P1OUT &=~BIT6;while(1){P1OUT ^=BIT0;P1OUT ^=BIT6;__delay_cycles(1000000);} //led交替亮,持续1s2.Led按键控制灯亮#include "msp430g2553.h"void main( void ){// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD;//关闭看门狗P1DIR &=~BIT3;P1DIR |=BIT0;P1IES |=BIT3;P1IE |=BIT3;_EINT();_BIS_SR(LPM0_bits+GIE);}#pragma vector=PORT1_VECTOR__interrupt void PORT1_ISR(void){int i;char pushkey;pushkey=P1IFG&BIT3;//第三位中断标志位for(i=0;i<1000;i++)//短暂延时软件去抖if((P1IN&pushkey)==pushkey){P1IFG=0;//中断标志清零return;}if(P1IFG&BIT3)//判断按键是否按下{P1OUT^=BIT0;}P1IFG=0;return;}3.矩阵键盘和数码管程序#include <msp430g2553.h>#include"Key&Display.h"//unsigned char Receive(void);void main( void ){// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD;Init_4lines_Mode();//初始化4线工作模式Send_Command(CH452_RESET);//CH452芯片内部复位Send_Command(KeyDisplay_ON);//允许显示驱动并启动键盘扫描//开中断,P2.0接CH452的DOUT引脚,当有键按下时,DOUT上产生由高到低的脉冲// P2SEL &= ~(BIT6+BIT7);P2IE|=BIT0;P2IES|=BIT0;P2IFG&=~BIT0;_EINT();while(1){}}//中断处理函数#pragma vector = PORT2_VECTOR//中断处理程序,接收到DOUT脉冲信号时,运行之__interrupt void Port2(void){unsigned char Keyvalue;Send_Command(CH452_GET_KEY);//单片机向CH452发送读取按键代码命令Keyvalue=Key_Read();// Keyvalue=Receive();switch(Keyvalue){case 0x40://按键K0按下{Send_Command( NDis1); //第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis00);//第0位数码管显示0break;}case 0x41://按键K1按下{Send_Command( NDis1); //第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis01);//第0位数码管显示1break;}case 0x42://按键K2按下{Send_Command( NDis1); //第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis02);//第0位数码管显示2break;}case 0x43://按键K3按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis03);//第0位数码管显示3break;}case 0x48://按键K4按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis04);//第0位数码管显示4break;}case 0x49://按键K5按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis05);//第0位数码管显示5break;}case 0x4A://按键K6按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis06);//第0位数码管显示6break;}case 0x4B://按键K7按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis07);//第0位数码管显示7break;}case 0x50://按键K8按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis08);//第0位数码管显示8break;}case 0x51://按键K9按下{Send_Command( NDis1);//第1位数码管不显示//Send_Command(Dis10);Send_Command(Dis09);//第0位数码管显示9break;}case 0x52://按键K10按下{Send_Command(Dis00);//第0个数码管显示字符"0"Send_Command(Dis11);//第1个数码管显示字符"1"break;}case 0x53://按键K11按下{Send_Command(Dis01);//第0个数码管显示字符"1"Send_Command(Dis11);//第1个数码管显示字符"1"break;}case 0x58://按键K12按下{Send_Command(Dis02);//第0个数码管显示字符"2"Send_Command(Dis11);//第1个数码管显示字符"1"break;}case 0x59://按键K13按下{Send_Command(Dis03);//第0个数码管显示字符"3"Send_Command(Dis11);//第1个数码管显示字符"1"break;}case 0x5A://按键K14按下{Send_Command(Dis04);//第0个数码管显示字符"4"Send_Command(Dis11);//第1个数码管显示字符"1"break;}case 0x5B://按键K15按下{Send_Command(Dis05);//第0个数码管显示字符"5"Send_Command(Dis11);//第1个数码管显示字符"1"break;}default:break;}P2IFG&=~BIT0;}4.红灯0.2秒闪一次,绿灯0.8秒闪一次#include <msp430g2553.h>void main(void){WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 &=~XTS; //配置时钟BCSCTL3 |=LFXT1S_2;IFG1 &=OFIFG;P1DIR |=BIT0+BIT6; // P1.0,P1.6 output P1OUT &=~BIT0; // P1.0,P1.6置0 P1OUT &=~BIT6;TACCR0 = 12000-1; //1秒定时,产生中断TACCR1 = 2400; //频率0.2*12000,定时0.2秒TACCR2 = 9600; //定时0.8秒TACTL = TASSEL_1 + MC_1+TAIE; // ACLK, 增计数模式TACCTL1 |=CCIE; // TACCR1中断使能TACCTL2 |=CCIE; // TACCR1中断使能_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt}// Timer_A3 Interrupt Vector (TA0IV) handler#pragma vector=TIMER0_A1_VECTOR__interrupt void Timer_A(void){switch( TA0IV ){case 2: P1OUT ^= BIT0; // 捕获/比较寄存器TACCR1break;case 4: P1OUT ^= BIT6;break; // 捕获/比较寄存器TACCR2case 10: break; // 未使用,计数达到TACCRO时执行中断,即1秒执行一次}}5.PMW波控制led灯亮度#include "msp430g2553.h"void main( void ){// Stop watchdog timer to prevent time out resetWDTCTL = WDTPW + WDTHOLD;P1DIR |=BIT6; //方向寄存器P1SEL |=BIT6; //功能寄存器TACTL=TASSEL_2+MC_1+ID_0; //定时器A控制寄存器选择增计数模式TACCTL1 |=OUTMOD_3; //捕获/比较控制寄存器TACCR0=1000-1;TACCR1=10;_BIS_SR(CPUOFF);}。
MSP430G2553单片机的中断使用格式

端口1中断函数多中断中断源:P1IFG.0~P1IFG7进入中断后应首先判断中断源,退出中断前应清除中断标志,否则将再次引发中断#pragma vector=PORT1_VECTOR__interrupt void Port1(){ //以下为参考处理程序,不使用的端口应当删除其对于中断源的判断。
if((P1IFG&BIT0) == BIT0){ //处理P1IN.0中断P1IFG &= ~BIT0; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT1) ==BIT1){//处理P1IN.1中断P1IFG &= ~BIT1; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT2) ==BIT2){//处理P1IN.2中断P1IFG &= ~BIT2; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT3) ==BIT3){//处理P1IN.3中断P1IFG &= ~BIT3; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT4) ==BIT4){//处理P1IN.4中断P1IFG &= ~BIT4; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT5) ==BIT5){//处理P1IN.5中断P1IFG &= ~BIT5; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT6) ==BIT6){//处理P1IN.6中断P1IFG &= ~BIT6; //清除中断标志//以下填充用户代码}else{//处理P1IN.7中断P1IFG &= ~BIT7; //清除中断标志//以下填充用户代码}}端口2中断函数多中断中断源:P2IFG.0~P2IFG7进入中断后应首先判断中断源,退出中断前应清除中断标志,否则将再次引发中断*****************************************************************************/ #pragma vector=PORT2_VECTOR__interrupt void Port2(){//以下为参考处理程序,不使用的端口应当删除其对于中断源的判if((P2IFG&BIT0) == BIT0){//处理P2IN.0中断P2IFG &= ~BIT0; //清除中断标志//以下填充用户代码}else if((P2IFG&BIT1) ==BIT1){//处理P2IN.1中断P2IFG &= ~BIT1; //清除中断标志//以下填充用户代码 }else if((P2IFG&BIT2) ==BIT2){//处理P2IN.2中断 P2IFG &= ~BIT2; //清除中断标志//以下填充用户代码 }else if((P2IFG&BIT3) ==BIT3){//处理P2IN.3中断 P2IFG &= ~BIT3; //清除中断标志//以下填充用户代码}else if((P2IFG&BIT4) ==BIT4){//处理P2IN.4中断P2IFG &= ~BIT4; //清除中断标志//以下填充用户代码 }else if((P2IFG&BIT5) ==BIT5){//处理P2IN.5中断P2IFG &= ~BIT5; //清除中断标志//以下填充用户代码}else if((P2IFG&BIT6) ==BIT6){//处理P2IN.6中断P2IFG &= ~BIT6; //清除中断标志//以下填充用户代码}else{//处理P2IN.7中断P2IFG &= ~BIT7; //清除中断标志//以下填充用户代码}}USART0发送中断函数******************************************************************************/ #pragma vector=USART0TX_VECTOR__interrupt void Usart0Tx(){//以下填充用户代码}USART0接收中断函数******************************************************************************/ #pragma vector=USART0RX_VECTOR__interrupt void Usart0Rx(){//以下填充用户代码}USART1发送中断函数******************************************************************************/ #pragma vector=USART1TX_VECTOR__interrupt void Usart1Tx(){//以下填充用户代码}SART1接收中断函数******************************************************************************/ #pragma vector=USART1RX_VECTOR__interrupt void Ustra1Rx(){//以下填充用户代码}基本定时器中断函数******************************************************************************/ #pragma vector=BASICTIMER_VECTOR__interrupt void BasTimer(){//以下填充用户代码}定时器A中断函数多中断中断源:CC1~2 TA******************************************************************************/#pragma vector=TIMER0_A1_VECTOR__interrupt void TimerA1(){//以下为参考处理程序,不使用的中断源应当删除switch (__even_in_range(TAIV, 10)){case 2: //捕获/比较1中断//以下填充用户代码break;case 4: //捕获/比较2中断//以下填充用户代码break;case 10: //TAIFG定时器溢出中断//以下填充用户代码break;}}定时器A中断函数中断源:CC0******************************************************************************/ #pragma vector=TIMERA0_VECTOR__interrupt void TimerA0(){//以下填充用户代码}多中断源:CC1~6 TB******************************************************************************/ #pragma vector=TIMERB1_VECTOR__interrupt void TimerB1(){//以下为参考处理程序,不使用的中断源应当删除switch (__even_in_range(TBIV, 14)){case 2: //捕获/比较1中断//以下填充用户代码break;case 4: //捕获/比较2中断//以下填充用户代码break;case 6: //捕获/比较3中断//以下填充用户代码break;case 8: //捕获/比较4中断//以下填充用户代码break;case 10: //捕获/比较5中断//以下填充用户代码break;case 12: / /捕获/比较6中断//以下填充用户代码break;case 14: //TBIFG定时器溢出中断//以下填充用户代码break;}}中断源:CC0******************************************************************************/ #pragma vector=TIMERB0_VECTOR__interrupt void TimerB0(){//以下填充用户代码}AD转换器中断函数多中断源:摸拟0~7、VeREF+、VREF-/VeREF-、(AVcc-AVss)/2 没有处理ADC12TOV和ADC12OV中断标志******************************************************************************/ #pragma vector=ADC_VECTOR__interrupt void Adc(){//以下为参考处理程序,不使用的中断源应当删除if((ADC12IFG&BIT0)==BIT0){ //通道0//以下填充用户代码}else if((ADC12IFG&BIT1)==BIT1){ //通道1//以下填充用户代码}else if((ADC12IFG&BIT2)==BIT2){ //通道2//以下填充用户代码}else if((ADC12IFG&BIT3)==BIT3){ //通道3//以下填充用户代码}else if((ADC12IFG&BIT4)==BIT4){ //通道4//以下填充用户代码}else if((ADC12IFG&BIT5)==BIT5){ //通道5//以下填充用户代码}else if((ADC12IFG&BIT6)==BIT6){ //通道6//以下填充用户代码}else if((ADC12IFG&BIT7)==BIT7){ //通道7//以下填充用户代码 }else if((ADC12IFG&BIT8)==BIT8){ //VeREF+//以下填充用户代码 }else if((ADC12IFG&BIT9)==BIT9){ //VREF-/VeREF-//以下填充用户代码}else if((ADC12IFG&BITA)==BITA){ //温度//以下填充用户代码}else if((ADC12IFG&BITB)==BITB){ //(A Vcc-A Vss)/2//以下填充用户代码}}看门狗定时器中断函数******************************************************************************/ #pragma vector=WDT_VECTOR__interrupt void WatchDog(){//以下填充用户代码}比较器A中断函数******************************************************************************/ #pragma vector=COMPARA TORA_VECTOR__interrupt void ComparatorA(){//以下填充用户代码}不可屏蔽中断函数******************************************************************************/ #pragma vector=NMI_VECTOR__interrupt void Nmi(){//以下为参考处理程序,不使用的中断源应当删除if((IFG1&OFIFG)==OFIFG){ //振荡器失效IFG1 &= ~OFIFG;//以下填充用户代码}else if((IFG1&NMIIFG)==NMIIFG){ //RST/NMI不可屏蔽中断IFG1 &= ~NMIIFG;//以下填充用户代码}else //if((FCTL3&ACCVIFG)==ACCVIFG){ //存储器非法访问FCTL3 &= ~ACCVIFG;//以下填充用户代码}}中断优先级:优先级顺序从高到低为:PORT2_VECTOR (1 * 2u) /* 0xFFE2 Port 2 */PORT1_VECTOR (4 * 2u) /* 0xFFE8 Port 1 */TIMER0_A1_VECTOR (5 * 2u) /* 0xFFEA Timer A CC1-2, TA */TIMER0_A0_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] */。
msp430按键中断_V1.01

• 软件中断(内中断) • 硬件中断(外中断)
• 非屏蔽中断 • 可屏蔽中断
4
开启总中断
5
中断响应和中断处理流程
当CPU收到中断或者异常的 信号时,它会暂停执行当前的程 序或任务,通过一定的机制跳转 到负责处理这个信号的相关处理 程序中,在完成对这个信号的处 理后再跳回到刚才被打断的程序 或任务中。
14
I/O中断实列
这是一个利用中断控制LED的亮灭实验,初始时LED常亮,按下按键,LED亮灭切换
15
IO 外部中断使用方法
高级单片机的全部 IO 口都带外部中断功能,MSP430 单片机要使用外部中断,遵 循以下步骤:
1) 通过 PxDIR 将 IO 方向设为输入。 2) 通过写 PxIES,决定中断的边沿是上升沿、下降沿或两种情况均中断。 3) 如果是机械按键输入,可以通过 PxREN 启用内部上下拉电阻,根据按键 的接法,设
7
MSP430中的中断系统
这是一个用户手册
8
MSP430F6638的P1到 P4都具有中断的功能
翻到msp430f6 638_Datasheet 第6章表6.3
9
中断嵌套
如果在中断服务子程中置位GIE(开全局中断),则允许 中断嵌套。 在允许中断嵌套的情况下,任何中断请求均将中断正在 执行的中断服务子程序,而不管中断的优先级如何。 (中断优先级仅用于裁决同时产生的中断请求)
CPU执行流程 中断申请
set GIE
中断子程序1
中断子程序2
10
I/O寄存器
使用实列:
P2DIR |= BIT7; //设P2.7为输出 P2DIR为方向寄存器,输出为1,输入为0. P2OUT |= BIT7; //初始化P2.7为高电平 P2OUT是输出数据寄存器,可控制管脚输出电平的高低,输出为
MSP430中断以及一个键盘的例子

最近在学习和实践的过程中接触到了线程的概念。
当你需要处理一大堆数据或者等待一个事件发生时候,系统其实并不需要等在那里,只需建立一个线程,适时的让它在后台运行,处理这些很占用系统的事件。
我想这与中断的功能很是相似,有些时候你让程序卡在那里仅仅是为了等待一个参数的改变,而这个参数完全可以在中断中实现修改,所以巧妙的使用中断对于高效的程序是必须的。
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键盘程序[中断方式

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();}}。
430单片机之中断

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,当响应用户不可屏蔽中断后,其他不可屏蔽中断就自动被禁止,以防止同级别的中断发生产生中断嵌套。
实验2 按键输入与中断

实验2 按键输入与中断实验目的:学习MSP430的中断系统,及其编程方法。
重点难点:中断REG的使用方法。
实验内容按下DY-FFTB6638实验箱的KEY1,产生一个中断请求,在中断服务程序中,点亮对应的LED。
实验原理DY-FFTB6638实验箱的KEY硬件电路如下:设计参考代码//******************************************************************************// MSP430F6638 Demo - Software Toggle P4//// Description: Toggle P4 by xor'ing P4 inside of a software loop.// ACLK = 32.768kHz, MCLK = SMCLK = default DCO~1MHz//// MSP430F6638// -----------------// /|\| |// | | |// --|RST P4.4|-->LED_RED// KEY1-->|P4.2 P4.5|-->LED_GREEN// | P4.6|-->LED_YELLOW////******************************************************************************#include"msp430f6638.h"unsigned char flag;void main(void){WDTCTL = WDTPW+WDTHOLD; // Stop WDTP4DIR &=~(BIT2);P4DIR |= BIT4+BIT5+BIT6; // P4.4,P4.5,P4.6 set as outputP4OUT &=~(BIT4+BIT5+BIT6); // set led offP2IE |= BIT6; // enable P2.6 interruptP2IFG &= ~(BIT6); // clean interrupt flag__enable_interrupt(); // enable interruptwhile(1){if((P4IN & 0x04)==0) // P4.2--KEY1{P2IFG |= BIT6;}else{P2IFG &=~BIT6;}}}// PORT2 interrupt service routine#pragma vector=PORT2_VECTOR__interrupt void port_2(void){P4OUT ^=(BIT4+BIT5+BIT6); // set led onP2IFG &=~BIT6; // clean interrupt flag}总结MSP430单片机仅P1和P2端口具有中断功能,程序中开启了P2.6的中断功能,而按键信号却是从P4.2输入的,如何解释?。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
msp430中断方式实现键盘扫描例程
类别:技术文章
来源:未知
作者:未知
关键字:键盘扫描
加入日期:2010-5-1
// 此示例程序为中断方式,得到键盘的键值,存放在队列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;
else
if((P1IN&0X70)==0X20)
x=1;
else
if((P1IN&0X70)==0x40)
x=2;
else
{
P1OUT=0X2; //扫描第二行
if((P1IN&0X70)==0X10)
x=3;
else
if((P1IN&0X70)==0X20)
x=4;
else
if((P1IN&0X70)==0x40)
x=5;
else
{
P1OUT=0X4; //扫描第三行
if((P1IN&0X70)==0X10)
x=6;
else
if((P1IN&0X70)==0X20)
x=7;
else
if((P1IN&0X70)==0x40)
x=8;
else
{P1OUT=8; //扫描第四行
if((P1IN&0X70)==0X10)
x=9;
else
if((P1IN&0X70)==0X20)
x=10;
else
if((P1IN&0X70)==0x40)
x=11;
}
}
}
return(x);
}
unsigned char keyj(void)
{unsigned char x;
P1DIR=0x0f;
P1OUT=0x0f; //键盘硬件:P10--P13为行线,最上面一根为P10
x=(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();
}
}。