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 CCS Technical Support

Question regarding INT_RB behaviour.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








Question regarding INT_RB behaviour.
PostPosted: Sat Nov 17, 2007 12:12 pm     Reply with quote

Here is the program that I have:
Code:

#include <16f877a.h>

#fuses HS
#fuses NOWDT
#fuses NOPROTECT
#fuses NOLVP

#use delay(clock=20000000)
#use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#include <stdlib.h>
#include <stdlibm.h>

long counterb;

#INT_RB
void encoder_ISR()
   {
   ++counterb;
   printf("\n\r%lu", counterb);
   }

void main(void)
   {   
   set_tris_B(0xFF);
   counterb = 0;
   port_b_pullups(TRUE); 

   enable_interrupts(INT_RB);
   enable_interrupts(GLOBAL);
   
   while (!kbhit())
      {
      if (counterb != 0)
          {
          // Do whatever here.
          }
      }
     
   disable_interrupts(INT_RB);
   disable_interrupts(GLOBAL);port_b_pullups(TRUE);
   }

I'm forced to use the CCS PIC16F877A board which has those two LEDs attached to port B leaving B6 and B7 available for external interrupts, which is what we require for two encoders (Timer2 is being used for PWM and not even sure T2 can be externally driven since I never looked into the datasheet for that timer ... I digress).

I would eventually like to create a simple INT_RB handler which will simply run each time there is a change on the upper nibble of port B (B6 and B7) and increment global variables depending on which is actually triggered.

The code compiles fine but nothing happens when I bring B6 or B7 to 5v.

Could that be because I don't have a switch available and it's going from floating voltage to 5 volts? I know it should be going between GND and 5V but I should get at least *something* to indicate that it's running.

What exactly does the port_b_pullups() do exactly? Create an internal resistance to measure a voltage across? I thought that's what a Set_Tris_B() does?

Any other thoughts/suggestions?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 17, 2007 1:49 pm     Reply with quote

Inside the #int_rb routine, you need to read Port B to clear the
mismatch condition. If you don't do this, you will get Port B interrupts
continuously and your program will appear to be locked up.
Example:
Code:

#byte PortB = 6   // Address of PortB for 16F-series PICs

#int_rb
void rb_isr()
{
int8 c;

// Put your code here.

c = PortB;  // Read PortB to clear mismatch condition
}


Also, in your main() code, you need to read Port B, and then clear
the INT_RB interrupt flag before you enable Port B interrupts and
global interrupts. Also, the RB6 and RB7 inputs should not be left
floating. I suggest that you enable the pull-ups at the start of the
program. Then cause an interrupt by momentarily connecting one
of the pins (RB6 or RB7) to ground.

Also, be aware that these two pins are used by the debugger or
programmer to talk to the PIC. You can't use these pins for normal
i/o while the programmer or debugger is connected.

Example:
Code:

void main()
{
char c;

port_b_pullups(TRUE);
delay_us(10);  // Allow time for them to pull-up to +5v
c = PortB;    // Clear mismatch condition
clear_interrupt(INT_RB);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);

// Put your code here.


while(1);   // Prevent PIC from going to sleep
}
Guest








PostPosted: Sat Nov 17, 2007 3:25 pm     Reply with quote

Yeah, I knew about the debugger pins. I figured that might have been the problem if pins B6 and B7 were left high by the ICD so I've been disconnecting the ICD, then running the program. I can't do much about the floating voltages at home except using the switch on PIN_A4 (normally HIGH).

With that connected I'd expect the ISR to continue counting until the button was held down (driving the pin to GND).

My program doesn't appear to be locking up. It just won't execute the interrupt at all. I know I shouldn't put a printf() statement in my routine but I wanted to have something that I knew for sure would show that something was being done. It just constantly outputs 0, which shouldn't be the case. It should be incrementing and I don't think you can exactly overflow a long in the time for one printf() to occur.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 17, 2007 4:57 pm     Reply with quote

To cause an INT_RB interrupt, a change in logic levels must occur on
one or more of pins B4-B7. You can't have the pins be in a floating
state. You need to put either a pull-down or a pull-up resistor on the
pins, to provide a well-defined logic level for the idle state. Then put
the opposite voltage on the pin. An interrupt should occur. A 2nd
interrupt will occur when you remove the voltage and the pin returns
to the idle state.

You need to make all the changes that I suggested, and you need to
put pull-up or pull-down resistors on your INT_RB pins. (10K will work).
Guest








PostPosted: Sun Nov 18, 2007 10:02 am     Reply with quote

I gather there it interrupts on an edge.

No way to make it interrupt on only one edge or just simply divide by two? I suppose we don't have to be exact and off by one but...

As for the whole port_x_pullup() issue, I'm still not sure why that is needed? I always thought that's what set_Tris_x() does.
Ttelmah
Guest







PostPosted: Sun Nov 18, 2007 10:12 am     Reply with quote

