Nios中PIO的INT

初涉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

 1 #ifndef SOPC_H_
 2 #define SOPC_H_
 3 
 4 #include "system.h"
 5 
 6 #define _LED
 7 #define _KEY
 8 
 9 
10 typedef struct
11 {
12     unsigned long int DATA;
13     unsigned long int DIRECTION;        // 0-> input; 1->output
14     unsigned long int INTERRUPT_MASK;   // 1-> enable the INT
15     unsigned long int EDGE_CAPTURE;
16 }PIO_STR;
17 
18 #ifdef _LED
19 #define LED ((PIO_STR*)PIO_LED_BASE)
20 #endif
21 
22 #ifdef _KEY
23 #define KEY ((PIO_STR*)PIO_KEY_BASE)
24 #endif
25 
26 #endif /*SOPC_H_*/

main.c

 1 /********************************************************************
 2  * enable bit cleaning for PIO-key-INT
 3  * 
 4  * when any of the 4 key is down,interrupt will occured,and check the
 5  * edge-capture-register to determine which key is down
 6  * 
 7  * during INT register initial, bit clean should be done once.
 8  * During ISR,bit clean should NOT be done(Line 48);INT disable/enable is useless(Line 41/72).
 9  * 
10  * 
11  * 2012-4-16 Lefroy Guo
12  * 
13 ********************************************************************/
14 
15 #include <stdio.h>
16 #include "../inc/sopc.h"
17 #include <system.h>
18 #include <unistd.h>
19 
20 //*******************************************************************
21 
22 
23 //  comment this line because there is no need to store key pressed imformation
24 //unsigned int key_flag = 0x0;       // 4bit for 4 key. 0->UP, 1->DOWN
25 
26 void blink(unsigned int times)
27 {
28     unsigned int i;
29     for(i=0;i<times;i++)
30     {
31         LED->DATA = 0xf;
32         usleep(50000);
33         LED->DATA = 0x0;
34         usleep(50000);
35     }
36 }
37 
38 void ISR_KEY(void *context,unsigned long id)
39 {
40     unsigned int i;
41     KEY->INTERRUPT_MASK = 0x0;        // disable INT
42     usleep(20000);                    // delay 20ms
43     for(i=0;i<4;i++)
44     {
45         if(((KEY->EDGE_CAPTURE>>(3-i))&1) == 1)
46         {
47             // (3-i)bit of key 's INT is occur,without knowing posedge or negedge!
48 //            KEY->EDGE_CAPTURE |= 1<<(3-i);       // Should NOT be done          
49             if(((KEY->DATA>>(3-i))&1) == 0)
50             {
51                 // (3-i)bit of key is down
52 //                ((key_flag>>(3-i))&1) |= 1;
53                 // mark key_flag (3-i) bit to 1, meaning this bit(3-i) of key is down
54                 LED->DATA |= 1<<(3-i);
55                 // set corresponding bit of led to high
56             }
57             else
58             {
59                 // (3-i)bit of key is down
60 //                ((key_flag>>(3-i))&1) &= 0;
61                 // mark key_flag (3-i) bit to 0, meaning this bit(3-i) of key is up
62                 LED->DATA &= ~(1<<(3-i));
63                 // set corresponding bit of led to low
64             }
65         }
66 //      else
67 //      {
68 //          // (3-i)bit of key 's INT is NOT occur, nothing happend to this bit key
69 //      }
70         
71     }
72     KEY->INTERRUPT_MASK = 0xF;        // enable INT
73 }
74 
75 int init_KEY(void)                    // Declaration the KEY_INT's ISR
76 {
77     KEY->INTERRUPT_MASK = 0xF;        // enable INT
78     KEY->EDGE_CAPTURE = 0xF;          // clear all pending bit
79     return alt_irq_register(PIO_KEY_IRQ,NULL,ISR_KEY);
80 }
81 
82 void main()
83 {
84     printf("*************************************************\n");
85     blink(3);
86     init_KEY();
87     usleep(1000000);
88     blink(3);
89     
90     while(1);
91     reture(0);
92 }

结论: INT初始化中,必须要先enable了再clear一下,否则挂掉!个人感觉这点最关键了,以前做ARM也是这样(都是RISC还挺像的);
    ISR里,不用clear,进去时先disable了,出来时再enable了(这点貌似没区别,但养成这习惯了,呵呵)。如果clear了,中断响应有问题!

posted @ 2012-04-16 23:03  公孙策  阅读(275)  评论(0编辑  收藏  举报