|
|
View previous topic :: View next topic |
Author |
Message |
mdemuth
Joined: 16 Apr 2007 Posts: 71 Location: Stuttgart, Germany
|
INT_RB is not working with 18f45k22(solved) |
Posted: Wed Mar 23, 2011 11:31 am |
|
|
Hello there,
I am trying to force an IRQ on pin change on port b.
Code: |
// CCS Compiler Version: 4.119
#include <18f45k22.h> //
#device ADC=10 //
#fuses INTRC_IO,NOWDT,NOPROTECT,BROWNOUT,PUT,MCLR, BORV27
#use delay(clock=64000000)
#use fast_io(b)
// Schaltausgänge
#define LED_GN PIN_B1
#define LED_RT PIN_B0
// Encoder
#define X_SPUR_A PIN_B4
#define X_SPUR_B PIN_B5
#define Y_SPUR_A PIN_B6
#define Y_SPUR_B PIN_B7
// LCD
#define LCD_DATA_PORT getenv("SFR:PORTD")
#define LCD_ENABLE_PIN PIN_E0 ////
#define LCD_RS_PIN PIN_E1 ////
#define LCD_RW_PIN PIN_E2 ////
#define LCD_DATA4 PIN_D4 ////
#define LCD_DATA5 PIN_D5 ////
#define LCD_DATA6 PIN_D6 ////
#define LCD_DATA7 PIN_D7
#include "lcd.c"
int8 i=0;
int8 j=0; // Schleifenzähler
int8 x_new, y_new;
signed int16 x_wert=0;
signed int16 y_wert=0;
#include <Encoder Anzeige.h>
#zero_ram
void main()
{
setup_oscillator (OSC_64MHZ);
SETUP_ADC_PORTS(sAN0 | sAN1 | sAN2 | sAN3);
SETUP_ADC(ADC_CLOCK_INTERNAL);
SETUP_DAC(DAC_OFF);
setup_comparator(nc_nc_nc_nc);
SETUP_WDT(WDT_OFF); //WDT
RESTART_WDT(); // Initialisierung
set_tris_b (0xf0);
port_b_pullups(TRUE);
lcd_init();
i=input_b();
delay_us(10); //ensure line has time to settle
clear_interrupt(INT_RB);
delay_us(10); //ensure line has time to settle
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
while(1)
{
if (input(X_SPUR_A)) x_wert++; // HW works fine, I can read this input
if (!input(X_SPUR_B)) y_wert++; // HW works fine, I can read thsi input
lcd_gotoxy(1, 1);
printf(lcd_putc, "X=%05ld",x_wert);
lcd_gotoxy(1, 2);
printf(lcd_putc, "Y=%05ld",y_wert);
if (bit_test(i,0))
{
output_low(LED_RT);
output_high(LED_GN);
}
else
{
output_low(LED_GN);
output_high(LED_RT);
}
delay_ms(10);
} // Ende while 1
} // Ende main
#INT_RB
void IRQ_XY()
{
j=input_b(); // to clear the IRQ
i++; // i remains 0
lcd_gotoxy(12, 1);
printf(lcd_putc, "%03u",i);
}
|
No success so far, what is wrong?
Thanks in advance!
Michael
Last edited by mdemuth on Mon Mar 28, 2011 3:27 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 23, 2011 12:33 pm |
|
|
Make a much more simple test program. Remove all the ADC code,
and the WDT code, and remove all the code in the while() loop.
Just test only the #int_rb problem. If you make a small program
and it still doesn't work, then I'll look at it.
Also, describe the input signal that is supposed to cause the #int_rb
interrupt. What are the voltage levels of this signal (high and low levels) ?
What is the Vdd voltage of the PIC ?
Here is a small test program for #int_rb on pin B7 only:
http://www.ccsinfo.com/forum/viewtopic.php?t=41951&start=1
Possible compiler bugs that could cause the problem, with fixes:
http://www.ccsinfo.com/forum/viewtopic.php?t=40980 |
|
|
mdemuth
Joined: 16 Apr 2007 Posts: 71 Location: Stuttgart, Germany
|
|
Posted: Thu Mar 24, 2011 2:18 am |
|
|
Hi PCM programmer,
I made a very simple program:
Code: |
//// CCS Compiler Version: 4.119
#include <18f45k22.h> //
#device ADC=10 //
#fuses INTRC_IO,NOWDT,NOPROTECT,BROWNOUT,PUT,MCLR, BORV27
#use delay(clock=64000000)
#use fast_io(b)
#define LED_RT PIN_B0
#define X_SPUR_A PIN_B4
#byte IOCB = 0xF7D
#byte ANSEL = 0xF7E
#byte ANSELH = 0xF7F
int8 j=0;
void flash_led() // flashes LEDs
{
for (j=0; j<10;j++)
{
output_toggle(LED_RT);
delay_ms(100);
}
}
#zero_ram
void main()
{
setup_oscillator (OSC_64MHZ);
setup_comparator(nc_nc_nc_nc);
SETUP_WDT(WDT_OFF); //WDT
IOCB = 0xF0;
ANSEL = 0;
ANSELH = 0;
set_tris_b (0xf0);
port_b_pullups(TRUE);
j=input_b(); // read the inputs and clear the IRQ
clear_interrupt(INT_RB);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
// flash once to check this subroutine
flash_led();
// works fine => LED flashes
while(1)
{
if (input(X_SPUR_A)) output_low(LED_RT);
else output_high(LED_RT);
delay_ms(100);
// LED has same state as input => HW is OK
} // Ende while 1
} // Ende main
#INT_RB
void IRQ_XY()
{
j=input_b(); // to clear the IRQ
flash_led(); // IRQ should force flashing, but does not!
}
|
VDD=5V Input is a simple switch.
#INT_RB is never called.
More assistance needed.....
Michael |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 24, 2011 3:11 pm |
|
|
I modified the program and now it works. The LED flashes when the
program starts. Then when you push a button on pin B4, the LED will
flash again. The main problem is that in vs. 4.119, the IOCB register
address is incorrect.
Code: |
#include <18F45k22.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,BROWNOUT,PUT,MCLR, BORV27,NOPBADEN
#use delay(clock=4000000)
#define LED_RT PIN_B0
#define X_SPUR_A PIN_B4
void setup_IOCB(int8 mask)
{
#byte IOCB = 0xF62 // Register address for 18F45K22
IOCB = mask;
}
//----------------------------
void flash_led(void)
{
int8 j=0;
for(j=0; j<10;j++)
{
output_toggle(LED_RT);
delay_ms(100);
}
}
//------------------------------
#int_rb
void IRQ_XY(void)
{
int temp;
flash_led();
temp = input(PIN_B4); // To clear mismatch condition
}
//============================================
void main()
{
int temp;
output_low(LED_RT); // LED is initially Off
port_b_pullups(0x10); // Enable pull-up on pin B4 only
temp = input(PIN_B4); // Read Pin B4 to clear mismatch condition
clear_interrupt(INT_RB);
enable_interrupts(INT_RB4); // Enable int-on-change for pin B4 only
setup_IOCB(0x10); // *** Fixes bug with ASM code for line above
enable_interrupts(GLOBAL);
flash_led();
while(1);
} |
|
|
|
mdemuth
Joined: 16 Apr 2007 Posts: 71 Location: Stuttgart, Germany
|
|
Posted: Mon Mar 28, 2011 3:26 am |
|
|
This looks much better => solved!
Thanks! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|