|
|
View previous topic :: View next topic |
Author |
Message |
ljmnunes
Joined: 02 Sep 2004 Posts: 13 Location: Brazil
|
#INT_EXT and #INT_RDA problem |
Posted: Sat Aug 01, 2009 8:54 am |
|
|
Hello!
Please, help me!
I write a code to read weigand card reader with almost 1900 lines long for the PIC 16F877A and it works fine. The PIC receive and transmit data over rs485 network using #INT_RDA and read the data weigand from PORT B using #INT_EXT. There are a hardware support for the external interrupt, of course...
My problem started when I moved to PIC18F452 because there are no more room to new code and I include a ps2 keypad for password.
After porting the code, the #INT_RDA interruption does not work anymore after a #INT_EXT event.
So I reduced the code to a minimum and put a LED to see the interrupts and I'm still blind, I can't see were is the problem. I tried the forum but found no clues to help me.
Here is the reduced code I tested. Oh, yes! It was compiled with V4.088.
Thank you very much!
Laercio.
Code: |
#pragma case // makes compiler case sensitive!!!
#include <18F452.h>
#device *=16
#device ADC=10
#define CRYSTAL 20000000 // Clock
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PROTECT //Code protected from reads
#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT //Brownout reset
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
//-------------------------------------------------------------------------
#define PS2START 0
#define PS2BIT 1
#define PS2PARITY 2
#define PS2STOP 3
#define BPSDEFAULT 38400
#define PS2DATA PIN_D0 // ps2 input
#define ACT PIN_A4 // Heart beat
#define PIN_EN PIN_B1
#define PIN_TX PIN_C6
#define PIN_RX PIN_C7
#include "PIC18F452_registers.h" // Generated by CCS C Compiler
#use delay(clock=CRYSTAL,RESTART_WDT)
#use rs232(BAUD=BPSDEFAULT, ENABLE=PIN_EN, XMIT=PIN_TX, RCV=PIN_RX, BITS=8, PARITY=N, ERRORS) // RS232_ERRORS
#zero_ram
int1 FlagTimKeyb;
int1 TimeOutCard ;
int1 Card_Ready;
int1 PS2DAT;
int8 PortBuf[36];
int8 Bit_Count;
int8 SerBuf[70];
int8 IndRX;
//-------------------------------------------------------------------------
#INT_RDA
void serial_isr(void) // receive data from rs485
{
SerBuf[IndRX++] = getc();
set_timer1(0);
if(IndRX >= sizeof(SerBuf)) IndRX = 0; // Circular buffer
output_low(ACT); // <<<<<<<<<<<< just for test
}
//-------------------------------------------------------------------------
#int_EXT
void EXT_isr(void) // used for capture ps2 and weigand data. The control code is stripped from main()
{
output_high(ACT); // <<<<<<<<<<<< just for test
if(FlagTimKeyb == TRUE){ // ps2 pulse
PS2DAT = input(PS2DATA);
}
else{ // card pulse.
if(Card_Ready == FALSE){
TimeOutCard = 0;
PortBuf[Bit_Count] = ~(input_b() & 0b00111100);
if(Bit_Count-- == 0) Card_Ready = TRUE; // Card complete
}
}
}
//-------------------------------------------------------------------------
void Boot(void)
{
output_float(PIN_B0);
port_b_pullups(TRUE);
delay_us(10);
#use fast_io(C)
set_tris_c(0b10000000);
#use fast_io(B)
set_tris_b(0b11111101);
#use fast_io(D)
set_tris_d(0b11111111);
output_c(0b11000111);
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
setup_spi(FALSE);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DIV_BY_16, 0, 1);
enable_interrupts(INT_RDA);
enable_interrupts(INT_EXT);
ext_int_edge( H_TO_L );
enable_interrupts(GLOBAL);
}
//-------------------------------------------------------------------------
void main(void)
{
Boot(); // Hardware config
// Inicializa(); //Select 26 or 36 bit card
// HoldReg[0] = 0b00000000000000000;
// Mudou = TRUE;
set_timer2(0);
for(;;); // Forever (do nothing)
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Aug 01, 2009 11:28 am |
|
|
1. You're using #fast_io statements after the isr routines, which means
they are operating under Standard i/o mode. Which means, input_b()
changes the TRISB to all inputs, upon the first #int_ext interrupt. It then
stays that way for the remaining execution time of the program.
My suggestion is, don't use #fast_io unless you know that you need it,
and if you do, then put the #fast_io statements above all code.
2. Bit_Count is never initialized, and it's never re-initialized at any time.
Therefore, it probably starts at 0x00, just due to the way RAM comes up
from power-on reset, but there's no guarantee of that. In the first pass
through the #int_ext isr, Bit_Count is decremented. It's now likely equal
to 0xFF. On the next #int_ext interrupt, it's going to write beyond the
bounds of PortBuf[], and possibly crash your program. |
|
|
ljmnunes
Joined: 02 Sep 2004 Posts: 13 Location: Brazil
|
|
Posted: Sat Aug 01, 2009 1:48 pm |
|
|
Quote: |
1. You're using #fast_io statements after the isr routines, which means
they are operating under Standard i/o mode. Which means, input_b()
changes the TRISB to all inputs, upon the first #int_ext interrupt. It then
stays that way for the remaining execution time of the program.
My suggestion is, don't use #fast_io unless you know that you need it,
and if you do, then put the #fast_io statements above all code.
|
Incredible! I never thought about the statement's code position! I have made many programs and so far I do not worried about it because always worked fine. Well... I'm still learning...
I put #fixed_io statement in the begin and this solved the problem with the code above, but my final code still have a trouble that I'm searching... The #INT_RDA don't work anymore... #INT_EXT aways works fine.
Quote: |
2. Bit_Count is never initialized, and it's never re-initialized at any time.
Therefore, it probably starts at 0x00, just due to the way RAM comes up
from power-on reset, but there's no guarantee of that. In the first pass
through the #int_ext isr, Bit_Count is decremented. It's now likely equal
to 0xFF. On the next #int_ext interrupt, it's going to write beyond the
bounds of PortBuf[], and possibly crash your program. |
Sorry, my mistake. You're right. In the final code that variable is initialized.
PCM programmer, thanks for your fast help. I am returning to the hunt. I will cook some codes and I hope you find the problem. I keep the post updated.
[]s
Last edited by ljmnunes on Sat Aug 01, 2009 2:02 pm; edited 1 time in total |
|
|
Ttelmah Guest
|
|
Posted: Sat Aug 01, 2009 1:59 pm |
|
|
The reason INT_RDA doesn't work, is your TRIS is wrong.
On the 18F452 chips, both serial pins, must be set as _outputs_, On the older 16 chips, the serial input had to be set as an input.
Check the data sheet.
This is the caveat of going DIY on TRIS.
Best Wishes |
|
|
ljmnunes
Joined: 02 Sep 2004 Posts: 13 Location: Brazil
|
|
Posted: Sat Aug 01, 2009 6:03 pm |
|
|
Thanks again!
The problem was solved.
I checked the final code and it works fine now, just like the test code above.
Best Regards.
Laercio
Off topic:
For Brazilian readers, know about our volunteer work and publish it. If you want to help us, please contact us:
http://magicossolidarios.org and http://magim.org (Webpages in portuguese only, sorry.)
Thanks
Laercio |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Sun Aug 02, 2009 1:55 pm |
|
|
Quote: | The reason INT_RDA doesn't work, is your TRIS is wrong.
On the 18F452 chips, both serial pins, must be set as _outputs_, On the older 16 chips, the serial input had to be set as an input.
Check the data sheet.
This is the caveat of going DIY on TRIS. |
This cleared up something i had been seeing and didn't know why it worked like that.
You get a free two for one. |
|
|
Ttelmah Guest
|
|
Posted: Sun Aug 02, 2009 1:59 pm |
|
|
I met this right in the early days of the 18F chips. For me, it was worse, since I had the then 'brand new' hardware 18F ICE, and this needed the TRIS set like a 16 chip, while the real chips followed the published data sheet.,
This was designed to really annoy!....
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 02, 2009 2:52 pm |
|
|
But the 18F452 data sheet says pin C6 is an output and pin C7 is an input:
http://ww1.microchip.com/downloads/en/DeviceDoc/39564c.pdf
Quote: |
16.0 ADDRESSABLE UNIVERSAL SYNCHRONOUS
ASYNCHRONOUS RECEIVER TRANSMITTER (USART)
In order to configure pins RC6/TX/CK and RC7/RX/DT
as the Universal Synchronous Asynchronous Receiver
Transmitter:
• bit SPEN (RCSTA<7>) must be set (= 1),
• bit TRISC<6> must be cleared (= 0), and
• bit TRISC<7> must be set (=1).
|
|
|
|
Ttelmah Guest
|
|
Posted: Mon Aug 03, 2009 9:52 am |
|
|
Yes.
First apologies. Inputs, not outputs.
I have an email note from Microchip, saying that both serial pins need to be set as inputs for some chips (non specific for date codes....). Odd is that it is not in the errata for the chip.
CCS in their own code set the bits as inputs, as does the data sheet for latter chips like the 4520.
The 'upgrade' notes for the 452, to the 4520, don't mention any changes in the TRIS settings, yet the 4520, requires both bits set as inputs.
I suspect it is one of the 'only affects some chips' problems that sometimes applies with Microchip. If you look at the published diagram for the pin, the circuit _ought_ to overide the output, whichever way TRIS is programmed....
Best Wishes |
|
|
PICman
Joined: 02 Nov 2007 Posts: 26
|
|
Posted: Mon Aug 03, 2009 9:24 pm |
|
|
My question: Is it better to simply NOT to use "fast_io" and simply IGNORE the TRIS commands ?
I've made a LOT of assembler and still have the habit of predefining the TRIState of the PIC's pins before starting the code by itself... Am I better to drop this habit and let the code define the pin's TRIState as the input/output instructions are executed ?
Thanks ! _________________ The ideal electronic world: A place where the words VERSION and REVISION do NOT exist ! |
|
|
Ttelmah Guest
|
|
Posted: Tue Aug 04, 2009 7:19 am |
|
|
Basically, yes.
The exceptions, are for things like using only one or two bits of portB, for an int on change, where the other bits need to be set as outputs, or for the ultimate speed. The compiler has over the years got better and better at handling TRIS itself, and it avoids a lot of portability issues. I'd say that for 99% of applications, let the compiler do it for you.
Best Wishes |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Tue Aug 04, 2009 11:25 am |
|
|
Ttelmah wrote: | Yes.
First apologies. Inputs, not outputs.
I have an email note from Microchip, saying that both serial pins need to be set as inputs for some chips (non specific for date codes....). Odd is that it is not in the errata for the chip.
|
I've read that. And I've seen that in action.
I typically code to inputs as the datasheet usually says, but when it doesn't work, I go and make the output pins output.
The module (UART) IS supposed to override the Digital I/O functionality... but that's not always the case.
Hey -- it could be worse, we could be dealing with the quirks of other companies chips which I've seen to be a LOT worse.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|
|
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
|