Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] how to use IOC1 and IOC2 on pic18f24k50

Status
Not open for further replies.

cllunlu

Member level 4
Joined
Nov 21, 2006
Messages
76
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,900
Hi everyone,

I wanna use interrupt on change IOCC1 and IOCC2 pins to read button. These pins are logically high, when button is pressed, it will be logically low and interrupt routine will run. But my code that is below doesnt work. Program doesnt run Interrupt routine any time.

Where is my mistake. Can you help me?


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
sbit SW1 at RC1_bit;
sbit SW2 at RC2_bit;
 
sbit SW1_Direction at TRISC1_bit;
sbit SW2_Direction at TRISC2_bit;
 
sbit LED0 at LATA0_bit;
sbit LED1 at LATA1_bit;
sbit LED2 at LATA2_bit;
 
sbit BUZZER at LATB3_bit;
 
sbit LED0_Direction at TRISA0_bit;
sbit LED1_Direction at TRISA1_bit;
sbit LED2_Direction at TRISA2_bit;
sbit BUZZER_Direction at TRISB3_bit;
 
#define INPUT 1
#define OUTPUT 0
 
#define LOW 0
#define HIGH 1
 
void init()
{
     CM1CON0 = 0x00;
     CM2CON0 = 0x00;
 
     ANSELA = 0x00;
     ANSELB = 0x00;
     ANSELC = 0x00;
 
     TRISA = 0xC0;
     TRISB = 0x00;
     TRISC = 0x00;
 
     PORTA = 0x00;
     PORTB = 0x00;
     PORTC = 0x00;
 
     LATA = 0x00;
     LATB = 0x00;
     LATC = 0x00;
 
     SW1_Direction = INPUT;
     SW2_Direction = INPUT;
 
     C1ON_bit = 0;
     C2ON_bit = 0;
 
     IOCC = 6;              // set RC1 and RC2 interrupt on change to ON
     INTCON.RCIF = 0;     // Clear interrupt flag prior to enable
     INTCON.RCIE = 1;     // enable on change interrupts
     INTCON.GIE  = 1;     // enable Global interrupts
 
     LED1_Direction = OUTPUT;
     LED2_Direction = OUTPUT;
     BUZZER_Direction=OUTPUT;
 
     UART1_Init(9600);
}
 
void interrupt(void)
{
     //BUZZER=HIGH;
     if (RCIF_bit == 1)
     {
          RCIE_bit=0;
          GIE_bit=0;
          
          if(SW1==0)
              LED1=~LED1;
          if(SW2==0)
              LED2=~LED2;
              
           INTCON.RCIF = 0;     // Clear interrupt flag prior to enable
           INTCON.RCIE = 1;     // enable on change interrupts
           INTCON.GIE  = 1;     // enable Global interrupt
     }
}
 
void main() {
 
     init();
     Delay_ms(50);
     
     LED1 = LOW;
     LED2 = LOW;
 
     LED0=HIGH;
     BUZZER=HIGH;
     Delay_ms(1500);
     BUZZER=LOW;
     while(1) 
     {
           LED0=~LED0;
           Delay_ms(700);
     }
}

 
Last edited by a moderator:

hello,

mistake with flag name..
RCIF,RCIE used for UART interrupt ?
 

RCIE and RCIF are for serial receive interrupt. RBIE and RBIF are for PORTB interrupt on change (RB4 - RB7). IOCx are different. I will soon post a code for you.

- - - Updated - - -

Try this code.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
sbit SW1 at RC1_bit;
sbit SW2 at RC2_bit;
 
sbit SW1_Direction at TRISC1_bit;
sbit SW2_Direction at TRISC2_bit;
 
sbit LED0 at LATA0_bit;
sbit LED1 at LATA1_bit;
sbit LED2 at LATA2_bit;
 
sbit BUZZER at LATB3_bit;
 
sbit LED0_Direction at TRISA0_bit;
sbit LED1_Direction at TRISA1_bit;
sbit LED2_Direction at TRISA2_bit;
 
sbit BUZZER_Direction at TRISB3_bit;
 
#define INPUT 1
#define OUTPUT 0
 
#define LOW 0
#define HIGH 1
 
#define ON 1
#define OFF 0
 
void interrupt(void) {
 
    if(IOCIF_bit) {
          IOCIF_bit = 0;
    
          if(IOCC1_bit) {
                IOCC1_bit = 0;        
                LED1 = ~LED1;
          }
          
          if(IOCC2_bit) {
                IOCC2_bit = 0;        
                LED2 = ~LED2;
          }   
    }
}
 
void main() {
 
    CM1CON0 = 0x00;
    CM2CON0 = 0x00;
    
    ANSELA = 0x00;
    ANSELB = 0x00;
    ANSELC = 0x00;
    
    TRISA = 0xC0;
    TRISB = 0x00;
    TRISC = 0x00;
    
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
    
    SW1_Direction = INPUT;
    SW2_Direction = INPUT;
    
    LED0_Direction = OUTPUT;
    LED1_Direction = OUTPUT;
    LED2_Direction = OUTPUT;
 
    BUZZER_Direction = OUTPUT;
    
    LED0 = OFF;
    LED1 = OFF;
    LED2 = OFF;
    
    BUZZER = OFF;
    
    Delay_ms(200);
    
    IOCIE_bit = 1;
    PEIE_bit = 1;
    GIE_bit = 1;
    
    IOCIF_bit = 0;
 
    LED0 = ON;
    BUZZER = ON;
    Delay_ms(1500);
    BUZZER = OFF;
 
    while(1) {
    
           LED0 = ~LED0;
           Delay_ms(1000);
    }
}

 

Attachments

  • Buttons (IOCx) and LEDs.rar
    29.7 KB · Views: 117
Last edited:

Thanks for your helping. I have tried your code. But When I pressed button, it doesnt run on interrupt routine. Another mistake?
 

I don't have that PIC to test. I will check the datasheet again and see if I have to do some other thing to make it work.
 

how we set falling edge or rising edge for interrupt?
 

Falling edge and rising edge is only for INTzx pin I think. I think interrupt is working but there is problem in my code. It is detecting both button press and release and toggling the LED so fast that it turns ON and then OFF. Please press and hold the button for a second or two and see if LED turns ON.

- - - Updated - - -

Try this code in hardware and reply.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
sbit SW1 at RC1_bit;
sbit SW2 at RC2_bit;
 
sbit SW1_Direction at TRISC1_bit;
sbit SW2_Direction at TRISC2_bit;
 
sbit LED0 at LATA0_bit;
sbit LED1 at LATA1_bit;
sbit LED2 at LATA2_bit;
 
sbit BUZZER at LATB3_bit;
 
sbit LED0_Direction at TRISA0_bit;
sbit LED1_Direction at TRISA1_bit;
sbit LED2_Direction at TRISA2_bit;
 
sbit BUZZER_Direction at TRISB3_bit;
 
#define INPUT 1
#define OUTPUT 0
 
#define LOW 0
#define HIGH 1
 
#define ON 1
#define OFF 0
 
void interrupt(void) {
 
    if(IOCIF_bit) {
          IOCIF_bit = 0;
    
          if(!RC1_bit) {                      
                LED1 = ~LED1;
          }
          
          if(!RC2_bit) {                    
                LED2 = ~LED2;
          }   
    }
}
 
void main() {
 
    CM1CON0 = 0x00;
    CM2CON0 = 0x00;
    
    ANSELA = 0x00;
    ANSELB = 0x00;
    ANSELC = 0x00;
    
    TRISA = 0xC0;
    TRISB = 0x00;
    TRISC = 0x00;
    
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
    
    SW1_Direction = INPUT;
    SW2_Direction = INPUT;
    
    LED0_Direction = OUTPUT;
    LED1_Direction = OUTPUT;
    LED2_Direction = OUTPUT;
 
    BUZZER_Direction = OUTPUT;
    
    LED0 = OFF;
    LED1 = OFF;
    LED2 = OFF;
    
    BUZZER = OFF;
    
    Delay_ms(200);
    
    IOCIE_bit = 1;
    PEIE_bit = 1;
    GIE_bit = 1;
    IOCC1_bit = 1;
    IOCC2_bit = 1;
    
    IOCIF_bit = 0;
 
    LED0 = ON;
    BUZZER = ON;
    Delay_ms(1500);
    BUZZER = OFF;
 
    while(1) {
    
           LED0 = ~LED0;
           Delay_ms(1000);
    }
}

 

Thanks milan.rajnik.
Your last code work.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top