MSP430 中断问题

MSP430 中断问题,第1张

f149要用f149的头文件啦,不过在你这个IO中断程序里用g2211的貌似不影响;
P1IES |= 0x08是把P1IES的第4位置1,第4位刚好对应P13,P1IES是中断中断触发方向寄存器,置1是下降沿触发中断;
0x08是0b00001000,对应P13;
类似的:
0x01是0b00000001,对应P10;
0x02是0b00000010,对应P11;
0x04是0b00000100,对应P12依次类推,规律挺明显的。

没开P13的中断使能
在关狗那句下面加上:
P1IE |= BIT3; //打开P13中断
__bis_SR_register(GIE); //开总中断
现在应该就可以进入P1中断了。

//msp430F149
44矩阵键盘P1口中断扫描
#include<msp430x14xh>
#define
KEY_DIR
P1DIR
#define
KEY_OUT
P1OUT
#define
KEY_IN
P1IN
#define
KEY_IE
P1IE
#define
KEY_IES
P1IES
#define
KEY_IFG
P1IFG
/全局变量/
unsigned
char
Key_Val;
//存放键值
void
CtrlKey(unsigned
char
sw);
//控制键盘开关//sw=0关
sw=1开
/
函数名称:Init_Keypad

能:初始化扫描键盘的IO端口

数:无
返回值
:无
/
void
Init_Keypad(void)
{
KEY_DIR
=
0x0f;
//P10~P13设置为输出状态,P14~P17输入
状态(上拉H)
KEY_OUT=0;
KEY_IES
=0xf0;
//P14~P17允许中断
KEY_IE
=0xf0;
//P14~P17下降沿触发中断
KEY_IFG=0;
//中断标志清0
Key_Val
=
0;
}
/
函数名称:Check_Key

能:扫描键盘的IO端口,获得键值

数:无
返回值
:无
/
//p14\5\6\7
接上拉电阻
/
key_Val
对应键值
列:[p14]
[p15]
[p16]
[p17]




行:
[p13]→
1
2
3
4
[p12]→
5
6
7
8
[p11]→
9
10
11
12
[p10]→
13
14
15
16
/
void
Check_Key(void)
{
unsigned
char
row
,col,tmp1,tmp2;
unsigned
char
keymap[]
=
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};//设置键盘逻辑键值
与程序计算键值的映射
tmp1
=
0x08;
for(row
=
0;row
<
4;row++)
//行扫描
{
KEY_OUT
=
0x0f;
//P14~P17输出全1
KEY_OUT
-=
tmp1;
//P14~p17输出四位中有一个为0
tmp1
>>=1;
if((KEY_IN
&
0xf0)<0xf0)
//是否P1IN的P10~P13中有一位为0
{
tmp2
=
0x10;
//
tmp2用于检测出哪一位为0
for(col
=
0;col
<
4;col++)
//
列检测
{
if((KEY_IN
&
tmp2)
==
0x00)
//
是否是该列,等于0为是
{
Key_Val
=
keymap[row4
+
col];
//
获取键值
return;
//
退出循环
}
tmp2
<<=
1;
//
tmp2右移1位
}
}
}
}
/
函数名称:delay

能:延时约15ms,完成消抖功能

数:无
返回值
:t=
tmp5clk
根据使用时钟调整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;
//
获取
p1IN
if((tmp
&
0xf0)
<
0xf0)
//如果有键按下
{
delay();
//消除抖动
Check_Key();
//
调用check_Key(),获取键值
}
}
/
控制打开或者关闭键盘中断
SW=
0:关闭;
ELSE:打开
/
void
CtrlKey(unsigned
char
sw)
{
if(sw==0)
KEY_IE
=0;
//关闭端口中断
else
KEY_IE
=0xf0;
//打开端口中断
}
/端口1按键中断/
#pragma
vector=PORT1_VECTOR
__interrupt
void
Port(void)
{
if((KEY_IFG&0xf0)!=0)
{
Key_Event();
if(Key_Val!=0)
//键值!=0有键按下
{
CtrlKey(0);
//关键盘中断
}
}
KEY_IFG=0;KEY_OUT=0;
//清中断标志
}

大概看了眼,中断三里面有2个问题比较明显:

P1IFG&BIT6==BIT6 和 P1IFG&BIT6;P1IFG&BIT2==BIT2 和 P1IFG&BIT2是一个意思,这个你自己把思路屡清楚了。

清中断标志清错了,实际上是没有启动清中断标志的作用,所以中断标志一直有效,不断进入中断如下:

if(P1IFG&BIT2)
{
TA0CTL |=TACLR;
P1OUT |= 0x01;                           
P1IFG &= ~0x04;    //这里修改下                      
  P2OUT|= 0x10;
flag=1;
return;

if(P1IFG&BIT6)
{
CCTL0&= ~CCIE;
P1OUT |= 0x01;                           
P1IFG &= ~0x40;//修改                          
   P2OUT &=~0x10;
flag=0;
return;
  } }


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13212585.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-06-21
下一篇 2023-06-21

发表评论

登录后才能评论

评论列表(0条)

保存