Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
March 28, 2024, 06:35:54 18:35


Login with username, password and session length


Pages: [1]
Print
Author Topic: Problem eith timer0  (Read 4846 times)
0 Members and 1 Guest are viewing this topic.
arash
Active Member
***
Offline Offline

Posts: 111

Thank You
-Given: 2
-Receive: 0


« on: March 31, 2009, 11:38:08 11:38 »

Hi.I'm new in IAR pic18 and trying to drive 18f452 tmr0 .Here is my code

#include <intrinsics.h>
#include <io18f452.h>

//========================================================

#pragma vector=0x0008
__interrupt void ISR (void)
{
  if(TMR0IF)
  {
    TMR0IE=0;
    TMR0IF=0;
    PORTD=PORTD^255;
    TMR0IE=1;
  }
}

//========================================================
int main(void)
{

  __set_configuration_bits(CONFIG1H,HSPLL_OSC_1);
  __set_configuration_bits(CONFIG2L,PWRT_ON_2&BOR_OFF_2);
  __set_configuration_bits(CONFIG2H,WDT_OFF_3);
  __set_configuration_bits(CONFIG3H,CCP2MX_ON_5);
  __set_configuration_bits(CONFIG4L,LVP_OFF_6);
  __set_configuration_bits(CONFIG5L,CP_OFF_8);

  TRISB=0;PORTB=0;
  TRISD=0;PORTD=0;
  T0CON=0x87;
  TMR0IE=1;
  TMR0IP=1;
  IPEN=1;
  GIEH=1;
  GIEL=1;
  PEIE=1;

  while(1)
  {
    RB0++;
  }
  return 0;
}

It works in Proteus but not work in real.The main section (RB0++)  works when the above line(#pragma) and the whole interrupt block remove.can you help me.Thanks
Logged
ALLPIC
Active Member
***
Offline Offline

Posts: 114

Thank You
-Given: 64
-Receive: 72


« Reply #1 on: March 31, 2009, 01:15:41 13:15 »

I think RB0++ is wrong because as it is Bool so by ++ you are making it more than 1 that may cause a problem. RB0 is PORTB so rathere than RB0++ if you can put PORTB++ then it will work, but you have to take care that PORTB will not flot more than 0xff. that I think will solve a problem and #pragma vector=0x0008 will not use in IAR pic18. I am not sure because I am not ueing IAR18 if you can give me IAR 18 I will check and let you know

Logged
arash
Active Member
***
Offline Offline

Posts: 111

Thank You
-Given: 2
-Receive: 0


« Reply #2 on: March 31, 2009, 01:56:15 13:56 »

The problem is that the code works in Proteus and RB0++ works (If i remove the interrupt section) .
I'm using demo version that i download directly from iar website
Logged
sam_des
Senior Member
****
Offline Offline

Posts: 253

Thank You
-Given: 124
-Receive: 146


« Reply #3 on: March 31, 2009, 08:44:53 20:44 »

Hi,

What is the code generated for 'RB0++' by compiler ? Check the listing.
What proteus does for this code ?
Is compiler generating 'RB0 toggle' as intended(?), If so you certainly won't see any changes on RB0, since processor is toggling it at 10 mips Smiley Check it with scope.

If I may say RB0++ is wrong, what is your intention - incrementing a bit var(port pin) ?

BTW you don't need to disable & re-enable interrupts within ISR, since all interrupts are by default disabled once youe enter ISR, also this your high priority interrupt, so that code isn't required.

Also from clarity point of view,  PORTD = PORTD ^ 255  should be written as,
 PORTD = PORTD ^ 0xff or better -
 PORTD ^= 0xff or even better -
 PORTD ^= 0b11111111 - IAR doesn't support this since it isn't ANSI, but provides most clear view of which bits are being toggled.

regards,
sam_des
« Last Edit: March 31, 2009, 08:50:40 20:50 by sam_des » Logged

Never be afraid to do something new. Remember Amateurs built the Ark, Professionals built the Titanic !
arash
Active Member
***
Offline Offline

Posts: 111

Thank You
-Given: 2
-Receive: 0


« Reply #4 on: March 31, 2009, 09:05:35 21:05 »

I already checked RB0 with oscilloscope.I'm sure that it works without ISR.
Logged
TomJackson69
Active Member
***
Offline Offline

Posts: 218

Thank You
-Given: 26
-Receive: 63


« Reply #5 on: April 01, 2009, 02:34:58 02:34 »

Hi.I'm new in IAR pic18 and trying to drive 18f452 tmr0 .Here is my code

#include <intrinsics.h>
#include <io18f452.h>

//========================================================

#pragma vector=0x0008
__interrupt void ISR (void)
{
  if(TMR0IF)
  {
    TMR0IE=0;
    TMR0IF=0;
    PORTD=PORTD^255;
    TMR0IE=1;
  }
}

//========================================================
int main(void)
{

  __set_configuration_bits(CONFIG1H,HSPLL_OSC_1);
  __set_configuration_bits(CONFIG2L,PWRT_ON_2&BOR_OFF_2);
  __set_configuration_bits(CONFIG2H,WDT_OFF_3);
  __set_configuration_bits(CONFIG3H,CCP2MX_ON_5);
  __set_configuration_bits(CONFIG4L,LVP_OFF_6);
  __set_configuration_bits(CONFIG5L,CP_OFF_8);

  TRISB=0;PORTB=0;
  TRISD=0;PORTD=0;
  T0CON=0x87;
  TMR0IE=1;
  TMR0IP=1;
  IPEN=1;
  GIEH=1;
  GIEL=1;
  PEIE=1;

  while(1)
  {
    RB0++;
  }
  return 0;
}

It works in Proteus but not work in real.The main section (RB0++)  works when the above line(#pragma) and the whole interrupt block remove.can you help me.Thanks


arash,

I don't have IAR pic18 but look at your program and what you said i have something to say.

What do you want to do with the intrupt? I see your interupt got nothing to do with your while loop because in the while loop you changing RB0 (PORTB,0) and in the interupt you do something with PORTD.

To check to see if your while loop and pin0 of portB work.
Let create a variable for counter:

int  Counter1;

and start with zero:

Counter1 = 0;

Now in your while loop increase Counter1 and check to see if it reach a number than change the state of pin RB0.

Counter1 += 1;       // increase by one

if(Counter1 == 50)
{
    //toggle RB0;       // what is toggle in your IAR?? (if you don't know like me than use next line)
    __asm BTG RB0  __endasm      // use inline assembly to toggle pin RB0 (hope this inline support by IAR)
    Counter1 = 0;      // clear Counter1 so we start the counter from 0 to 50, that way RB0 will toggle every 50 count.
}

So your while loop will looks like this:

 while(1)
  {
     Counter1 += 1;          // increase by one
     if(Counter1 == 50)
     {
           //toggle RB0;       // what is toggle in your IAR?? (if you don't know like me than use next line)
           __asm BTG RB0  __endasm      // use inline assembly to toggle pin RB0 (hope this inline support by IAR)
           Counter1 = 0;      // clear Counter1 so we start the counter from 0 to 50, that way RB0 will toggle every 50 count.
     }
  }

Or you can use delay for some mS (look in your library for delay, I work with MPLAB C18 so I don't know your compiler)

delaymS(20)   //delay 20mS;
RB0 = 0;
delaymS(20)   //delay 20mS;
RB0 = 1;

After you have your while loop work than debug your interupt routine. Your interupt routine look OK but you are using 1:128 prescale 8 bits, so it may be too long for next interupt to occur in Proteus. I would suggest to set T0CON=0x81; for 8 bits and prescale :4).

Hope this help,

Tom


Logged

Con Rong Chau Tien
arash
Active Member
***
Offline Offline

Posts: 111

Thank You
-Given: 2
-Receive: 0


« Reply #6 on: April 01, 2009, 06:38:34 06:38 »

I think this version of Iar compiler has some bugs.Take a look at this

  unsigned char tm;

  while(1)
  {
    tm=TMR0L;
    RD0=0;
    RD0=1;
    RD0=0;

  }

Compiler dose not compile this.

  unsigned char tm;

  tm=TMR0L;
  while(1)
  {
    RD0=0;
    RD0=1;
    RD0=0;

  }

but this cod compiled successfully.
 Huh
Logged
arash
Active Member
***
Offline Offline

Posts: 111

Thank You
-Given: 2
-Receive: 0


« Reply #7 on: April 01, 2009, 08:01:40 08:01 »

 Huh
« Last Edit: April 01, 2009, 08:03:53 08:03 by arash » Logged
sam_des
Senior Member
****
Offline Offline

Posts: 253

Thank You
-Given: 124
-Receive: 146


« Reply #8 on: April 01, 2009, 02:35:57 14:35 »

Hi,

Quote
think this version of Iar compiler has some bugs.Take a look at this

  unsigned char tm;

  while(1)
  {
    tm=TMR0L;
    RD0=0;
    RD0=1;
    RD0=0;

  }

Compiler dose not compile this.

  unsigned char tm;

  tm=TMR0L;
  while(1)
  {
    RD0=0;
    RD0=1;
    RD0=0;

  }

but this cod compiled successfully.

This isn't a bug, but just warning. See that in the first code you assigned TMR0L to tm within while() loop, but have never used tm anywhere nor there is any way to terminate while() loop. Compiler being optimizing, warned you about it.

Since TMR0L is a 'volatile', compiler generated code in spite of warning. If you use any other 'non-volatile' var in place of TMR0L, compiler will completely remove it.

This is called 'loop in-variant' optimization. It will move non-varying code out-of-loop or will completely remove it depending on loop code. That's what you did yourself in your second code.

Can you post code-listing generated by compiler for your original code, so that we can further help you.

regards,
sam_des
Logged

Never be afraid to do something new. Remember Amateurs built the Ark, Professionals built the Titanic !
arash
Active Member
***
Offline Offline

Posts: 111

Thank You
-Given: 2
-Receive: 0


« Reply #9 on: April 02, 2009, 05:45:43 05:45 »

Thanks sam_des.I think i have to learn more about C++.
Logged
sam_des
Senior Member
****
Offline Offline

Posts: 253

Thank You
-Given: 124
-Receive: 146


« Reply #10 on: April 02, 2009, 06:28:05 18:28 »

Arash,
Be careful man ! You have more than hundred posts.  Tongue
Use 'thank you' button, people will be more happy & we'll avoid cluttering up of our forum with unncessary posts  Grin
Or else.... Angry

regards,
sam_des
Logged

Never be afraid to do something new. Remember Amateurs built the Ark, Professionals built the Titanic !
drthilina
Newbie
*
Offline Offline

Posts: 14

Thank You
-Given: 19
-Receive: 7


« Reply #11 on: April 29, 2009, 10:05:09 22:05 »

Hi everyone.....
  Since this was a similar issue I didn't want to start a new thread. Please help me if you can.... I use C18 compiler and I'm trying to implement a High interrupt on INT0 and a Low interrupt on TMR0.. my code is shown below

#include <p18F4550.h>

#pragma config PWRT=ON, WDT=OFF, MCLRE=ON, PBADEN=OFF
#pragma config CCP2MX=ON, STVREN=OFF, LVP=OFF, ICPRT=OFF
#pragma config XINST=OFF, DEBUG=OFF, FOSC=XT_XT, FCMEN=ON

// prototyping
void low_isr(void);
void high_isr(void);

// global variables
char count=0;

void main(void)
{
   //Enable timer and its interrupts
   T0CON=0xD0;
   INTCON2bits.TMR0IP=0;//timer on low priority interrupt
   INTCON2bits.INTEDG0=1;   //interrupt on rising edge
   INTCON=(1<<7)+(1<<5)+(1<<4);
   TRISD=0;
   while (1)
   {
   }
}

/*-------------------------------------------------*/
#pragma code low_vector=0x18
void low_interrupt (void)
{
   _asm GOTO low_isr _endasm;
}
#pragma code
/*-------------------------------------------------*/
#pragma interruptlow low_isr
void low_isr(void)
{
   count++;
   PORTD=count;
   INTCONbits.T0IF=0;
   if(count==80)
   {
      count=0;
   }
}
/*-------------------------------------------------*/
#pragma code high_vector=0x08
void high_interrupt (void)
{
   _asm GOTO high_isr _endasm;
}
#pragma code
/*-------------------------------------------------*/
#pragma interrupt high_isr
void high_isr(void)
{
   count=0;
   INTCONbits.INT0F=0;
}
/*-------------------------------------------------*/

Even though I forced the program to go Low priority on Timer0 it always goes to High Priority Vector.. I checked with MPLAB SIM, Protues VSM and Oshonsoft PIC18... all with the same results... this ISR was taken from the C18 manual... please let me know where I'm doing wrong..

Regards
Logged
TomJackson69
Active Member
***
Offline Offline

Posts: 218

Thank You
-Given: 26
-Receive: 63


« Reply #12 on: April 29, 2009, 11:25:15 23:25 »

drthilina and Arash,
This is how I write my HI and LOW interrupt. Read the errata sheet from Microchip you will understand.

Code for MC18 (can mofify for other compiler)

//=====================================================================
//---------------------------------------------------------------------
// Locate Hi-Pri-int handler code
#pragma code highVector = 0x08

void HighVector (void)         // This function directs execution to the
{                          // actual interrupt code
   _asm

      goto HI_isr
   _endasm
}
//=====================================================================
//---------------------------------------------------------------------
// Locate Low-Pri-int handler code
#pragma code lowVector = 0x18
void lowVector (void)
{
   _asm
      goto LOW_isr
   _endasm
}

//=====================================================================
//-------------------- Program code bat dau ---------------------------
//=====================================================================
//---------------------------------------------------------------------


#pragma code    RB_int =   0x100      // I did put mine in 0x100 but
                                          // you don't have to.

//=====================================================================
//---------------------------------------------------------------------

#pragma interruptlow HI_isr

void HI_isr(void)
{
   //CHECK FOR INT0 FLAG

   //---------
   // put your code here
   //---------


   // CLEAR INT0 FLAG FOR NEXT INT0
}


//---------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------
#pragma interruptlow LOW_isr       // --- Khong auto save context if low-int ---

void LOW_isr(void)
{

   PIR1bits.TMR2IF = 1;      // disable Timer2 Interrupt. (OR WHATEVER YOUR TIMER)

   //---------
   // put your code here
   //---------

   PIR1bits.TMR2IF = 0;      // Enable Timer2 Interrupt.
}

///////////////////////////////////////////////////////////////////////
//

Note: See how #pragma interruptlow USED on both LOW and HI interrupt!

Hope that will solve your problem.

Tom
« Last Edit: April 29, 2009, 11:37:31 23:37 by TomJackson69 » Logged

Con Rong Chau Tien
drthilina
Newbie
*
Offline Offline

Posts: 14

Thank You
-Given: 19
-Receive: 7


« Reply #13 on: May 10, 2009, 04:58:54 16:58 »

Dear Tom,

The code you gave does not prioritise the interrupts right?.. it just executes the mentioned function twice.... but with further trial and error.. I found that there is a bit IPEN in the RCN register (why the hell in that..?) to enable the prioritising. afterwards the code that I've put up worked like a charm.. anyway.. I hope my experirence can help some other..

Cheers
Logged
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC