5
\$\begingroup\$

I am running below code in a PIC16F887 that runs at 20 MHz. I feed PORTB.0 a signal of 1 KHz from my signal generator. However, whenever the signal is low, PORTC.1 toggles at a rate of either ~5usec or ~10usec. Also, I've connected an OP-AMP's output that gives 0V-4V, still the same.

I have tried enabling weak pull ups inside, didn't work.

The microcontroller is on an EasyPIC5 development board, so I can enable and disable either pull-up or pull-down resistors that are 10K. Didn't work, either.

Is this some kind of silicon problem(?) or is there a mistake in my code?

Here is a screenshot from the oscilloscope that probes PORTC.1:

enter image description here

enter image description here

Here is my code, please omit off-topic part of it:

volatile unsigned int fiftymicros=0;
volatile unsigned int milis=0;
volatile unsigned char fiftymicroscounter=0;
volatile unsigned int data_time=0;
volatile unsigned int milis_ctr=0;
unsigned long int data_bar[20]={0};
void interrupt()
{
     if(INTCON.T0IF)
     {
      TMR0=198;
      INTCON.T0IF=0;
      fiftymicros++;
      if(++fiftymicroscounter==40) { fiftymicroscounter=0; milis++; }
     }
     if(INTCON.RBIF)
     {
      PORTC.F1=~PORTC.F1;
      INTCON.RBIF=0;
     }
}
void main()
{
     ANSEL =0;
     ANSELH=0;
     TRISA=0; PORTA=0;
     TRISB=0x01; PORTB=0;
     TRISC=0; PORTC=0;
     TRISD=0; PORTD=0;
     TRISE=0; PORTE=0;
     OPTION_REG.INTEDG=1;
     OPTION_REG.T0CS=0;
     OPTION_REG.PSA=0;
     OPTION_REG.PS0=1;
     OPTION_REG.PS1=0;
     OPTION_REG.PS2=0;
     //OPTION_REG.B7=0;
     //WPUB=0x80;
     INTCON.TMR0IE=0;
     INTCON.RBIE=1;
     IOCB.B0=1;
     INTCON.GIE=1;
     UART1_Init(9600);
     Delay_ms(100);
     milis_ctr=milis;
     while(1)
     {
     }
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ You are probably not clearing the condition properly on the high to low transition, so it keep recurring. \$\endgroup\$ – Olin Lathrop Mar 10 '12 at 0:01
  • \$\begingroup\$ @OlinLathrop I guess me blaming hardware prevented you from writing an answer :) ...silicon problem... \$\endgroup\$ – abdullah kahraman Mar 11 '12 at 11:46
5
\$\begingroup\$

You need to read PORTB before clearing the RBIF flag inside interrupt(), otherwise the mismatch will still exist and the RBIF flag won't be cleared. See section 3.4.3 INTERRUPT-ON-CHANGE in the PIC's datasheet:

For enabled interrupt-on-change pins, the present value is compared with the old value latched on the last read of PORTB to determine which bits have changed or mismatched the old value.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I wonder why those application notes do not include C code. I am not against assembly, however, they should include both. AN566 supports this answer. EXAMPLE 1: SINGLE INTERRUPT WITH A SMALL PULSE ... CLR_RBINTF MOVF PORTB, 1 ; Read PortB (to itself) to end ; mismatch condition \$\endgroup\$ – abdullah kahraman Mar 11 '12 at 12:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.