IF statement IGNORED

Thread Starter

graham2550

Joined Jun 24, 2014
14
I am creating a simple bug repeller, all it consists of is a ramping frequency between 20khz and 61khz.
I'm using a PIC16F688 at 20Mhz.
I use timer0 interrupt to switch a pin on and off to create a square wave.
I use timer1 interrupt at its slowest setting to increment the timer0 register, thus increasing the frequency.
when the variable for the timer0 gets to a certain point (61khz, 655315) I reset the variable to 140( 20khz)
The first pass starts correct frequency but the IF statement in the ISR to reset the numbers is totally ignored.
Timer0 just goes from 0 to 65535. Ignoring my "if " statement it seems.
very strange.
anyone help please, what am I doing wrong?

Rich (BB code):
sbit FOUT at RC0_bit;
sbit FOUT_Direction at TRISC0_bit;

unsigned int Timer_Count;

void InitTimer1(){            //.1sec
 T1CON         = 0x31;
  TMR1IF_bit         = 0;
  TMR1H         = 0x00;
  TMR1L         = 0x00;
  TMR1IE_bit         = 1;
}

void InitTimer0(){             //freq
  OPTION_REG         = 0x88;
  TMR0                 = Timer_Count;
  TMR0IE_bit = 1;
}

void Interrupt(){

   if (TMR0IF_bit){
     TMR0IF_bit = 0;
     TMR0 = Timer_Count;
     FOUT = ~FOUT;
  }
   if(TMR1IF_bit){                          //0.2 second
     TMR1IF_bit = 0;
     TMR0IE_bit = 0;
     Timer_Count ++;
     if (Timer_Count > 65513) Timer_Count = 140;      //65513 is 61khz, 140 is 20khz
     TMR0IF_bit = 0;
     TMR0IE_bit = 1;
  }
}

void main() {
ANSEL = 0;
ADCON0 = 0;     //turn off analog functions
CMCON0 = 7;     //turn off comparators
PORTC = 0;
TRISC = 0;      // port C outputs


Timer_Count = 140;
INTCON         = 0xE0;
InitTimer1();       //.1 sec
InitTimer0();        //freq



while (1)
  {
}
}
 

JohnInTX

Joined Jun 26, 2012
4,787
Timer 0 is only 8 bits so it can't accept the 16 bit TimerCount.

Since you are already in an ISR, you don't have to turn off TMR0IE in the TMR1 service.

EDIT: its MicroC, yes?
Change
void Interrupt to
void interrupt

Keywords are case sensitive and you did not have any interrupt routine built (it thought 'Interrupt' was a normal routine and since it was not called, got optimized right out). Be sure to turn ON case-sensitivity for the project. Its off by default - a bad idea. From the manual:
The mikroC PRO for PIC identifiers aren't case sensitive by default, so that Sum, sum,
and suM represent an equivalent identifier. Case sensitivity can be activated or suspended
in Output Settings window. Even if case sensitivity is turned off Keywords
remain case sensitive and they must be written in lower case.
There are a couple of ways you can tell when this is happening:
Start the Debugger and observe that you can't set breakpoints on any of the code in the interrupt routines - there is no code.
Open the Listing Output window (not the Assembler Output) and observe that there is nothing built for any interrupt routine. It IS there in the assembler output but the linker optimizes it out.

Keep in mind that MicroC's software debugger does NOT support interrupts, timer values in a watch window. You might want to create a project in MPLAB 8.x in the same folder and import the .COF and .C files from MicroC and use MPSIM. That's what I did and the problem became immediately apparent.

Have fun.
 
Last edited:

Thread Starter

graham2550

Joined Jun 24, 2014
14
Thank you JohnInTX for waking me up. I dont know what I was thinking. I know its an 8bit timer, max 255. Thanks for the advice on case sensitivity, I'll put that right in settings. Yes MikroC I use, have been sinse I started coding PIC's.
I want to try MPLABX, is this a good IDE and compiler?
Anyway, with your advice now works good.
 

JohnInTX

Joined Jun 26, 2012
4,787
Thank you JohnInTX for waking me up. I dont know what I was thinking. I know its an 8bit timer, max 255. Thanks for the advice on case sensitivity, I'll put that right in settings. Yes MikroC I use, have been sinse I started coding PIC's.
I want to try MPLABX, is this a good IDE and compiler?
Anyway, with your advice now works good.
MPLABX / XC8 is good and getting better as bugs are fixed. Compared to MicroC, it probably compiles tighter code and has better debugging support. It supports the cheap PICKit debuggers which support/program a wider variety of PICs. XC8 also handles baseline/midrange PICs better (in my experience).

MicroC has more library support for easy development with LCD displays, beepers, CAN, Ethernet, USB etc. and is a bit more user-friendly.

The free version of XC8 has no set memory limitations but it doesn't optimize like the paid version. Give them a look.
 

Thread Starter

graham2550

Joined Jun 24, 2014
14
Yes thats why I chose MikroC because of the library, its very good. and I use the PicKit programmer with it.
I use MikroC for PIC32 also, supports ICD.
But I'll definitely give MPLABX a try.
Thanks again for your help and advice
 

kubeek

Joined Sep 20, 2005
5,795
Rich (BB code):
 if (TMR0IF_bit){...}
Is TMR0IF_bit actually returning the value of that bit, or is it a constant with the location of that bit inside some register?
 

Thread Starter

graham2550

Joined Jun 24, 2014
14
TMR0IF is timer 0 interrupt flag.
It gets set when the timer overflows.
For an 8 bit timer this is 255, a 16 bit timer 65535. Timers count clock frequency /4.
You can read it and clear it, TMR0IF =0.
It will trigger an interrupt.
 

THE_RB

Joined Feb 11, 2008
5,438
Rich (BB code):
 if (TMR0IF_bit){...}
Is TMR0IF_bit actually returning the value of that bit, or is it a constant with the location of that bit inside some register?
MikroC allows bitwise logic, and detecting or setting/clring bits directly.

That if() statement will directly test the INTCON.TMR0IF bit and compile down to a BTFSS asm instruction.
 

Thread Starter

graham2550

Joined Jun 24, 2014
14
thanks for your reply THE_RB, as you will have noticed in an earlier post, this has been solved.
anyway, the 'if' statement in question was this one: if (Timer_Count > 65513) Timer_Count = 140;
 
Top