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

wdt with timer0 interrupt with 18f46k22

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



Joined: 25 Aug 2010
Posts: 47

View user's profile Send private message

wdt with timer0 interrupt with 18f46k22
PostPosted: Tue Jun 11, 2019 7:27 am     Reply with quote

hi,
I have used wdt clearly but I couldn't use wdt with timer0 interrupt.
(I want to write message on lcd before reset the card).

I use this code but not working.
Code:

setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);
setup_wdt(WDT_ON | WDT_1S);


How can I use interrupt with wdt?

thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jun 11, 2019 9:34 am     Reply with quote

Post a complete (but small) test program, where you enable interrupts
and have a Timer0 interrupt routine.

Also post your compiler version.

The reason is, in the 18F46K22, according to the block diagrams in the
data sheet, there is no connection between Timer0 and WDT.
In older PICs, like the 16F877, yes.

If you post a real test program, we can see what you're doing.
Ttelmah



Joined: 11 Mar 2010
Posts: 19487

View user's profile Send private message

PostPosted: Tue Jun 11, 2019 10:31 am     Reply with quote

However even on the older PIC's, the only 'connection' is that the prescaler
is shared. The two systems are otherwise independant, and enabling the
watchdog does not affect the ability to use timer0 at all.
zamzam23



Joined: 25 Aug 2010
Posts: 47

View user's profile Send private message

PostPosted: Wed Jun 12, 2019 1:46 am     Reply with quote

of course, here is some part of code. (Complier: v5.055)

Code:

#ignore_warnings 203
#include "18f46K22.h"
#DEVICE *=16,PASS_STRINGS=IN_RAM,  HIGH_INTS=TRUE
#ROM int16 getenv("EEPROM_ADDRESS") = {500}
#device ADC=10
#include "stdlib.h"
#include "math.h"
#fuses HSH,WDT_SW,NOBROWNOUT,NOLVP,PUT,NOWRT,NODEBUG,NOCPD,NOSTVREN,NOPROTECT,NOIESO,NOFCMEN,NOPLLEN
#use delay(crystal=20MHz, clock=20Mhz)

#int_rtcc
void interrupt_wdt(void)
{
glcd_init(on); delay_ms(50);
glcd_text57(5,20,"WDT alarm is coming!",1,on);
while(1);
}

#use delay(clock=20M)
void main ( )
{

    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
    disable_interrupts(INT_TIMER1);

   
    setup_adc(ADC_CLOCK_INTERNAL);
    setup_adc_ports(sAN0 | sAN1);
    delay_us(25); 
   
    setup_timer_2(T2_DISABLED,0,1); 
    setup_ccp1(CCP_OFF);

   
    setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);
    enable_interrupts(INT_RTCC);
    enable_interrupts(GLOBAL);
    setup_wdt(WDT_ON | WDT_1S);
   
   
    while(1)
    {
        restart_wdt();
    }
}
zamzam23



Joined: 25 Aug 2010
Posts: 47

View user's profile Send private message

PostPosted: Wed Jun 12, 2019 4:44 am     Reply with quote

PCM programmer wrote:

The reason is, in the 18F46K22, according to the block diagrams in the
data sheet, there is no connection between Timer0 and WDT.
In older PICs, like the 16F877, yes.


if there is no connection between wdt and timer0, this code will not work as normally right?

So, how can I get alarm just before wdt reset?
temtronic



Joined: 01 Jul 2010
Posts: 9220
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jun 12, 2019 5:31 am     Reply with quote

It's not really possible. The WDT is not xtal contolled and basic timing for it is 3.5-4.7ms from the data sheet. This will be at 'room temperature' and will vary on actual temperature.
Now you could add an EXTERNAL WDT(E-WDT).Old school was to use a 74123(?) retriggerable multivibrator that would send a constant 'high' until it timed out, to an interrupt input pin. 'main()' would send a pulse to the E-WDT. Keep in mind this device is R-C timed as well, so it'll vary.

What is the purpose for using the WDT ?

also...
having ANY delays inside any ISR is bad coding
Ttelmah



Joined: 11 Mar 2010
Posts: 19487

View user's profile Send private message

PostPosted: Wed Jun 12, 2019 5:39 am     Reply with quote

The units are never connected. The only 'link' is that on some of the more
basic PIC's they share their prescaler.

On this chip, two completely separate units. You are setting the watchdog
for a nominal 1 second (beware you should restart the watchdog before doing
this otherwise it may well have counted quite a few cycles already at this
point - changing the divisor does not reset the count). Then a separate timer
being fed off the master oscillator, /4 /1 /65536, so 1/76th second.
Then, how are you testing?. Understand that the WDT, will not function
in a debugger.
Then the watchdog, does not actually start running till you get into the
timer0 interrupt code, since you have a restart_wdt in the main code.
So it'll enter this timer interrupt after 1/76th second, then wait for (about) 1
second, till the watchdog fires. The code as posted can't compile, since you
don't load any code for the GLCD.
Some comments inline:
Code:

#include "18f46K22.h"
//*=16 not required on a PIC18
//You are also not using HIGH_INTS
#DEVICE PASS_STRINGS=IN_RAM

#ROM int16 getenv("EEPROM_ADDRESS") = {500}
#device ADC=10

#fuses HSH,WDT_SW,NOBROWNOUT,NOLVP,PUT,NOWRT,NODEBUG,NOCPD,NOSTVREN,NOPROTECT,NOIESO,NOFCMEN,NOPLLEN
#use delay(crystal=20MHz, clock=20Mhz)

//code should always be after fuses and clock
#include <stdlib.h>
#include <math.h>

//Don't switch netween using RTCC and Timer0
#INT_TIMER0
void interrupt_timer0(void)
{
   //You don't show any driver for the GLCD being loaded
   glcd_init(on); delay_ms(50);
   glcd_text57(5,20,"WDT alarm is coming!",1,on);
   //If you use 'TRUE', you don't need to ignore warning 203
   while(TRUE)
     ; //Now because the code will stall here, the watchdog will trigger
}

#use delay(clock=20M)
void main ( )
{

    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
    //ADC_CLOCK_INTERNAL is not recommended above 1MHz   
    setup_adc(ADC_CLOCK_DIV_32);
    setup_adc_ports(sAN0 | sAN1);
    delay_us(25);
   
    setup_timer_2(T2_DISABLED,0,1);
    setup_ccp1(CCP_OFF);
   
    setup_timer_0(T0_INTERNAL | T0_DIV_1);
   
    enable_interrupts(INT_TIMER0);
    enable_interrupts(GLOBAL);
   
    setup_wdt(WDT_ON | WDT_1S);
     
    while(TRUE)
    {
        restart_wdt();
    }
}   

The timer, and the watchdog are two separate systems.
zamzam23



Joined: 25 Aug 2010
Posts: 47

View user's profile Send private message

PostPosted: Wed Jun 12, 2019 7:10 am     Reply with quote

thanks for your explanatory answers.

I understood that wdt and timerX are separate systems so I am going to think another way for progress my software.

I cannot detect wdt just before triggers but Maybe I can detect it just after wdt with this code.

Code:
switch ( restart_cause() )
   {
      case WDT_TIMEOUT:
      {
         glcd_text57(5,20,"WDT reset !...",1,on);
         delay_ms(2000);
         break;
      }
      case NORMAL_POWER_UP:
      {
         break;
      }
   }
Ttelmah



Joined: 11 Mar 2010
Posts: 19487

View user's profile Send private message

PostPosted: Wed Jun 12, 2019 7:23 am     Reply with quote

Though the systems are independant, there is no reason at all that you cannot
set a timer to actually trigger just before the watchdog.
However remember that sending text to a GLCD, will take a significant
time, so you need to allow for this. Also the watchdog won't trigger while
the code is looping calling restart_wdt.

So:
Code:

void main ( )
{

    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
    //ADC_CLOCK_INTERNAL is not recommended above 1MHz   
    setup_adc(ADC_CLOCK_DIV_32);
    setup_adc_ports(sAN0 | sAN1);
    delay_us(25);
   
    setup_timer_2(T2_DISABLED,0,1);
    setup_ccp1(CCP_OFF);
   
    setup_timer_0(T0_INTERNAL | T0_DIV_64);
    set_timer0(0L);
    //This now gives 20MHz/(4*16*65536) = 1.19Hz
    //So interrupt in 0.838 seconds
   
    enable_interrupts(INT_TIMER0);
    enable_interrupts(GLOBAL);
   
    setup_wdt(WDT_ON | WDT_1S);
    restart_wdt();
     
    while(TRUE)
    {
        delay_cycles(1);
        //Now code will sit here, and the timer will trigger in 0.838
        //seconds and the watchdog a few mSec later.
    }
}   
temtronic



Joined: 01 Jul 2010
Posts: 9220
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Jun 13, 2019 4:33 am     Reply with quote

re:
Quote:
I am going to think another way for progress my software.
Please tell us what you're trying to do, we may know of a way to do it.

You need to remember the WDT is not an accurate 'timer'.

Jay
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