Very much, no.....
TRIS, configures the individual pins as inputs, or outputs. Once a pin is an input, it can trigger the interrupt. However if it is floating, it can trigger this randomly, at any time, and draw extra power as the input transitions.
An input, _must_ be connected at all times to something, to ensure it is held either high or low. The port_B_pullups, allow a 'floating' input, to reliably be pulled gently high, till a switch or similar source, pulls it low.
The RB interrupt, triggers on both edges. All you do, is in the interrupt, read the level, and see if it is the edge you want.
The separate interrupts (INT_EXTn), can be programmed to occur on a specific edge, but are not available on the pins you want to use.

Best Wishes
Guest








PostPosted: Sun Nov 18, 2007 4:24 pm     Reply with quote

So, pullups are only necessary if I cannot ensure a digital logic level and/or the voltage is floating for a period?

Another issue is how to handle debounce? In our case, we are using phototransistors as the interrupt source(s) so should we be concerned about it?
SET



Joined: 15 Nov 2005
Posts: 161
Location: Glasgow, UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Nov 19, 2007 5:21 am     Reply with quote

Yes, phototransistors are effectively light to current converters, so unless they are feeding into a comparator or similar then you might see 'in between' voltages. If you however the phototransistors see only 'light' and 'dark' then it should be fine.
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Mon Nov 19, 2007 7:14 am     Reply with quote

The port B pullups are already taking the line to 5v. You need to take the line to GND in order to generate your interrupt OR you can remove the port B pullups and fit external pull DOWNS to the pins. That way when you take the pin to 5v you should have your interrupt.
zagoaristides



Joined: 08 Jul 2007
Posts: 15
Location: Cordoba - Argentina

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

Hi, the int_rb doesn't work. I've read many threads
PostPosted: Tue Feb 23, 2010 2:37 pm     Reply with quote

Code:

#include <16F917.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOCPD                    //No EE protection
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NODEBUG                  //No Debug mode for ICD

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)


#include "C:\Documents and Settings\Aristides\Escritorio\gus\main.h"

char Arriba, Abajo, Enter, Escape;

#int_RB
void  RB_isr(void)
{
      char auxiliar;
      disable_interrupts(INT_RB);
     
      Enter    = !input (PIN_B4);
      Arriba   = !input (PIN_B5);
      Abajo    = !input (PIN_B6);
      Escape   = !input (PIN_B7);
     
      delay_ms (20);  //anti-rebotes
      auxiliar = input_b();

      clear_interrupt(INT_RB); 
      enable_interrupts(INT_RB);
      /*
      #asm movf Port_B,0 #endasm*/
}


void main()
{
   char c;

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_lcd(LCD_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   // TODO: USER CODE!!

   port_b_pullups(TRUE);
   delay_us(10);  // Allow time for them to pull-up to +5v
   c = input_b();    // Clear mismatch condition
   clear_interrupt(INT_RB);
   enable_interrupts(INT_RB);
   enable_interrupts(GLOBAL);
   
// Put your code here.

while(1);   // Prevent PIC from going to sleep
}

What can I do to make it work ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Feb 23, 2010 3:35 pm     Reply with quote

How are you testing this ? I don't see any printf statements to show
the output. How do you know if it's working or not working ?

Are you testing this in real hardware, or in Proteus ?

What is the signal source that is driving pins B4 to B7 ? Do you have
push-button switches on those pins ? Or some other signal ?
What are the voltage levels of the signals ?
zagoaristides



Joined: 08 Jul 2007
Posts: 15
Location: Cordoba - Argentina

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

Thanks my friend
PostPosted: Tue Feb 23, 2010 4:03 pm     Reply with quote

PCM programmer wrote:
How are you testing this ? I don't see any printf statements to show
the output. How do you know if it's working or not working ?

Are you testing this in real hardware, or in Proteus ?

What is the signal source that is driving pins B4 to B7 ? Do you have
push-button switches on those pins ? Or some other signal ?
What are the voltage levels of the signals ?


I've tested on Proteus. The others work, this doesn't
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Feb 23, 2010 4:31 pm     Reply with quote

I can't test anything on Proteus because I don't have it.
zagoaristides



Joined: 08 Jul 2007
Posts: 15
Location: Cordoba - Argentina

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

PostPosted: Mon May 03, 2010 7:38 am     Reply with quote

PCM programmer wrote:
I can't test anything on Proteus because I don't have it.

in real simulation doesn't work either.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon May 03, 2010 11:14 am     Reply with quote

I looked at your code and found a problem with this line:
Quote:

port_b_pullups(TRUE);

In the 16F917, PortB pullups are individually enabled. You need to
use a bitmask instead of True/False. If you want pull-ups on pins B4-B7
then you need to set those bits high, in the function parameter. Example:
Code:

port_b_pullups(0xF0);  // Enable pull-ups on pins B4-B7
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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