您的位置:首页 > 移动开发 > IOS开发

Nios中PIO的INT

2012-04-16 23:03 134 查看
初涉nios中的INT,开始做的时候中断虽然正常的产生了,但是debug发现初始化木有成功的返回值,main函数中代码:

if(!init_KEY1())
{
printf("interupt register successfully!\n");
}
else
{
printf("Error: interupt register failed!\n");
}

while(1);


中断能正常产生,这说明初始化一定好了。但是那两个printf都木有打出来,还为这个苦恼了一会儿。咱不能光初始化了以后啥事儿都跑到ISR里做吧,嗯!问题一定得解决的。

后来看到了http://www.cnblogs.com/crazybingo/archive/2011/04/03/2004477.html#2356430这篇文章,真是一下点醒了我,以前做ARM时,记得在有INT初始化时,一定要clear pending bit的,否则直接挂掉了(ARM中进入ISR也要有这步的)。

最后问题解决了,写点东西,做个备份吧,如果还能帮上别人,那更好了。如果有异议,希望大家指教。

做的是4bit PIO接4个按键,任何一个按下都会有独立的LED响应(4个LED也用4bit的PIO接的)。4个键不能冲突,没有中断嵌套。贴上源码:

SOPC.h

#ifndef SOPC_H_
#define SOPC_H_

#include "system.h"

#define _LED
#define _KEY

typedef struct
{
unsigned long int DATA;
unsigned long int DIRECTION;        // 0-> input; 1->output
unsigned long int INTERRUPT_MASK;   // 1-> enable the INT
unsigned long int EDGE_CAPTURE;
}PIO_STR;

#ifdef _LED
#define LED ((PIO_STR*)PIO_LED_BASE)
#endif

#ifdef _KEY
#define KEY ((PIO_STR*)PIO_KEY_BASE)
#endif

#endif /*SOPC_H_*/


main.c

/********************************************************************
* enable bit cleaning for PIO-key-INT
*
* when any of the 4 key is down,interrupt will occured,and check the
* edge-capture-register to determine which key is down
*
* during INT register initial, bit clean should be done once.
* During ISR,bit clean should NOT be done(Line 48);INT disable/enable is useless(Line 41/72).
*
*
* 2012-4-16 Lefroy Guo
*
********************************************************************/

#include <stdio.h>
#include "../inc/sopc.h"
#include <system.h>
#include <unistd.h>

//*******************************************************************

//  comment this line because there is no need to store key pressed imformation
//unsigned int key_flag = 0x0;       // 4bit for 4 key. 0->UP, 1->DOWN

void blink(unsigned int times)
{
unsigned int i;
for(i=0;i<times;i++)
{
LED->DATA = 0xf;
usleep(50000);
LED->DATA = 0x0;
usleep(50000);
}
}

void ISR_KEY(void *context,unsigned long id)
{
unsigned int i;
KEY->INTERRUPT_MASK = 0x0;        // disable INT
usleep(20000);                    // delay 20ms
for(i=0;i<4;i++)
{
if(((KEY->EDGE_CAPTURE>>(3-i))&1) == 1)
{
// (3-i)bit of key 's INT is occur,without knowing posedge or negedge!
//            KEY->EDGE_CAPTURE |= 1<<(3-i);       // Should NOT be done
if(((KEY->DATA>>(3-i))&1) == 0)
{
// (3-i)bit of key is down
//                ((key_flag>>(3-i))&1) |= 1;
// mark key_flag (3-i) bit to 1, meaning this bit(3-i) of key is down
LED->DATA |= 1<<(3-i);
// set corresponding bit of led to high
}
else
{
// (3-i)bit of key is down
//                ((key_flag>>(3-i))&1) &= 0;
// mark key_flag (3-i) bit to 0, meaning this bit(3-i) of key is up
LED->DATA &= ~(1<<(3-i));
// set corresponding bit of led to low
}
}
//      else
//      {
//          // (3-i)bit of key 's INT is NOT occur, nothing happend to this bit key
//      }

}
KEY->INTERRUPT_MASK = 0xF;        // enable INT
}

int init_KEY(void)                    // Declaration the KEY_INT's ISR
{
KEY->INTERRUPT_MASK = 0xF;        // enable INT
KEY->EDGE_CAPTURE = 0xF;          // clear all pending bit
return alt_irq_register(PIO_KEY_IRQ,NULL,ISR_KEY);
}

void main()
{
printf("*************************************************\n");
blink(3);
init_KEY();
usleep(1000000);
blink(3);

while(1);
reture(0);
}


结论: INT初始化中,必须要先enable了再clear一下,否则挂掉!个人感觉这点最关键了,以前做ARM也是这样(都是RISC还挺像的);
    ISR里,不用clear,进去时先disable了,出来时再enable了(这点貌似没区别,但养成这习惯了,呵呵)。如果clear了,中断响应有问题!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: