CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

#INT_EXT and #INT_RDA problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ljmnunes



Joined: 02 Sep 2004
Posts: 13
Location: Brazil

View user's profile Send private message

#INT_EXT and #INT_RDA problem
PostPosted: Sat Aug 01, 2009 8:54 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Aug 01, 2009 11:28 am     Reply with 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.


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

View user's profile Send private message

PostPosted: Sat Aug 01, 2009 1:48 pm     Reply with quote

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







PostPosted: Sat Aug 01, 2009 1:59 pm     Reply with 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.

Best Wishes
ljmnunes



Joined: 02 Sep 2004
Posts: 13
Location: Brazil

View user's profile Send private message

PostPosted: Sat Aug 01, 2009 6:03 pm     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Sun Aug 02, 2009 1:55 pm     Reply with quote

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 Cool two for one.
Ttelmah
Guest







PostPosted: Sun Aug 02, 2009 1:59 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Aug 02, 2009 2:52 pm     Reply with quote

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







PostPosted: Mon Aug 03, 2009 9:52 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Aug 03, 2009 9:24 pm     Reply with quote

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







PostPosted: Tue Aug 04, 2009 7:19 am     Reply with quote

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: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Tue Aug 04, 2009 11:25 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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