打印

CY7C63813的中断冲突问题

[复制链接]
3599|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jackle_zheng|  楼主 | 2009-7-21 17:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
   求助!!!在使用cypress的CY7C63813的时候,碰到一个中断冲突问题,我搞不清原因。项目实现的功能就是把遥控器的按键动作封装成标准的USB mouse动作。硬件上,我通过一个GPIO口连接到一个红外接收管上。现在的问题是:一旦我打开PORT0的ISR,程序跑着跑着就死掉了,我做了个试验,在main函数while(1)中,让LED闪烁,只要我打开PORT0的ISR,不要一会儿,LED停止闪烁,程序跑死了。如果,我把boot.tpl中的PORT0中断跳转还原到默认的PORT0 ISR,注释掉自己写PORT0 ISR,那么LED等一直在闪烁,程序运行正常。
    我只发现了问题,但是搞不清为什么,所以,请教高手,这个PORT0的中断同其他的中断会不会有什么冲突,比如说,USB SIE的什么中断,我的PORT0 ISR如下:
void PORT0_ISR( void )
{
// key_pressed = 1;
 unsigned int i;
 unsigned int j;
 key_code_32 = 0;
 //P05CR &= ~0X40;
 //if(key_pressed)
 //{
  //INT_CLR0 |= 0X10;//clear P0.5 interrupt flag
  M8C_DisableIntMask(INT_MSK0,0x10);//disable P0.5 interrupt
  //key_pressed = 0;
  //start_9ms_delay = 1;
 //bootstrap_9ms = 9;//delay 9ms
  //while(bootstrap_9ms);
  for(j = 0;j<3200;j++)//delay 9ms
  {
   if(P0DATA & 0X20)//if p0.5 turn to high level,return,prevent mis-trigger
   {
   M8C_EnableIntMask(INT_MSK0,0x10);//enable P0.5 interrupt
   asm("reti");
   }
  }
  //start_9ms_delay = 0;
  //for(i = 0;i<12000;i++)//delay 6ms
  for(i = 0;i<2618;i++)//delay 6ms
   {
   if(!(P0DATA & 0X20))//if p0.5 turn to low level,jump out
   break;
   }
  for(i=0;i<32;i++)// get system codes and data codes,TOTAL 32BIT
 {
  while(!(P0DATA & 0X20));//WAIT FOR HIGH LEVEL
  //for(j = 0;j<5400;j++);//delay 0.9ms
  for(j = 0;j<540;j++);//delay 0.9ms
  if(P0DATA & 0X20)
    {
    key_code_32 |= 1;
    }
  key_code_32 <<= 1;
 }
 //  data_code = (unsigned char)((key_code_32&0x0000FF00)>>8);//get data code
 //data_code >>= 8;
// data_code_neg = (unsigned char)(key_code_32&0x000000FF);//get data anti-code
 //M8C_EnableIntMask(INT_MSK0,0x10);//enable P0.5 interrupt

   PRT1DR &= 0X7F;
   //delay();
  i = 65535;
 while(i)
 {
  i--;
 }
   PRT1DR |= 0X80;

 //if(data_code = ~data_code_neg)//check data valid
  // {
  // data_valid = 1;
   //LED blink
 //  PRT1DR &= 0X7F;
   //delay();
 //   i = 65535;
 //while(i)
// {
//  i--;
// }
 //  PRT1DR |= 0X80;
 //  }

  //P05CR |= 0X40;
  M8C_EnableIntMask(INT_MSK0,0x10);//enable P0.5 interrupt
  INT_CLR0 |= 0X10;//clear P0.5 interrupt flag
}
沙发
jackle_zheng|  楼主 | 2009-7-22 10:38 | 只看该作者

哪位兄弟帮忙转一下cypress的AE,谢谢哈

使用特权

评论回复
板凳
derekx| | 2009-7-22 11:21 | 只看该作者

你是如何调用Port0ISR中断程序的?

使用特权

评论回复
地板
jackle_zheng|  楼主 | 2009-7-22 13:24 | 只看该作者

GPIO口下降沿触发PORT0 ISR的

