Timer1, Interrupts and SLEEP (on 18F45K22) - can't get it to work at all!


Closed Thread
Results 1 to 4 of 4
  1. #1
    Join Date
    Sep 2009
    Location
    South Wales (UK)
    Posts
    62

    Default Timer1, Interrupts and SLEEP (on 18F45K22) - can't get it to work at all!

    Hi,
    I'm trying to get a circuit I have to save on battery power by sleeping for most of the time. Having read through as much as my head would take of interrupts, timers, sleep modes etc I'm starting to cloud over. I did have timer0 running earlier, creating an interrupt and pulsing a blue LED. I'm now trying to get timer1 to do the same thing, although just getting it to say 'interrupt' on the serial port within the interrupt routine. However, I can't get it to enable. I've even looked at TMR1L/H and they are not incrementing at all!
    Going nuts here!!! Can anyone PLEASE take a look at my code (have removed the majority of crap to simplify it for anyone who has the time/inclination...
    My eventual aim is to incorporate this code into my already working code for writing I2C sensor data to SD card to allow data capture over several days/weeks from a single battery - note the commented out PMD variables where I was attempting to disable as many peripherals as possible.
    Any clues/hints greatly appreciated.

    Best regards all, and happy guy fawkes!
    Jimbo

    Code:
    define      OSC 16
    DEFINE      HSER_BAUD 19200
    DEFINE      HSER_CLROERR 1  ' Auto clear over-run errors
    DEFINE      HSER_RCSTA 90h
    DEFINE      HSER_TXSTA 20h
    blue_LED                var portb.5
    trisa                   =   %00000000
    trisd                   =   %00000000
    trisc                   =   %00000000
    trisb                   =   %00001000  
    adcon0.0                =   0
    ANSELA                  =   0
    ANSELB                  =   0
    ANSELC                  =   0
    ANSELD                  =   0
    ANSELE                  =   0 
    ADCON1                  =   15
    tmp1                    var byte
    tmp2                    var byte
    p1                      var byte
    p2                      var byte
    p3                      var byte
    seconds                 var byte
    pausetime               var byte
    OSCCON = OSCCON | %11110000 ' set internal clock to 16 MHz incase of switchover
    On Interrupt Goto myint
    'PMD0 = %11111110
    'PMD1 = %11111111
    'PMD2 = %11111111
    pause 4000
    IPR1.0 = 1
    INTCON = %11000000  ' global int enable, 
    T1CON.7 = 1   ' timer 1 clock source is oscillator (external xtal) YES
    T1CON.6 = 0   ' """""""""""""""""""""""""""""""""""""""""""""""""" YES
    T1CON.5 = 0   ' prescale value set to 1:1                          YES
    T1CON.4 = 0   ' """""""""""""""""""""""""                          YES
    TMR1H = $ff
    TMR1L = 0
    T1CON.2 = 1   ' do not synchronise external clock input with system clock YES 
    T1CON.1 = 0   ' 8 bit timer? 
    T1CON.0 = 1   ' enable timer 1
    T1CON.3 = 1   ' secondary (external) oscillator enable bit         YES
    TMR1H = 0     ' Clear time counts before Timer1 re-start
    TMR1L = 0     ' Clear time counts before Timer1 re-start
    PIR1.0 = 0    ' Clear over-flow flag before enable
    PIE3.0 = 1
    PIE1.0 = 1    ' timer 1 enable interrupt
    lp3:
    high blue_LED
    p2 = TMR1L
    hserout[$d,$a,#p2]
    pause 50
    low blue_LED
    pause 50
    goto lp3
    Disable 
    myint:
        high blue_LED
        pause 50
        low blue_led
        hserout[$d,$a,"Interrupt!"]  
        PIR1.0 = 0
        Resume               
        Enable

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,512


    Did you find this post helpful? Yes | No

    Default Re: Timer1, Interrupts and SLEEP (on 18F45K22) - can't get it to work at all!

    Hi,
    You have the two highest bits of T1CON set to 10 and T1CON.3 set to 1 which, if I read the datasheet correctly, sets TMR1 up to be clocked from an external crystal (32768Hz) connected between the SOSCI and SOSCO pins. Do you have a crystal connected here?

    If you want TMR1 to be "driven" by the main oscillator (the internal 16MHz oscillator in your case) you should set the two high bits to either 00 (Fosc) or 01 (Fosc/4). This mode however won't work if you want TMR1 to wake the PIC up from sleep since the main osciallator (now "driving" TMR1) is shut down when you enter sleep mode.

    /Henrik.

  3. #3
    Join Date
    Sep 2009
    Location
    South Wales (UK)
    Posts
    62


    Did you find this post helpful? Yes | No

    Default Re: Timer1, Interrupts and SLEEP (on 18F45K22) - can't get it to work at all!

    Hi Henrik,

    Many thanks for your help. I was going round in circles last night. I was confused by the fact that the timer could be clocked when the oscillator was shut down, but as you say, there it was in black and white - secondary oscillator!!! I was glancing past the SOSCI/O part, just seeing the OSCI/O thinking it was the main oscillator. Anyway, I've fitted a 32.768 KHz xtal to the secondary pins and will continue with things. Last night I did manage to get the chip to go to idle, but I guess that's no mean feat! Going to sleep, sent it to sleep and that was that lol.

    Cheers again, you have been a great deal of help on what most people would consider a simple issue.

    Jimbo

  4. #4
    Join Date
    Sep 2009
    Location
    South Wales (UK)
    Posts
    62


    Did you find this post helpful? Yes | No

    Default Re: Timer1, Interrupts and SLEEP (on 18F45K22) - can't get it to work at all!

    Hi Henrik,

    Just to thank you again. Installed the 32.768KHz xtal with a 12pF cap on each leg to earth and it now all runs. Also, I now have a clearer head and all the settings now make sense in my head. Current drops from around 2mA for my test circuit to about 100uA, which I believe is roughly the norm. This should DRAMATICALLY increase the lifetime of the battery!

    The code I now have is below for the benefit of others.

    Best regards

    Jimbo

    Code:
    define      OSC 16
    DEFINE      HSER_BAUD 19200
    DEFINE      HSER_CLROERR 1  ' Auto clear over-run errors
    DEFINE      HSER_RCSTA 90h
    DEFINE      HSER_TXSTA 20h
    blue_LED                var portb.5   'prototype =a3, sleep test cct b5
    trisa                   =   %00000000
    trisd                   =   %00000000
    trisc                   =   %00000000
    trisb                   =   %00001000  
    adcon0.0                =   0
    ANSELA                  =   0
    ANSELB                  =   0
    ANSELC                  =   0
    ANSELD                  =   0
    ANSELE                  =   0 
    ADCON1                  =   15
    tmp1                    var byte
    tmp2                    var byte
    p1                      var byte
    p2                      var byte
    p3                      var byte
    seconds                 var byte
    pausetime               var byte
    i2cSDA      VAR PORTD.1
    i2cSCL      VAR PORTD.0
    pause 50
    i2cwrite i2cSDA,i2cSCL, $d0, $3e, [64] ' switch off the gyroscope (save 6.5 mA)
    pauseus 5
    'I2CWRITE i2cSDA,i2cSCL, $a6, $2c, [%1000]  'accelerometer
    pauseus 5
    OSCCON = OSCCON | %11110000 ' set internal clock to 16 MHz incase of switchover
    On Interrupt Goto myint
    PMD0 = %10111110 ' leave UART1 and Timer1 enabled
    PMD1 = %10111111 ' leave MSSP1 (SPI) enables
    PMD2 = %11111111 ' disable all these peripherals
    IPR1.0 = 1
    INTCON = %11000000  ' global int enable
    OSCCON.7 = 0  ' CPU goes to IDLE when SLEEP command given
    T1CON.3 = 1   ' secondary (external) oscillator enable bit         
    T1CON.7 = 1   ' timer 1 clock source is oscillator (external xtal) 
    T1CON.6 = 0   ' """""""""""""""""""""""""""""""""""""""""""""""""" 
    T1CON.5 = 0   ' prescale value set to 1:1                          
    T1CON.4 = 0   ' """""""""""""""""""""""""                          
    T1CON.2 = 1   ' do not synchronise external clock input with system clock  
    T1CON.1 = 0   ' 2x 8 bit timer value output
    TMR1H   = $fc   ' Clear timer1 count 
    TMR1L   = 0   ' Clear timer1 count 
    PIR1.0  = 0   ' Clear over-flow flag before enable
    PIE1.0  = 1   ' timer 1 enable interrupt
    T1CON.0 = 1   ' enable timer 1
    
    lp:
    
    ' do something in this loop
    sleep 10 ' and then go to sleep
    
    goto lp
    stop
    Disable 
    myint:
        hserout[$d,$a,"Interrupt!"]
        high blue_led
        pause 1
        low blue_led
        TMR1H = $fc
        TMR1L = $0
      
        PIR1.0 = 0 ' reset interrupt request flag
        Resume               
        Enable

Members who have read this thread : 1

You do not have permission to view the list of names.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts