pic18f887 event timer


Closed Thread
Results 1 to 19 of 19
  1. #1
    Join Date
    Aug 2005
    Location
    NC, USA
    Posts
    53

    Default pic18f887 event timer

    I am using a PIC18F887 with the internal oscilator set @ 8MHz. I have a subroutine I need to fire off at a routine basis (nominally every 22ms although I want it a constant that I can tune). Can someone give me a crash course (with as much details so I don't have to ask a bunch of follow on dummy questions) on how I set this up as some sort of timer on an interupt, preferably without using assembly, but if that is the only way, I am willing to try. I have no available IO pins remaining if that matters. I am using no other interupts, but future versions may entail a serial interupt. I only want it to fire after a complete line is executed, which I think is by default, then return to the next line after it runs the routine. I suspect its fairly easy, but I am not sure where to start.

    Thanks,
    Charlie

  2. #2
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    http://www.picbasic.co.uk/forum/showthread.php?t=3251
    Be sure to read the first eight post.
    Dave
    Always wear safety glasses while programming.

  3. #3
    Join Date
    Aug 2005
    Location
    NC, USA
    Posts
    53


    Did you find this post helpful? Yes | No

    Default

    OK. This looks good. Thanks.

    I think the overkill blinking light is the right for me to use. I am unlear what to change to get timer 1 to fire off every 22ms.

    I assume it starts with this seting
    T1CON = $31 ; Prescaler = 8, TMR1ON

    I have two different harware setups I am trying to put it in. Both use the PIC16F887, one with an external 20MHz Osc, the other with an internal 8MHz. It looks like a prescaler of 1:8 is the max, so I suspect I need to do a counter in the interupt routine that only fires my event every nth time to acheive the 22ms event? Is this a big burden or is there a simpler way? Can someone show me some examples of how to do the math to get the event to fire off properly with the two oscillator speeds?


    Thanks,
    Charlie

  4. #4
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    Can someone show me some examples of how to do the math to get the event to fire off properly with the two oscillator speeds?
    Charlie, play with the attached little tool to find out.

    How to use it: click on the box enter the new value and press enter.

    Cheers

    Al.
    Attached Files Attached Files
    Last edited by aratti; - 26th October 2010 at 09:54.
    All progress began with an idea

  5. #5
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Timer 1 is 16 bit.
    At 8 Mhz with a prescale of 1 and a peload of 21537 will give 22.0 mSec
    At 20 Mhz with a prescale of 2 and a peload of 10536 will give 22.0 mSec

    http://www.picbasic.co.uk/forum/cont....-PICMultiCalc
    http://www.picbasic.co.uk/forum/show...3259#post23259
    Dave
    Always wear safety glasses while programming.

  6. #6
    Join Date
    Aug 2005
    Location
    NC, USA
    Posts
    53


    Did you find this post helpful? Yes | No

    Default compile errors

    I am not sure if I shoudl reply to this thread or the main interupt thread.

    Anyways, I am getting errors when compiling. It looks like its all with the includes files.

    I have attached a screenshot showing the errors and my code

    Can anyone let me know what I am doing wrong?

    Thanks,
    Charlie
    Attached Files Attached Files

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    The answers are in the errors. They tell you what you need to do.
    DT

  8. #8
    Join Date
    Aug 2005
    Location
    NC, USA
    Posts
    53


    Did you find this post helpful? Yes | No

    Default

    ...perhaps the errors mean something to those who know, but I am not smart enough to know (hence the reason I am for asking for help). A little more guidance would be appreciated. am I suposed to edit pbppic14.lib, if so how and where, its a huge file. Or am I suposed to change the includes file for the PIC16F887?

    Thanks,
    Charlie

  9. #9
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Add ...

    wsave VAR BYTE $70 SYSTEM

    to your program.
    DT

  10. #10
    Join Date
    Aug 2005
    Location
    NC, USA
    Posts
    53


    Did you find this post helpful? Yes | No

    Default

    OK. Thanks, Compiles now and have a blinking LED. Back to the timing... Sorry I am so dense with this.

    How do I go about setting the timer for prescale of 1 and a peload of 21537

    I have been looking at previous posts and the datasheet for the 16f887, but not really sure what I need to do.

    I assume I have to set T1CON and perhaps OPTION_REG

    Also would I be better off using Timer2 since its 8bit (would it be less resources, etc?). As the timer is tripping along, there is no issue with timing of other things like serial commands, I2C timing, etc?

  11. #11
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    http://www.picbasic.co.uk/forum/show...7472#post17472
    Has the example to set the pre-scaler.
    Then in your code for the pre-load.
    Code:
    PreLoad     VAR WORD
    PreLoad =  21537 
    TMR1L = PreLoad.LowByte
    TMR1H = PreLoad.HighByte
    Then in the interrupt routine
    Code:
    TMR1L = PreLoad.LowByte   ' Load the timer with preload value.
    TMR1H = PreLoad.HighByte
    Maybe....
    Dave
    Always wear safety glasses while programming.

  12. #12
    Join Date
    Aug 2005
    Location
    NC, USA
    Posts
    53


    Did you find this post helpful? Yes | No

    Default

    cool. I had it in the begining, did not have it in the interupt. Firing every 22ms on the scope.

    So, this will not mess up anything as far as I2C or serial? or is that dependent on what I do during the interupt? (The final interupt will take about 10-14ms and fire off every 22ms)

  13. #13
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    So, this will not mess up anything as far as I2C or serial? or is that dependent on what I do during the interupt? (The final interupt will take about 10-14ms and fire off every 22ms)
    You need to get in and out of an interrupt routine as quick as possible.
    So if the I2C and serial stuff is handled out side then you should be good.
    Dave
    Always wear safety glasses while programming.

  14. #14
    Join Date
    Aug 2005
    Location
    NC, USA
    Posts
    53


    Did you find this post helpful? Yes | No

    Default

    In order to get in and out quick I will need to use another timer I guess. I need to fire off serries of 8 pulses every 22ms. The high pulses will range from 400us to 1800us with a 400uslow pulse/pause between each one. So I am looking for some advise as to the best approach. Would be the best approach it with a second timer or the same one? I guess if I use the same one I can add up all the small pulses and then wait the difference of 22ms and repeat, but I am not sure if that is as reliable as using two timers, perhaps simpler though. If two timers, should I use timer1 (the 16 bit one for the shorter pulses since their accuracty is more critical than the 22ms) and timer0 or timer2 for the 22ms event. Is there any big deal with changing the preload value for the shorter pulses each time?

    In either approach, can I use a case select inside the interupt routine to remember where I am in the interupt pulse train each time I return, or is there something I have to do to pass variables in and out of the interupt routine.

    Thanks,
    Charlie

  15. #15
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    I probably worded that wrong. Just make sure you finish before the next period and/or leave enough time to do whatever else you need to do.
    Dave
    Always wear safety glasses while programming.

  16. #16
    Join Date
    Aug 2005
    Location
    NC, USA
    Posts
    53


    Did you find this post helpful? Yes | No

    Default

    I have finished puting the original non interupt code into the new program. any reason why PORTB.2 is all of a sudden reading high all the time. I can ground it out with a switch and it will not change state. I when back to the old program and the pin funtions fine, so I assume its something to do with the new interupt, since that is all that has changed, but I can't figure out what. Any suggestions. Thanks

  17. #17
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Just for giggles can you post your current code? Preferably in code tags...
    Dave
    Always wear safety glasses while programming.

  18. #18
    Join Date
    Aug 2005
    Location
    NC, USA
    Posts
    53


    Did you find this post helpful? Yes | No

    Default

    here is the entire front end...

    Code:
    @  __config _CONFIG1, _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_ON & _LVP_OFF & _CP_OFF
    
    OSCCON = $70 'sets the oscillator speed
    DEFINE OSC 8 'Oscillator speed in MHz
    
    'http://www.picbasic.co.uk/forum/showthread.php?t=3251
    INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System
    INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts
    
    PORTA = %00000000 ' output logic at power-up
    PORTB = %00000000 ' output logic at power-up
    PORTC = %00000000 ' output logic at power-up
    PORTD = %00000000 ' output logic at power-up
    PORTE = %00000000 ' output logic at power-up
    
    ' Set up serial UART
    define HSER_RCSTA 90H           ' Set Receive Status and control register
    DEFINE HSER_TXSTA 24H           ' set transmit status and control register
    DEFINE HSER_BAUD 19200          ' baud setting   19200  115200
    define HSER_CLROERR 1           ' reset on serial buffer overflow
    
    ' Define Analog parameters
    ADCON1 = %10000000          'Right Justify
    ANSEL = %11111111           'Analog on for AN0-AN7
    ANSELH = %00000000          'AN8-13 off
    
    Define	ADC_BITS 10 	    ' Set number of bits in result
    Define	ADC_CLOCK 3	        ' Set clock source (3=rc)
    Define	ADC_SAMPLEUS 10	    ' Set sampling time in uS
    
    ' Alias pins  (0=Output, 1=Input)
    L1      VAR PORTC.5 :TRISC.5 = 0
    L2      VAR PORTD.2 :TRISD.2 = 0
    L3      VAR PORTD.1 :TRISD.1 = 0
    L4      VAR PORTD.0 :TRISD.0 = 0
    L5      VAR PORTC.1 :TRISC.1 = 0
    
    Sp      var PORTC.2 :TRISC.2 = 0  'pulsed signal 
    
    S2      var PORTD.5 :TRISD.5 = 1 'mode switch - LCD Select Mode
    S3      var PORTD.4 :TRISD.4 = 1 'mode switch - LCD Light 
    S1      var PORTD.7 :TRISD.7 = 1 'mode switch - Plus 
    S5      var PORTD.6 :TRISD.6 = 1 'mode switch - Minus 
    
    S8      var PORTB.4 :TRISB.4 = 1 'Pelco-D board - Zoom
    S11     var PORTB.5 :TRISB.5 = 1 'Peclo-D board - Zoom
    
    S7      var PORTB.1 :TRISB.1 = 1 'RC board - Mast
    S10     var PORTB.3 :TRISB.3 = 1 'RC board - Mast
    
    S6      var PORTB.2 :TRISB.2 = 1 'Video Select
    
    'Define RAM
    i               var     byte
    j               var     byte
    RC_Mode         var     Bit  'Flag to switch back and forth from arm and drive funtions
    S2_Rel          var     BIT  'flag to see if switch is realsed
    S6_Rel          var     BIT  'flag to see if switch is realsed
    Mode_Debug      var     bit  'Flag for LCD Debug Mode
    Mode_Debug1     var     bit  'Flag for LCD Debug Mode
    LCD_msg         var     byte 'Counter to reset LCD message Display
    wsave           VAR     BYTE $70 SYSTEM 'value required for interupt
    PreLoad         VAR     WORD 'Preload value for timer interupt
    PreLoad =  21537 
    
    JOY1X           var     word    ' Analog Values
    JOY1Y           var     word
    JOY2X           var     word
    JOY2Y           var     word
    P1              var     word
    Battery         var     word    ' Battery voltage analog
    Battery_r       var     word    ' battery voltage remainder
    Batt_div        con     660     ' scaling value to get Volts
    Batt_Alarm      con     480     ' approx 7.2V
    Batt_Stop       con     430     ' approx 6.5V
    Batt_stop1      var     byte
    Batt_beep       var     byte
    Lights_Last     var     BIT
    Video_Mode      var     BYTE
    Video_Changed   VAR     BYTE
    
    JOY1X_Trim      var     Byte 'trim value 128 = neutral trim, 0=-128, 256=128
    JOY1Y_Trim      var     Byte 
    JOY2X_Trim      var     Byte 
    JOY2Y_Trim      var     Byte 
    Temp_Trim       var     BYTE
    
    JOY1X_GainH     con 6  'Gain for High end of stick 50-130% (5-13)
    JOY1X_GainL     con 6  'Gain for Low end of stick 50-130% (5-13)
    JOY1Y_GainH     con 6
    JOY1Y_GainL     con 6
    JOY2X_GainH     con 6
    JOY2X_GainL     con 6
    JOY2Y_GainH     con 6
    JOY2Y_GainL     con 6
    P1_GainH        con 10
    P1_GainL        con 10
    
    JOY1X_Max       con 1400  'pan
    JOY1X_Min       con 800   'pan
    JOY1Y_Max       con 1400  'tilt
    JOY1Y_Min       con 800   'tilt 
    JOY2X_Max       con 1400 
    JOY2X_Min       con 800
    JOY2Y_Max       con 1400
    JOY2Y_Min       con 800
    P1_Max          con 1850  'Aux Tilt
    P1_Min          con 450   'Aux Tilt
    
    Pulse_Start     con     400 '400us - fudge: Pulse Start (high) + chan pulse (low) = Total chan pulse
    chan_adj        con     9 'fudge factor for pulses (used a scope to come up with value)
    Chan_Ctr        con     1100
    Chan1           var     word 'Aile
    Chan2           var     word 'Elev
    Chan3           var     word 'Thro
    Chan4           var     word 'Rudd
    Chan5           var     word 'Gear
    Chan6           var     word 'Aux1
    Chan7           var     word 'Aux2
    Chan8           var     word 'Aux3
    Chan1f          var     word 'Aile
    Chan2f          var     word 'Elev
    Chan3f          var     word 'Thro
    Chan4f          var     word 'Rudd
    Chan5f          var     word 'Gear
    Chan6f          var     word 'Aux1
    Chan7f          var     word 'Aux2
    Chan8f          var     word 'Aux3
    
    'Reverse Bits, Channel , Mode 1 (0=Normal, 1=Reverse)
    Chan1_1R        con     0 'Drive Turn 
    Chan2_1R        con     1 'Drive Speed
    Chan3_1R        con     0 'Camera Tilt
    Chan4_1R        con     0 'Camera Pan
    Chan5_1R        con     1 'Aux Camera Tilt
    
    'LCD Constants
    LCD_CLR         con 88 'clear
    LCD_INSTR       CON 254 'instruction command
    LCD_L           con 71 'move curser to position 71 [column] [row]
    LCD_H           CON 72 'move curser home
    LCD_BL1         con 66 'backlight on, follow by minutes
    LCD_BL0         con 70 'backlight off
    
    ASM
    INT_LIST  macro    ; IntSource, Label, Type, ResetFlag?
            INT_Handler TMR1_INT, _RC_Pulse, PBP, yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    T1CON = %00000001           ; Prescaler = 1:1, TMR1ON
    TMR1L = PreLoad.LowByte
    TMR1H = PreLoad.HighByte    ; preload to give 22mS interrupts (at 1:1)
    
    ' /////////////////////////////////////////////////////////////////////////////
    ' Begin
    ' /////////////////////////////////////////////////////////////////////////////
    
    high l1: pause 50: high l2: pause 50: high l3: pause 50: high l4: pause 50: high l5: pause 50 
    low l1: pause 50: low l2: pause 50: low l3: pause 50: low l4: pause 50: low l5: low 50
    
    'trim values retreived from eeprom
    gosub Sub_Read_EEprom
    
    if JOY1X_Trim = 255 and JOY1Y_Trim = 255 then   'means things are zeroed out (reprogrammed), so set defaults
        High L5: pause 250: low L5
        JOY1X_Trim = 128 
        JOY1Y_Trim = 128 
        JOY2X_Trim = 128 
        JOY2Y_Trim = 128 
        gosub Sub_Write_EEprom
    endif
    
    @ INT_ENABLE  TMR1_INT     ; enable Timer 1 interrupts
    
    ' /////////////////////////////////////////////////////////////////////////////
    ' Main Loop
    ' /////////////////////////////////////////////////////////////////////////////
    mainloop: ' Main program loop

  19. #19
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Code:
    PORTA = %00000000 ' output logic at power-up
    PORTB = %00000000 ' output logic at power-up
    PORTC = %00000000 ' output logic at power-up
    PORTD = %00000000 ' output logic at power-up
    PORTE = %00000000 ' output logic at power-up
    Try setting the TRIS registers here
    TRISA = xxx
    TRISB = xxx
    _ _ _ _ _ _
    Dave
    Always wear safety glasses while programming.

Members who have read this thread : 2

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

Posting Permissions

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