port0 isr实现的是remote controler的解码,红外脉冲的编码是9ms的引导码(低电平),接着4.5ms的高电平,然后开始数据的传送,通过高电平的长短来表示“1”或“0”。

使用特权

评论回复
5
jackle_zheng|  楼主 | 2009-7-22 14:21 | 只看该作者

我猜想是中断阻塞的问题

芯片内部集成了一个mstimer的计数器,对应的mstimer ISR实现的功能是USB polling interval的downcounter以及usb activity timeout检测。而我的port0口ISR执行完需要110ms左右,在此期间,1ms计时结束后,无法进入mstimer ISR,造成了阻塞。原因可能是这样的。还得琢磨怎么搞。有做过USB接收头接收红外遥控器的兄弟,帮帮忙,指点指点啊,

使用特权

评论回复
6
jxin| | 2009-7-23 17:05 | 只看该作者

可以发你的project上来看看吗

使用特权

评论回复
7
benedy| | 2009-7-23 17:48 | 只看该作者

中断没有返回

照你这样描述,我想是程序能够进入中断,但是进入中断服务程序后,没有返回,与标准的程序比一比,是不是你的中断程序少了返回指令。

使用特权

评论回复
8
jackle_zheng|  楼主 | 2009-7-23 17:56 | 只看该作者

谢了,jxin

    project里面的东西,我今天查找问题的时候,为了定位bug,有删减,mstimer模块也已经给删掉了,可能看起来比较吃力,不过代码还在,呵呵。
    在PORT0中断服务程序中,实现的功能是红外信号接收,采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms 的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms 的组合表示二进制的“1”,108ms 宽的发射代码由一个引导码(9ms),一个结果码(4.5ms),低8 位地址码(9ms~18ms),高8 位地址码(9ms~18ms),8位数据码(9ms~18ms)和这8 位数据的反码(9ms~18ms)组成。一次有效的下降沿触发后,后面的32位数据码都是通过延时来获取的。
    我怀疑可能是我的PORT0口多次触发中断造成的死机。可能该IO口被posted,然后,在ISR之后,一旦打开中断MASK,posted中断就会pending了,很有可能会再次触发中断。我自己的查找方向,希望没有误导到jxin,呵呵
相关链接:https://bbs.21ic.com/upfiles/img/20097/200972317363949.rar

使用特权

评论回复
9
ni_labview| | 2009-7-24 09:24 | 只看该作者

已经给AE哥哥转达,稍等

使用特权

评论回复
10
jackle_zheng|  楼主 | 2009-7-24 09:31 | 只看该作者

谢谢ni_labview,希望AE哥哥能尽快给个信,呵呵

使用特权

评论回复
11
jackle_zheng|  楼主 | 2009-7-27 11:49 | 只看该作者

知道怎么死的了

  原因:错误的理解了asm的功能, asm("reti");这一句只是把RETI语句插入到当前位置,而没有出栈动作,也就是死在中断里面了,找不到返回点了,查找生成的汇编后,发现的。对照生成的汇编,加上如下语句就好了。
        asm("add SP,-4");
    asm("pop X");
    asm("pop A");
    asm("mov [__r0],A");
    asm("pop A");
        asm("reti");

使用特权

评论回复
12
jxin| | 2009-7-27 13:08 | 只看该作者

恭喜恭喜

使用特权

评论回复
13
jackle_zheng|  楼主 | 2009-7-27 13:36 | 只看该作者

jxin兄弟,还有问题啊,呵呵

我在PORT0_ISR里面读IO状态,这个应该没有问题吧,就向下面语句这样:
  for(j = 0;j<3000;j++)//delay 9ms
  {
   if(P0DATA & 0X20)//if p0.5 turn to high level,return
   {
    key_pressed = 1;
    P05CR |= 0X40;
    asm("add SP,-4");
    asm("pop X");
    asm("pop A");
    asm("mov [__r0],A");
    asm("pop A");
    asm("reti");
   }
  }
   正常情况下,红外接收的引导码在9ms里面,肯定是低电平的,只有干扰脉冲触发中断后,很快的又回到高电平,我测了一下,只有250us左右。
    我正常按遥控器的时候,我在示波器也接到了红外接收管的输出上,看到的波形是正常的,也就是说引导码是9ms的低电平,可是偏偏在上面的那个if语句那里返回了,理论上,这个时候的P05口应该是低电平才对啊。
    我怀疑有干扰,逻辑不匹配,于是禁止P0口中断,在while(1)里面一直把P0.5口的状态读到P0.1口输出,用示波器输出查看波形,波形也是正常的。
    现在比较郁闷了,不知道问题在哪里了!!!!

使用特权

评论回复
14
benedy| | 2009-7-27 17:04 | 只看该作者

有点乱

你说的有点乱,既然是低电平,返回就没有错啊!

使用特权

评论回复
15
benedy| | 2009-7-27 17:05 | 只看该作者

回复

是不是应当加一个上拉电阻呢?

使用特权

评论回复
16
jackle_zheng|  楼主 | 2009-7-27 17:38 | 只看该作者

To benedy兄弟

    我整理一下,我的意思是说,如果没有干扰的话,正常触发的话,下降沿之后应该有9ms的低电平,如果有干扰的话,由于干扰的低电平比较窄,在9ms的时间内,必然会返回到高电平,那么,在9ms内如果检测到高电平就判断为干扰脉冲,直接返回if(P0DATA & 0X20)//if p0.5 turn to high level,return
    你说的加上拉电阻是指在红外接收头输出端加上拉电阻吗?在红外接收头输出端我加了2K的上拉电阻。
    理论上,在ISR里面读IO状态应该没有问题吧

使用特权

评论回复
17
Apnote| | 2009-7-29 15:47 | 只看该作者

楼主,问题有点乱...

楼主,问题有点乱。
理一下头绪:
1.如果没有干扰的话,正常触发的话,下降沿之后应该有9ms的低电平;
2.如果有干扰的话,由于干扰的原因,低电平比较窄(在小于9ms的时间内)必然会返回到高电平。
3.正常按遥控器的时候,波形测出来是正常的9ms的低电平,但是在9ms时间内
程序却跑到了if(P0DATA & 0X20)//if p0.5 turn to high level,return,
也就是P05在9ms时间内跳到高电平return。
4.怀疑P0口中断影响。禁止P0口中断,在while(1)里面一直把P0.5口的状态读到P0.1口输出,波形也是正常的。

呵呵,不知道是不是这样的说法...

使用特权

评论回复
18
jackle_zheng|  楼主 | 2009-7-29 16:33 | 只看该作者

呵呵,总算有兄弟关注了

   Apnote兄弟,是这样的:我把问题发上来之后,自己也是一刻不停的查找问题,所以,会有点乱,呵呵。
   你的理解是对的。正常操作遥控器的时候,9ms引导码之内不可能有高电平的,但是程序确实是从if(P0DATA & 0X20)那里跑掉了(我设置了标志位,触发后外接的LED会闪),我的查找过程是这样的:
1.用示波器查看红外接收头输出的波形是不是对的,验证的结果是正常的。说明,信号进入P0口之前是正常的。
2.禁止P0口中断,在main函数里面把P0.5的状态赋给P0.1口输出,示波器查看的结果也是没有问题的。说明,信号进入P0.5口后的逻辑也是对的。
附if(P0DATA & 0X20)的汇编代码:
mov A,REG[0]
mov [_ro],A
tst [_r0],32
jz L16

    今天下午,我换了个写法,貌似解决了这个问题。我先PORT0_TEMP = P0DATA & 0X02;然后,在条件判断的时候,采用if(PORT0_TEMP)的形式。
相应的汇编也附上:
;PORT0_TEMP = P0DATA & 0X02;
  mov A,REG[0]
  and A,2
  mov [X+2],A
  ....
;if(PORT0_TEMP)
  cmp [X+2],0
  jz L7
    虽然说,算是解决了这个问题,仍然不知道为什么,在C51里面,if(P0DATA & 0X20)这么写也没有问题啊,很是奇怪!!!!!!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

17

帖子

0

粉丝