View previous topic :: View next topic |
Author |
Message |
LJBass
Joined: 12 Sep 2006 Posts: 5
|
int_ra problem |
Posted: Tue Dec 05, 2006 8:10 am |
|
|
Hi,
I'm want to use the port a onchange interupt from the 16F785 microcontroller, but it just aint working.
I connected 2 switches to the RA0 and RA5 pin. I also connected 3 leds to RC0, RC1 and RC2.
I wrote the following code:
Code: |
#include <16F785.h>
#fuses INTRC_IO,PUT,NOWDT,NOPROTECT
#use delay(clock=8000000)
#int_ra
void ra_isr() {
int8 c;
c = input_a();
if(c > 0)
output_c(0xFF);
else
output_c(0x00);
}
void main() {
set_tris_c(0x00);
set_tris_a(0xFF);
enable_interrupts(INT_RA);
enable_interrupts(GLOBAL);
output_c(0xFF);
while (TRUE) {
// Do something
}
}
|
When powering op the microcontroller only the leds will go on. Changing the state of the switches doesn't have any effect at all.
What could be the problem?
Thanks in advance,
LJBass |
|
|
picprogrammer
Joined: 10 Sep 2003 Posts: 35
|
|
Posted: Tue Dec 05, 2006 8:56 am |
|
|
You read the a-port instead of the serial character.
c = input_a(); has to be: c = getc(); |
|
|
LJBass
Joined: 12 Sep 2006 Posts: 5
|
|
Posted: Tue Dec 05, 2006 9:26 am |
|
|
Hi,
Thanks for your reply. I tried it but no change, still the same problem.
I just want to use the a inputs not a rs232 connection.
I thought getc() was only used for rs232.
some extra info: I'm using compiler version 3.223 |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Tue Dec 05, 2006 10:35 am |
|
|
If you look at the data sheet you will see the pins you need are used for multiple functions (which is usually true for most Microchip devices).
You have to use setup_comparator() option to disable the comparator input on A0 and then disable the OSC input on A5 using the fuses before you can use these pins for digital inputs.
BTW, You are correct that getc() is for RS232 and the input_a() is meant for digital inputs as you first used it.. When you get the Port A pins set to digital be sure to take into account the open pins you are not using on Port A. Those will affect the operation of your code as it is written. You might want to test individual pins rather than the entire port. |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Tue Dec 05, 2006 11:35 am |
|
|
If you are reading the port use input_a() not getc()
since you are using an interrupt on port change service routine
Note
getc is for reading from a rs232 pin with an interrupt from the USART upon receipt of a character service routine. |
|
|
LJBass
Joined: 12 Sep 2006 Posts: 5
|
|
Posted: Tue Dec 12, 2006 9:26 am |
|
|
I'm still having problems. I changed my code. Changing the state off the switches does help, port c stay's hi. It just doesn't call the interupt.
Code: |
#include <16F785.h>
#fuses INTRC_IO,PUT,NOWDT,NOPROTECT
#use delay(clock=8000000)
void main() {
int tmp;
setup_oscillator(OSC_8MHZ | OSC_INTRC);
SETUP_ADC(ADC_OFF);
SETUP_ADC_PORTS(NO_ANALOGS);
clear_interrupt(INT_RA);
enable_interrupts(INT_RA);
enable_interrupts(GLOBAL);
set_tris_a(0xFF);
set_tris_c(0x00);
output_c(0xFF);
while(1) {
tmp++;
if(tmp==254)
tmp = 0;
}
}
#int_ra
void ioc_isr(void)
{
int8 c;
c = input_a();
output_c(0x00);
}
|
Any suggestions?
Thanks in advance,
LJBass |
|
|
Ttelmah Guest
|
|
Posted: Tue Dec 12, 2006 9:50 am |
|
|
Multiple parts:
First, how are the 'switches' connected?. You need something like a pull up resistor, and a switch to ground, or a changeover switch to actually get the pin to change.
Second though, is that the F875, is different from just about any other PIC, in how the interrupt on change is enabled/works. On most pics, simply enabling the interrupt is all that is needed, and it then affects a large lump of the port. However the 875, allows the interrupt to also be enabled/disabled on a 'per pin' basis. The default for the register controlling this, has all the pins disabled on boot. You then need:
Code: |
#byte IOCA=0x96
//Then somewhere in your code, to enable pins 0, and 5:
IOCA=0x21;
|
Best Wishes |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Dec 12, 2006 10:59 am |
|
|
As an alternative to Ttelmah's solution:
On other chips like the PIC16F684 you can enable the individual 'on change' interrupts by using code like: Code: | enable_interrupts(INT_RA4);
// or for multiple ports:
enable_interrupts(INT_RA0 | INT_RA2 | INT_RA3);
clear_interrupt(INT_RA);
enable_interrupts(GLOBAL); |
Problem is that in v3.249 this is not functioning. If you have PCWH you can use chipedit.exe to make it work:
- Copy the defines for INT_RA0, INT_RA1, etc. from pic16f684.h to pic16f785.h
- Use chipedit.exe to modify the configuration of the pic16f785. Under 'Other Features' change the 'IOC/WPU' setting from 'None' to 'Normal'.
Or ask CCS for an updated devices.dat file. |
|
|
|