msp430中断扫描键盘例程

合集下载

MSP430单片机应用中键盘的软件设计

MSP430单片机应用中键盘的软件设计
30
按键设计在行、 列线交叉上, 行列线分别连接到按键开关 的两端。当行线通过上拉电阻接 +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按键控制灯亮程序

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单片机的中断使用格式

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

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中断以及一个键盘的例子

最近在学习和实践的过程中接触到了线程的概念。

当你需要处理一大堆数据或者等待一个事件发生时候,系统其实并不需要等在那里,只需建立一个线程,适时的让它在后台运行,处理这些很占用系统的事件。

我想这与中断的功能很是相似,有些时候你让程序卡在那里仅仅是为了等待一个参数的改变,而这个参数完全可以在中断中实现修改,所以巧妙的使用中断对于高效的程序是必须的。

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键盘程序[中断方式

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单片机之中断

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 按键输入与中断

实验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输入的,如何解释?。

MSP430程序库七按键

MSP430程序库七按键

MSP430程序库七按键msp430程序库按键键是单片机系统中最常用的输入设备之一;几乎只要需要交互式输入,就必须有键盘。

这个博客实现了一个通用键盘程序。

只要它提供一个读取键值(底部键值)的函数,程序就会完成一些列处理,比如去抖振、存储在队列中等等。

同时,本程序提供了最常用的4*4矩阵键盘程序和4键程序。

硬件介绍:本文主要实现了一个键盘的通用框架,可以很方便的改为不同的键盘函数,这里实现了两种按键4个单独按键和4*4行列扫描的键盘。

四个按键的工作原理如下:四个按键的一端接地,另一端连接上拉电阻,然后输入单片机0-P1的P1。

3个港口;这样,当按键时,单片机接收到一个低电平。

释放时,单片机输入信号具有上拉电阻,并固定在高电平。

4*4的按键:行输入信号配有桑拉电阻,无按键时默认电平高电平;列扫描信号线直接接到按键列线;读键时,列扫描信号由单片机给出低电平信号(按列逐列扫描),读取行信号,从而判断具体是哪个按键;电路图大概如下:在图中,In是键盘的列扫描线,out是键盘输出的行信号线。

扫描也可以按行扫描。

此时,in是行扫描行,out是键输出的列信号行。

我的程序按列扫描(行和列扫描的原理相同,但行和列是交换的)。

这里,同时实现了4*4按键的scanf函数的移植,同时,加入了之前实现的液晶的printf函数的移植,搭建了一个可以交互输入输出的完整的一个系统;液晶的printf又加入了函数,实现了退格;可以在输入错误数字的时候退格重新输入。

程序实现:首先,我们来谈谈这个项目的结构。

该程序实现了一个循环队列来存储按下的键值。

可以保存最新的四把钥匙,防止钥匙丢失;程序使用中断模式按键。

每16毫秒读取一次按键(使用看门狗的间隔中断),以判断按键值是否有效。

如果有效,将其放入队列并等待读取。

循环队列的实现:通过数组实现。

为了判断队列是否已满,数组的最后一个元素不需要存储密钥代码值:/**********************宏定义***********************/#definekeysize4//键码值队列#definelengthkeysize+1//队列数组元素个数/***************************************************//**********************键值队列*********************///可keysize(length-1)个键码循环队列占用一个元素空间charkey[length];入队函数:入队时,队满则出队一个,以保存最新的四个按键。

msp430非常详细有用的讲解和例程

msp430非常详细有用的讲解和例程

7
6
5
DCO.2 DCO.1 DCO.0
4 MOD.4
3 MOD.3
2 MOD.2
1 MOD.1
0 MOD.0
DCO.0-DCO.4 定义 8 种频率之一,可以分段调节 DCOCLK 频率,相邻两种频率相差 10%。而频率由注入直流发生器的电流定义。
MOD.0-MOD.4 定义在 32 个 DCO 周期中插入的 Fdco+1 周期个数,而在下的 DCO 周期 中为 Fdco 周期,控制改换 DCO 和 DCO+1 选择的两种频率。如果 DCO 常数为 7,表示 已经选择最高频率,此时不能利用 MOD.0-MOD.4 进行频率调整。
低功耗设置的技巧问题: 1、LPM4:在振荡器关闭模式期间,处理机的所有部件工作停止,此时电流消
耗最小。此时只有在系统上电电路检测到低点电平或任一请求异步响应中断的外部中断 事件时才会从新工作。因此在设计上应含有可能需要用到的外部中断才采用这种模式。 否则发生不可预料的结果。
2、LPM3:在 DC 发生器关闭期间,只有晶振是活动的。但此时设置的基本时序条 件的 DC 发生器的 DC 电流被关闭。由于此电路的高阻设计,使功耗被抑制。注:当从 DC 关闭到启动 DC0 要花一端时间 (ns-us)
微控网供应 MSP430 单片机系列开发工具,欢迎订购。 模块列表 1- 复位模块 2- 时钟模块 3- IO 端口模块 4- WDT 看门狗模块 5- Timer A 定时器模块 6- 比较器 A 模块 7- ADC12 数模转换模块 8- USART 串行异步通讯模块 9- CPU 模块及全局资料 10-MSP430 其它应用介绍
3-SMCLK: 子 系 统 时 钟 , SMCLK 是 由 2 个 时 钟 源 信 号 所 提 供 . 他 们 分 别 是 XT2CLK(F13、F14)和 DCO,如果是 F11、F11X1 则由 LFXT1CLK 代替 TX2CLK。同样 可设置相关寄存器来决定分频因子及相关的设置。

MSP430-IO中断方式按键检测

MSP430-IO中断方式按键检测

MSP430-IO中断方式按键检测MSP430入门教程专题(六)——IO中断方式按键检测//MSP430F14-利用IO中断方式实现按键检测程序/************************************************************** ***********///以下是结合MC430F14开发板来实现的按键检处理程序实验.//分别使用了采个三个按键接到MSP430的通用IO口,按任意一个按键可以使板上的LED反转.//例程中,单片机一直处于最低功耗状态,用户可以通过按下按键后唤醒单片机.单片机唤醒//后再进行去抖动动作.同时执行键处理程序.处理完后再次进入LPM4低功耗模式. //在本程序中用户可以灵活地修改程序来实现你相关的功能.//本程序适用在手持设备或电池供电的设计中.此程序结构比较通用,级用户可参与或套用修改.//应用目标板:MC430F14x开发板/************************************************************** ***********/#include#define key1 0x01#define key2 0x02#define key3 0x04#define delay_small 200#define key_1 0xfe //定义返回键值1#define key_2 0xfd //定义返回键值2#define key_3 0xfb //定义返回键值3void key_process_0(void);void key_process_1(void);void key_process_2(void);void key_check (void);unsigned char key_value; //定义键值全局变是//************************************************************* ************void main(void){WDTCTL = WDTPW + WDTHOLD; // 停止看门狗P1OUT |= BIT1; //关LEDP1DIR |= BIT1; // 设置P1.1为输出//以下设置是采用不同的编写方式,新手可以参考使用P2IE |= BIT0+BIT1+BIT2; // P2.0-P2.2 IO口中断使能P2IES |= 0x07; // P2.0-P2.2 IO口边沿触发中断方式设置P2IFG &= ~(key1+key2+key3); // P2.0-P2.2 IO口中断标志位清除_EINT(); //中断允许// 或直接写成 _BIS_SR(LPM4_bits + GIE);LPM4; // 进入低功耗LPM4,此时单片机功耗最低while(1){P2IE &= ~(BIT0+BIT1+BIT2); // P2.0-P2.2 IO口关闭中断允许P2IFG &= ~0x07; // P2.0-P2.2 IO口中断标志位清除key_check ();switch (key_value) //对键值进行处理.采switch语法结构查询 { case key_1: key_process_0(); //调用键处理程序1break;case key_2: key_process_1(); //调用键处理程序2break;case key_3: key_process_2(); //调用键处理程序2break;default: break;}key_value=0x00; //键值清除P2IE |= BIT0+BIT1+BIT2; // P2.0-P2.2 IO口中断使能P2IFG &= ~0x07; // P2.0-P2.2 IO口中断标志位清除LPM4;}}//************************************************************* ************//P2中断服务程序#pragma vector=PORT2_VECTOR__interrupt void Port_2(void){switch (P2IFG){case 0x01: key_value=0xfe;break;case 0x02: key_value=0xfd;break;case 0x04: key_value=0xfb;break;default: P2IFG &= ~0x07; // P2.0-P2.2 IO口中断标志位清除break;}P2IFG &= ~0x07; // P2.0-P2.2 IO口中断标志位清除LPM4_EXIT;}//************************************************************* ************ void key_process_0(void) //值处理,用户可以自己修改...{P1OUT ^= BIT1;}//************************************************************* ************ void key_process_1(void) //值处理,用户可以自己修改...{P1OUT ^= BIT1;}//************************************************************* ************ void key_process_2(void) //值处理,用户可以自己修改...{P1OUT ^= BIT1;}//************************************************************* ************* void key_check (void){ unsigned int i;for(i=0;i<="">if(0xff !=(P2IN & 0xf8)) //是否有键存在?{while(0xff !=( P2IN | 0xf8)); //一直等待按键松开}elsekey_value = 0x00; //延时去抖动无键按下,则清除键变量. }//************************************************************* ************* //如果在按键电路中加RC滤波电路,实现按键去抖动的效果会更显著此.。

用单片机中断来扫描键盘的程序

用单片机中断来扫描键盘的程序

用单片机中断来扫描键盘的程序用单片机中断来扫描键盘的程序/*程序效果:用51单片机的中断来扫描键盘,按下按键,蜂鸣器响,数码管有相应的键值显示,按下E键继电器关,按下C键继电器开。

这与上一程序的功能相同,比上一程序简洁但理解相对困难些。

开发设计:/*/#include<reg52.h> //头文件#include<intrins.h>#define uchar unsigned char //宏定义#define uint unsigned intsbit jdq=P3^5; //位声明,驱动继电器管脚sbit fmq=P3^4; //位声明,驱动蜂鸣器管脚code uchar table[]={0x3f,0x06,0x5b,//数码管显示的数值0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};code uchar key_tab[17]={ //此数组为键盘编码0xed,0x7e,0x7d,0x7b, // 0,1,2,3,0xbe,0xbd,0xbb,0xde, // 4,5,6,7,0xdd,0xdb,0x77,0xb7, // 8,9,a, b,0xee,0xeb,0xd7,0xe7,0xff}; // c,d,e,f,uchar l_key=0x00; //定义变量,存放键值uchar l_keyold=0xff; //作为按键放开否的凭证void readkey(); //扫描键盘,获取键值void display(uchar *lp,uchar lc); //显示子函数void delay(); //延时子函数void main() //主函数{EA=1; //打开总中断EX0=1; //打开外部中断P0=0xf0; //键值高4位为高电平,低4位为低电平while(1){display(&l_key,1); //调用显示子函数if(l_key==14) //是否按下E键,是则关闭继电器jdq=1;if(l_key==12) //是否按下C键,是则打开继电器jdq=0;}}void key_scan() interrupt 0//外部中断0,0的优先级最高{EX0=0; //在读键盘时,关闭外部中断,防止干扰带来的多次中断TMOD&=0xf1; //设置定时器为工作方式1TH0=0x2e; //设置初值,为12毫秒,十进制值为11776TL0=0x00;ET0=1; //开启定时器中断0TR0=1; //启动定时器计数}void time0() interrupt 1 //定时器0的中断函数{TR0=0; //关闭定时器0readkey(); //定时12ms后产生中断,调用此函数,读取键值}void readkey() //扫描键盘子函数{uchar i,j,key; //定义局部变量j=0xfe; //设定初值key=0xff;for(i=0;i<4;i++) // 逐列扫描键盘{P0=j;if((P0&0xf0)!=0xf0) //有按键按下,高4位不可能全为1 {key=P0; //读取P0口的值,推出循环,否则循环下次break;}j=_crol_(j,1); //此函数的功能是:左移循环}if(key==0xff) //如果读取不到P0口的值,如干扰,则返回{l_keyold=0xff;P0=0xf0; // 恢复P0口的值,等待按键按下fmq=1;EX0=1; //在返回前,打开外部中断return;}fmq=0; //有按键按下,打开蜂鸣器if(l_keyold==key) // 检查按键放开否,如果相等表明没有放开{TH0=0x2e; //设置初值TL0=0x00;TR0=1; //继续启动定时器,检查按键放开否return;}TH0=0x2e;TL0=0;TR0=1; //启动定时器l_keyold=key; //获取键值,作为放开否的凭证for(i=0;i<17;i++) //查表获得相应的16进制值存放到l_key中{if(key==key_tab[i]){l_key=i;break;}}//程序运行到此,就表明有键值存放到l_key中,主程序//就可以检测键盘值并作相应的处理}void display(uchar *lp,uchar lc) //显示子函数{uchar i; //定义局部变量P1=0xf8; //点亮第一个数码管P2=0; //P2口为输出值for(i=0;i<lc;i++) //循环显示{P2=table[lp[i]]; //查表获得相应的要显示的数字的数码段delay(); //延时P2=0; //清零,准备显示下一个数值}}void delay() //延时子函数{_nop_();_nop_();_nop_();_nop_();_nop_();}如果程序无法编译,请删除所有前导空白.。

MSP430_按键的定时器扫描

MSP430_按键的定时器扫描

MSP430_按键的定时器扫描//按键的定时器扫描:每1ms进入一次time中断,10ms进行一次按键检测。

#includechar Key_Pressed_Flag=0;//按键标志位char Key_Front=1, Key_Current=1;//上次按键值,本次按键值int Key_Det_1ms_Cnt=0;int main(void){WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗//配置系统时钟DCOCTL = 0;BCSCTL1 = CALBC1_1MHZ; // 设置 DCO为1MDCOCTL = CALDCO_1MHZ;//配置定时器P1DIR |=BIT0; // 2P1.0为输出P1OUT |=BIT0; //初始化CCTL0 = CCIE; // CCR0中断使能CCR0 = 1000; //设置定时器计数值TACTL = TASSEL_2 + MC_1; // SMCLK为定时器时钟,向上计数模式//配置按键P1SEL &= ~(BIT3); // 1设置P1.3为IO口P1DIR &= ~BIT3; // 2设置P1.3为输入P1REN |= BIT3; // 3使能SW2为上下拉 (P1.3)P1OUT |= BIT3; // 4设置SW2为上拉 (P1.3)//配置串口模块P1SEL |= BIT1 + BIT2 ; // 配置引脚P1SEL2|= BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TX UCA0CTL1 |= UCSSEL_2; // 模块时钟选择为SMCLK UCA0BR0 = 104; // 设置波特率UCA0BR1 = 0; // 1MHz/104=9600bpsUCA0MCTL = UCBRS0; // 调整波特率UCA0CTL1 &= ~UCSWRST; // **使能系统复位** IE2 |= UCA0RXIE; // 使能USCI_A0接收中断//使能全局中断_BIS_SR(GIE); // 使能中断while(1){//按键处理if(Key_Pressed_Flag){Key_Pressed_Flag=0;P1OUT ^=BIT0; //位的异或运算:使得输出改变}}}// Timer A0 interrupt service routine#pragma vector=TIMER0_A0_VECTOR__interrupt void Timer_A (void){//基于定时器的按键检测Key_Det_1ms_Cnt++;//计数器if(Key_Det_1ms_Cnt==10){Key_Det_1ms_Cnt=0;//计数器置0,为下一次计数做准备Key_Current=BIT3 & P1IN;if((Key_Current==0)&&(Key_Front>0))Key_Pressed_Flag=1;Key_Front=Key_Current;}}// Echo back RXed character, confirm TX buffer is ready first #pragma vector=USCIAB0RX_VECTOR__interrupt void USCI0RX_ISR(void){while (!(IFG2&UCA0TXIFG)); // 检测发送是否准备好UCA0TXBUF = UCA0RXBUF; // 将接收数据发送给主机}。

MSP430矩阵键盘程序

MSP430矩阵键盘程序

/***************************************************************** ***********keyboard for MSP430Designed by CUGer——Mr.Wei程序可用,当系统时钟改变时,注意修改按键消抖延时***************************************************************** ***********/#include<msp430x16x.h>#define KEY_DIR P1DIR#define KEY_OUT P1OUT#define KEY_INP1IN#define KEY_IEP1IE#define KEY_IES P1IES#define KEY_IFG P1IFG/***************全局变量***************/unsigned char Key_Val;void CtrlKey(unsigned char sw);/*******************************************函数名称:Init_Keypad功能:初始化扫描键盘的IO端口参数:无返回值:无********************************************/void Init_Keypad(void){KEY_DIR=0x0f;态,P1.4~P1.7输入状态(上拉H)KEY_OUT&=0xf0;(卫编)KEY_IES =0xf0;KEY_IE=0xf0;KEY_IFG= 0;Key_Val=16;值均可}/******************************************* 函数名称:Check_Key功能:扫描键盘的IO端口,获得键值参数:无//存放键值//控制键盘开关//sw=0关sw=1开//P1.0~P1.3设置为输出状//P1.0~P1.3输出为低电平//P1.4~P1.7下降沿触发中断//P1.4~P1.7允许中断//中断标志清0//按键值初始设为非0~15的返回值:无********************************************/ //p14\5\6\7接上拉电阻/***************************************key_Val对应键值列:[p14][p15][p16][p17]↓↓↓↓行:[p13]→0123[p12]→4567[p11]→891011[p10]→***************************************/void Check_Key(void){unsigned char hang ,lie,tmp1,tmp2;unsigned char keymap[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};//设置键盘逻辑键值与程序计算键值的映射tmp1 = 0x08;for(hang = 0;hang < 4;hang++)//行扫描{KEY_OUT = 0x0f;//P1.0~P1.3输出全1KEY_OUT -= tmp1;//P1.0~p1.3输出四位中有一个为0tmp1 >>=1;if((KEY_IN & 0xf0)<0xf0)//是否P1IN的P1.4~P1.7中有一位为0{tmp2 = 0x10;// tmp2用于检测出哪一位为0for(lie = 0;lie < 4;lie++)//列检测{if((KEY_IN & tmp2) == 0x00)//是否是该列,等于0为是{Key_Val = keymap[hang*4 + lie];//获取键值return;//退出循环}tmp2 <<= 1;// tmp2右移1位}}}}/*******************************************函数名称:delay功能:延时约15ms,完成消抖功能参数:无返回值:t= tmp*5*clk根据使用时钟调整tmp值********************************************/void delay(void){unsigned int tmp;for(tmp = 12000;tmp > 0;tmp--);}/*******************************************函数名称:Key_Event功能:检测按键,并获取键值参数:无返回值:无********************************************/ void Key_Event(void){unsigned char tmp;KEY_OUT=0;设置P1OUT全为0,等待按键输入tmp=KEY_IN;获取p1INif((tmp&0xf0)<0xf0)键按下{delay();除抖动Check_Key();调用check_Key(),获取键值switch(Key_Val)//P2.0~P2.3接发光二极管,测试程序用{case 0:P2DIR|=BIT0;P2OUT |=BIT0;delay();P2OUT ^=BIT0;break;case 1:P2DIR|=BIT1;P2OUT |=BIT1; delay();P2OUT ^=BIT1;break;case 2:P2DIR|=BIT2;P2OUT |=BIT2; delay();P2OUT ^=BIT2;break;case 3:P2DIR|=BIT3;P2OUT |=BIT3; delay();P2OUT ^=BIT3;break;case 4:P2DIR|=BIT0;P2OUT |=BIT0; delay();P2OUT ^=BIT0;break;case 5:P2DIR|=BIT1;P2OUT |=BIT1; delay();P2OUT ^=BIT1;break;case 6:P2DIR|=BIT2;P2OUT |=BIT2; delay();P2OUT ^=BIT2;break;case 7:P2DIR|=BIT3;P2OUT |=BIT3; delay();P2OUT ^=BIT3;break;case 8:P2DIR|=BIT0;P2OUT |=BIT0; delay();P2OUT ^=BIT0;break;case 9:P2DIR|=BIT1;P2OUT |=BIT1; delay();P2OUT ^=BIT1;break;case 10: P2DIR|=BIT2;P2OUT |=BIT2; delay();P2OUT ^=BIT2;break;//////如果有//消//case 11: P2DIR|=BIT3;P2OUT |=BIT3; delay();P2OUT ^=BIT3;break;case 12: P2DIR|=BIT0;P2OUT |=BIT0; delay();P2OUT ^=BIT0;break;case 13: P2DIR|=BIT1;P2OUT |=BIT1; delay();P2OUT ^=BIT1;break;case 14: P2DIR|=BIT2;P2OUT |=BIT2; delay();P2OUT ^=BIT2;break;case 15: P2DIR|=BIT3;P2OUT |=BIT3; delay();P2OUT ^=BIT3;break;default :break;}}}/********************************************************** ***********控制打开或者关闭键盘中断SW= 0:关闭;ELSE:打开***************************************************************** ****/void CtrlKey(unsigned char sw){if(sw==0)KEY_IE =0;//关闭端口中断elseKEY_IE =0xf0; //打开端口中断}/****************************************************************** ***主函数***************************************************************** ****/void main(){WDTCTL=WDTPW+WDTHOLD;//关闭看门狗Init_Keypad();//键盘初始化delay();CtrlKey(1);//键盘打开while(1)Key_Event();//不断扫描,获取键值}/*端口1按键中断*/#pragma vector=PORT1_VECTOR__interrupt void Port(void){if((KEY_IFG&0xf0)!=0){Key_Event();if(Key_Val!=16)//键值!=16有键按下{CtrlKey (0);//关键盘中断}}KEY_IFG=0;KEY_OUT=0;//清中断标志}。

MSP430并行数字输入输出端口中断的使用_6

MSP430并行数字输入输出端口中断的使用_6

第6章并行数字输入输出端口中断的使用——按键电路的设计目标通过本章的学习,应掌握以下知识●中断的概念和工作过程●MSP430微控制器芯片支持的中断类型●Embedded Workbench for MSP430开发软件的中断服务程序结构●按键开关●独立式键盘的原理电路●MSP430微控制器芯片的并行输入/输出端口涉及中断的相关寄存器●字节操作运算符●条件语句●多个数据的输入方法引言信号处理是电子线路的一项主要的工作。

处理信号必须具有一个被处理的对象,也就是需要使用某种方式将被处理的信号引入电路。

在数字系统中,键盘是一种常见的信息输入工具。

组成键盘的按键开关具有两种工作状态,因此通过按键开关的断开,或者接通,就能够完成数字量0,或者1,两种取值的输入。

组成电路以后,按键开关的断开和接通可以用高电平和低电平这2种数字电路的工作状态反映出来。

这样将按键电路与MSP430微控制器芯片的输入/输出管脚连接起来,通过读取管脚的状态就能够判断按键开关是否动作,从而接收外部输入的信息。

按键开关组成键盘的电路形式常用的有独立式键盘电路和矩阵式键盘电路两种。

独立式键盘电路无论电路结构,还是它的识别程序结构,都比较简单。

矩阵式键盘电路的优点是对微控制器芯片的输入/输出管脚的占用数量较少。

作为一本入门书籍,本章只涉及独立式键盘电路。

键盘电路的处理时间只占用微控制器工作时间非常少的部分,同时键盘的使用还是随机的,这样让微控制器不断地读取按键的工作状态,显然降低了系统对信号的处理速度。

中断的概念非常适合按键工作状态的识别。

16.1按键开关当需要向微控制器传送命令,或者输入数据时,键盘通常被使用。

键盘是一组按键开关的集合。

像数码管一样,键盘也是应用系统的一个重要组成部分。

按键开关具有2个状态,闭合或者断开。

组成合适的电路,这2个状态反映在电压上就是按键开关分别呈现出高电平,或者低电平。

在数字电路中,这两个电平分别用来表示数据1,或者0。

msp430单片机中断方式实现按键的单击、双击

msp430单片机中断方式实现按键的单击、双击

// Timer B0 interrupt service routine //定时中断函数 #pragma vector=TIMERB0_VECTOR __interrupt void Timer_B (void) //按键中断函数中的首次按键处理部分开启 了定时器 B,若此后一直无按键按下,或者是第二按键按下前双击事件时间间隔到了,定时
该按键单击、双击识别代码是在做基于 msp430 的课题时写出来的,采用 IO 口 2 的中断方 式实现,相比较于扫描方式,具有响应快,CPU 功耗低的特点。本代码可以移植到其他类 型的单片机中使用。 情景: 1、一次按键按下,不再按键,则判定为一次单击事件 2、一次按键按下,再次按下按键,前后两次时间>0.5s,则将首次按键判定为单击事件 3、一次按键按下,再次按下按键,前后两次时间<0.5s,则将两次按键判定为双击事件 代码分三部分:主函数按键查询函数,按键中断函数,定时器中断函数 #define KEY2SING 0 #define KEY2DOUB 1 unsigned char KEY2FLAG=KEYNDOWN; unsigned char KEY2TYPE; unsigned char KEY2DOWNNUM=0;
器会产生中断,这里可以表明首次按键按下为一次单击事件。 { TBCTL &= ~MC_1; KEY2DOWNNUM = 0; KEY2FLAG=KEYDOWN; KEY2TYPE=KEY2SING; } // Port 2 interrupt service routine //按键中断函数 #pragma vector=PORT2_VECTOR __interrupt void Port2_ISR (void) { if(KEY2DOWNNUM==0) //是首次按键按下,首次按键标志标记,初 始化定时器 B。这里注意一下,由于要对双击事件进行判断,会有个定时间隔,因而首次按 键按下时不能标志按键按下标志, 需要在定时完成后才能标志按键按下标志, 单击事件的响 应时间至少为 0.5s(可以通过减小双击事件的时间间隔来加快单击事件的响应,不建议设置 的很小,除非你的手指够快) { KEY2DOWNNUM = 1; TBCTL |= TBSSEL_1 + ID_3 + MC_1 + TBCLR; } else //非首次按键按下,能进行到这里表明定时 器的定时间隔没有到,即第二次的按键按下与首次按键按下可以算作一次双击事件。 { TBCTL &= ~MC_1; KEY2DOWNNUM = 0; KEY2FLAG = KEYDOWN; KEY2TYPE = KEY2DOUB; } P2IFG &//首次按下标志

msp430 按键控制LED 最基本程序

msp430 按键控制LED 最基本程序

按键篇经过一短时间的学习,下面,亲自动手编写一下程序吧。

程序的目的是:按下按键,控制LED的亮和灭。

短按键,则小灯亮1秒,然后灭;长按键,小灯常亮。

首先,完成键盘的扫描程序。

第一点:如果是扫描,就要用到定时器。

我想设计定时器每隔10ms扫描一次按键。

定时器,我选用定时器A。

它的定时中断函数如下:函数名称:TimerA_ISR功能:定时器A的中断服务函数参数:无返回值:无********************************************/#pragma vector = TIMERA0_VECTOR__interrupt void TimerA_ISR(void){GetKey();}上面这个定时中断函数的意思就是:每当定时时间到了以后,就调用GetKey()函数一次。

GetKey()函数就是扫描键盘按键的函数了。

在GetKey()函数中,会根据按键类型(长按/短按)返回不同的数值。

根据返回的数值,做小灯亮法的操作。

那么,返回的这个值,我们需要保存在一个变量中,在这里定义一个变量ucharFlagLcd ;来保存返回值。

这个变量在全局变量中定义,以保证它的作用域。

那么定时函数就变为#pragma vector = TIMERA0_VECTOR__interrupt void TimerA_ISR(void){FlagLcd =GetKey();}定时器中断的时间间隔,我在主函数中定义。

这样写:CCTL0 = CCIE; //使能CCR0中断CCR0 = 40; //设定周期0.01STACTL = TASSEL_1 + ID_3 + MC_1; //定时器A的时钟源选择ACLK,增计数模式这样,定时器这块就算完工了。

那么,下面进行按键扫描程序。

按键的定义是这样的,根据我板子的按键原理图如下这是一个矩阵键盘。

其中KEY就是外部高电平3.3V。

我只想用其中的P1.0作为这次试验的按键。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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();
}
}。

相关文档
最新文档