Help whit tmr1 on pic16f877a


Closed Thread
Results 1 to 16 of 16
  1. #1
    Join Date
    Apr 2012
    Posts
    14

    Unhappy Help whit tmr1 on pic16f877a

    Hi:
    After a long while being away, I finally have the time to continue learning about programming pics, I have started this project and again find myself stuck
    I am trying to make a distance meter using tmr1 of a PIC16f877A using an incremental encoder which it has a circumference wheel of 200mm and 200 pulses/rev. as external clock source, the purpose of this is to measure pieces of tape of the same length, using a word size settable variable to load the tmr1 and on overflow create an interrupt.
    So this is what I find out so far: tmr1 is composed of two 8 bit registers TMR1H and TMR1L and to load a value let´s say 10,000 (ten meters), I´ll have to do 65535-10000= 55535, which is the value I have to load tmr1 with, to cause an interrupt on overflow, but what is really confusing me, is that as I understand, I have to write to TMR1H and TMR1L separately breaking the value in two, and I don’t know how to approach this on the program.
    May be I am getting it wrong, so I´ll greatly appreciate any guidance on this matter

  2. #2
    Join Date
    Feb 2010
    Location
    USA, New England
    Posts
    164


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    Is this what you're looking for?

    wTimerVal var Word

    wTimerVal = 55535
    TMR0H = wTimerVal .highbyte
    TMR0L = wTimerVal .lowbyte
    Best Regards,
    Paul
    Last edited by prstein; - 2nd February 2013 at 04:35. Reason: Forgot to set wTimerVal to 55535...
    The way to avoid mistakes is to gain experience. The way to gain experience is to make mistakes.

  3. #3
    Join Date
    Apr 2012
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    Thanks prstein, yes I think that is it. I will try it and let you know

  4. #4
    Join Date
    Apr 2012
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    Hi there:
    I apologize for taken so long to reply but in between attending a job and a family my time left to do other things is from very slim to none.
    Anyways after messing around with the code I came out with something that works at least on the isis proteus simulator, one thing that I noticed is that when I press the encoder button the tmr1 value increment in more than one unit, but I think that’s because I didn’t put any debouncing time on the code I’ll check that out.
    I going to leave de code and a snapshoot of the circuit for you to look at it and if you will comment about it, but please don´t be to rough on me, since this is my first code for something useful other than blinking leds.
    About the code (this is just part of it) is to be used with an incremental encoder, I mean it only send pulses and not difference which way is turning, it is only to measure distance and to cause an interrupt whenever the set distance has been reached, ahhh and one other thing, does any body can tell me how to increase the count, because the tmr1 only counts up to little more than 65 meters before it overflows, providing than each pulse equals one millimeter

    '************************************************* **************************
    'Name : TAPE MEASURING
    'Author : [Don Luis]
    'Notice : Copyright (c) 2013 [select VIEW...EDITOR OPTIONS]
    'All Rights Reserved
    'Date : 02/02/2013
    'Version : 1.0
    'Notes : PROGRAM CODE TO TEST THE TMR1 OPERATION
    '************************************************* *********************************

    ' FUSES DEFINE
    DEFINE HS_OSC,WDT_OFF,PWRT_ON, BOD_OFF,LVP_OFF,CPD_OFF,WRT_HALF,DEBUG_OFF,PROTECT _OFF

    ' LCD INITIALIZING
    DEFINE OSC 4
    DEFINE LCD_DREG PORTB ' set portb for lcd
    DEFINE LCD_DBIT 4 ' set data bit from 4 to seven
    DEFINE LCD_RSREG PORTB
    DEFINE LCD_RSBIT 2 ' set bit 1 as RS bit
    DEFINE LCD_EREG PORTB
    DEFINE LCD_EBIT 3 ' set bit 2 as enable bit
    DEFINE LCD_BITS 4 ' define number of data bits
    DEFINE LCD_LINES 2 ' define number of lines
    DEFINE LCD_COMMANDUS 2000 ' set time for lcd to start
    DEFINE LCD_DATAUS 50 ' set time for lcd data transfer
    pause 2000

    'INITIALIZING SFR'S
    adcon1= %10001110
    PIE1= %00000001 ' Periferal interrupt enable tmr1
    INTCON= %11000000 ' TMR1 interrupt control off
    on interrupt goto motstop ' Interrupt handdler

    'SETTING TRIS
    trisa= %11110011
    trisb= %00000001
    trisc= %11111111
    trisd= %11110000
    trise= %000

    ' PORT DEFINING
    encoder var portc.0 ' variable for encoder signal input
    motor var porta.3 ' variable for motor control
    brake var porta.2 ' variable for brake control

    ' SETTING VARIABLES
    t1val var word ' set variable to store tmr1 value
    tempo var byte ' set variable for timing pause
    medida var word ' set variable to store required travel distance
    tctval var word ' set variable used to display the actual tmr1 value

    'INITIALIZING VARIABLES
    tempo= 50
    t1val=0
    medida= 10
    tctval= 0

    'INITIALIZING PORTS
    low brake
    low motor

    lcdout $FE,$01 ' clear lcd display line 1
    pause 20 ' small pause to give time to lcd
    lcdout " SYSTEM READDY" ' display introduction message
    pause 5000 ' during 5 seconds

    main:
    t1val=65535-medida ' load tmr1 whith FFFF- the value of medida
    TMR1H = t1val.highbyte
    TMR1L = t1val.lowbyte
    T1CON=%00000111 ' enable tmr1
    high motor ' turn motor on

    rutpal:
    tctval.highbyte= TMR1H
    tctval.lowbyte= TMR1L ' load tctval variable with actual timer value
    if TMR1H=0 & TMR1L=0 then ' this command is used to prevent the program from
    goto main ' going into an endless loop after a return from
    endif ' an interrupt routine
    lcdout $FE,$01 ' clear display line 1
    lcdout "TIMER VALUE" ' display message on line 1
    pause 20 ' pause to give the lcd some time to execute
    lcdout $FE,$C0 ' clear display line 2
    lcdout dec tctval ' display decimal value of tctval on line 2
    pause 100 ' small pause
    goto rutpal ' loop untill a interrupt ocurrs

    disable ' disable all interrupts
    motstop: 'interrupt handler
    low motor ' stop the motor
    high brake ' turn brake on
    pause 2000 ' pause just we can see de led on for a moment
    low brake ' turn brake off
    TMR1H=0 ' clear tmr1
    TMR1L=0
    T1CON=%00000110 ' disable tmr1
    lcdout $FE,$01 ' clear lcd display line 1
    lcdout " CYCLE" ' display message on line 1
    pause 20 ' small pause to give time to the lcd to execute
    lcdout $FE,$C0 ' clear line two of lcd
    lcdout " CONCLUDED" ' display message on line two of lcd
    PIR1.0=0 ' clear flag
    pause 2000 ' two second pause
    resume ' end interrupt routine
    enable ' enable interrupts

    Name:  Dibujo.jpg
Views: 2585
Size:  257.1 KB
    Last edited by DonLuis; - 13th February 2013 at 03:16. Reason: MISSPELING

  5. #5
    Join Date
    Feb 2010
    Location
    USA, New England
    Posts
    164


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    On a good day I am perhaps 10% as good as the regular and reliable people on this forum but I'll do my best...

    A couple of things stand out to me as a little odd.

    Code:
    ' FUSES DEFINE
    DEFINE HS_OSC,WDT_OFF,PWRT_ON, BOD_OFF,LVP_OFF,CPD_OFF,WRT_HALF,DEBUG_OFF,PROTECT _OFF
    Although this compiles I don't think it does anything. Presuming you're using PBP3, it would be something more like
    Code:
    #CONFIG
    __config _CONFIG1, _HS_OSC & _WDT_ON & _LVP_OFF & _CP_OFF  ;etc
    #ENDCONFIG
    See Chapter 4.9 of the PBP3 manual.

    Regarding
    Code:
    if TMR1H=0 & TMR1L=0 then
    When reading a 16-bit timer you should get in the habit of reading the low byte first. And when writing to the timer, write the high byte first. Check the datasheet for why this is so.

    On your schematic, MCLR should be pulled high through a 4.7K (or so) resistor instead of being connected directly to power.

    To increase the count from TMR1 I think you might be able to use a pre-scaler, although there would be a loss of resolution. You could also get clever and figure out how many times the TMR1 interrupt flag would occur.

    Hope this helps...

    Best Regards,
    Paul
    The way to avoid mistakes is to gain experience. The way to gain experience is to make mistakes.

  6. #6
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,615


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    +1 !

    let's add ..

    Code:
    if TMR1H=0 & TMR1L=0 then
    is automatically ( in this case ! ) "marked" by INTCON.2 flag ... because of an interrupt generation.

    but you have a very very very very ... high probability the "if TMR1H=0 & TMR1L=0" test result to be always false ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  7. #7
    Join Date
    Apr 2012
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    Thank you all for your comments and taking the time, I’ll do the recommended corrections and keep working on the code and of course will read de manual.

  8. #8
    Join Date
    Apr 2012
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    Hello guys:
    Continuing with my project, after completing my code which is rather long since include a longitude set up routine, a temperature set up, thermostat routine a 4x4 keyboard and a lcd display interface routine and other control goodies.

    Even though almost everything works as planed I come up to a dead end, it so happens that using the tmr1 to measure the length of the expended foil I have a huge difference between the inputted measure and the one I get.

    Between 2 and 3 times longer and never get the same, let me explain a little, let’s suppose the worst scenario
    The expended roll measures 300mm in diameter (it’ll never get that big) so this is according to my math’s 300x3.1416= 942.48mm, and given that the shaft turns at 150 rpm then 150/60= 2.5 rps. Then 942.48x2.5= 2356mm per second and since every mm equals a pulse gives me a speed of 1/2356= 0.00043 us per mm and using a 4 Mhz xtal that is 1us, almost 400 times the foil speed, so I thought it wasn’t enough time for the pic to process the info, so I went o 8 Mhz, and then 16 Mhz xtal and all ways got the same.
    So I decided to try counting by interrupts using Rb.0 and made a routine for that and I got the same results the only difference is that measures nearly equal, 1mean still 3 times more but with 5mm more or less, I did have a commercial incremental encoder but I don’t know what happen to it, can’t find it, so I make one and it looks like this (well they appear on the bottom)
    I used a regular IR led and opt transistor, turning the roller by hand I can count the 149 pulses per revolution, the output (negative pulse) of the opt transistor is feed to a 74ls14 smith trigger and then (positive pulse) to the pic pin, so I have a doubt if the problem is in the code or in the hardware but I am missing pulses big time, any help on this mater like always be greatly appreciated, also I live some pieces of the code related.


    ‘THIS IS A CODE WITH THE TMR1 INTERRUPT

    DEFINE INTRC_OSC_NOCLKOUT &_HS_OSC & _WDT_OFF & _PWRTE_ON & _BOREN_OFF & _LVP_OFF & _CPD_OFF &_WRT_HALF & _DEBUG_OFF & _CP_OFF

    ' LCD INITIALIZING
    DEFINE OSC 16 ' define oscilator cristal 16 mhz
    DEFINE LCD_DREG PORTB ' set portb for lcd
    DEFINE LCD_DBIT 4 ' set data bit from 4 to seven
    DEFINE LCD_RSREG PORTB
    DEFINE LCD_RSBIT 2 ' set bit 1 as RS bit
    DEFINE LCD_EREG PORTB
    DEFINE LCD_EBIT 3 ' set bit 2 as enable bit
    DEFINE LCD_BITS 4 ' define number of data bits
    DEFINE LCD_LINES 2 ‘define number of lines
    DEFINE LCD_COMMANDUS 2000 ' set time for lcd to start
    DEFINE LCD_DATAUS 50 ' set time for lcd data transfer
    DEFINE ADC_BITS 10 ' define analog register 10 bit word
    DEFINE ADC_CLOCK 3 ' define clock source internal rc clock
    DEFINE ADC_SAMPLEUS 50 ' define adc samplign every 50 ms
    pause 3000 ' pause to initialize lcd

    PIE1= %00000001 ' enable timer1
    INTCON= %11000000 ' enable interrupts
    on interrupt goto motstop ' interrupt handler

    rutpal: ' main routine
    LCDOUT $FE, $01
    pause 20
    lcdout "TEMP " ‘display TEMP suffix on line 1
    LCDOUT $FE,$C0
    LCDOUT "M.U." ‘ display M.U. suffix on line 2
    low l4

    rpal: ‘main loop
    if alcal=0 then gosub nosensor ' check for temperature sensor condition
    adcin 0, calsens ‘ sample sensor
    calsens = 488 * calsens ; 1024*488=499712; ‘ convert to °C
    calsens = DIV32 10
    LCDOUT $FE, $80 +6 ‘ display temperature on line 1
    pause 20
    lcdout DEC calsens DIG 4, DEC calsens DIG 3,DEC calsens DIG 2, ".", DEC calsens DIG 1, $DF,"C", " rp"
    LCDOUT $FE,$C0 +5 ' display used foil length on line 2
    pause 20
    LCDOUT dec contador
    if calsens<= temperatura-200 then high calentador ' if temperature is lower than setting, turn heater on
    if calsens=> temperatura then low calentador ' and if it's higher then turn it off
    button porta.1,0,0,0,boton,1,b1 ' check activation sensor if pressed go to b1
    if c1= 0 then gosub debo ' if the key * was pressed go to debounce routine
    if c1=0 then ‘ if still pressed sound key and go to set temperature
    sound porta.5,[fr,10]
    high l4
    gosub tempajust
    if jo=1 then ‘ on return clear flag and go to main loop
    jo=0
    goto rutpal
    endif
    endif

    if c2= 0 then ' if the key 0 was pressed go to jogging routine
    if jo=1 then ‘ on return clear flag and go to main loop
    jo=0
    goto rutpal
    endif
    endif

    if c3= 0 then gosub debo ' if the key # was pressed go to debounce routine
    if c3=0 then
    sound porta.5,[fr,10] ‘if still pressed sound key and go to set length
    high l4 ‘ on return clear flag and go to main loop
    gosub medajust
    if jo=1 then
    jo=0
    goto rutpal
    endif
    endif

    if c4= 0 then gosub debo ' if the if the key D was pressed go to debounce routine
    if c4=0 then ‘if still pressed sound key and go to clear contador routine
    sound porta.5,[fr,10] ‘ on return clear flag and go to main loop
    high l4
    gosub borrar
    if jo=1 then
    jo=0
    goto rutpal
    endif
    endif
    goto rpal ' loop untill a subroutine is called up


    b1:
    counter= 0 ' routine to prevent program from seizing if sensor is not released
    if porta.1= 1 then
    boton=0
    goto avance
    endif
    if porta.1= 0 then counter= counter +1
    pause 50
    if counter= 50 then rutpal
    goto b1

    avance:
    t1val= 65535 – medida ‘ load tmr1
    TMR1H = t1val.highbyte
    TMR1L = t1val.lowbyte
    T1CON=%00000111 ‘ enable tmr1
    high motor ‘ turn motor on
    goto rutpal ‘ return to main loop

    disable ‘ disable interrupts
    motstop:
    low motor ‘ stop motor
    high brake ‘ turn brake on and wait 300ms
    pause 300
    low brake ‘ turn brake off
    T1CON=%00000110 ‘ disable tmr1
    PIR1.0=0 ‘ clear tmr1 overflow flag
    contador= contador+medida ‘ add contador to previous count and return
    resume
    enable ‘ enable interrupts

    ‘THIS IS A CODE WITH THE RB.O INTERRUPT

    DEFINE INTRC_OSC_NOCLKOUT &_HS_OSC & _WDT_OFF & _PWRTE_ON & _BOREN_OFF & _LVP_OFF & _CPD_OFF &_WRT_HALF & _DEBUG_OFF & _CP_OFF

    ' LCD INITIALIZING
    DEFINE OSC 16 ' define oscilator cristal 16 mhz
    DEFINE LCD_DREG PORTB ' set portb for lcd
    DEFINE LCD_DBIT 4 ' set data bit from 4 to seven
    DEFINE LCD_RSREG PORTB
    DEFINE LCD_RSBIT 2 ' set bit 1 as RS bit
    DEFINE LCD_EREG PORTB
    DEFINE LCD_EBIT 3 ' set bit 2 as enable bit
    DEFINE LCD_BITS 4 ' define number of data bits
    DEFINE LCD_LINES 2 ‘define number of lines
    DEFINE LCD_COMMANDUS 2000 ' set time for lcd to start
    DEFINE LCD_DATAUS 50 ' set time for lcd data transfer
    DEFINE ADC_BITS 10 ' define analog register 10 bit word
    DEFINE ADC_CLOCK 3 ' define clock source internal rc clock
    DEFINE ADC_SAMPLEUS 50 ' define adc samplign every 50 ms
    pause 3000 ' pause to initialize lcd

    INTCON= %10000000 ' enable interrupts
    OPTION_REG.6=1 ‘ define interrupt edge (rising edge)
    on interrupt goto motstop ' interrupt handler

    rutpal: ' main routine
    LCDOUT $FE, $01
    pause 20
    lcdout "TEMP " ‘display TEMP suffix on line 1
    LCDOUT $FE,$C0
    LCDOUT "M.U." ‘ display M.U. suffix on line 2
    low l4

    rpal: ‘main loop
    if alcal=0 then gosub nosensor ' check for temperature sensor condition
    adcin 0, calsens ‘ sample sensor
    calsens = 488 * calsens ; 1024*488=499712; ‘ convert to °C
    calsens = DIV32 10
    LCDOUT $FE, $80 +6 ‘ display temperature on line 1
    pause 20
    lcdout DEC calsens DIG 4, DEC calsens DIG 3,DEC calsens DIG 2, ".", DEC calsens DIG 1, $DF,"C", " rp"
    LCDOUT $FE,$C0 +5 ' display used foil length on line 2
    pause 20
    LCDOUT dec contador
    if calsens<= temperatura-200 then high calentador ' if temperature is lower than setting, turn heater on
    if calsens=> temperatura then low calentador ' and if it's higher then turn it off
    button porta.1,0,0,0,boton,1,b1 ' check activation sensor if pressed go to b1
    if c1= 0 then gosub debo ' if the key * was pressed go to debounce routine
    if c1=0 then ‘ if still pressed sound key and go to set temperature
    sound porta.5,[fr,10]
    high l4
    gosub tempajust
    if jo=1 then ‘ on return clear flag and go to main loop
    jo=0
    goto rutpal
    endif
    endif

    if c2= 0 then ' if the key 0 was pressed go to jogging routine
    if jo=1 then ‘ on return clear flag and go to main loop
    jo=0
    goto rutpal
    endif
    endif

    if c3= 0 then gosub debo ' if the key # was pressed go to debounce routine
    if c3=0 then
    sound porta.5,[fr,10] ‘if still pressed sound key and go to set length
    high l4 ‘ on return clear flag and go to main loop
    gosub medajust
    if jo=1 then
    jo=0
    goto rutpal
    endif
    endif

    if c4= 0 then gosub debo ' if the if the key D was pressed go to debounce routine
    if c4=0 then ‘if still pressed sound key and go to clear contador routine
    sound porta.5,[fr,10] ‘ on return clear flag and go to main loop
    high l4
    gosub borrar
    if jo=1 then
    jo=0
    goto rutpal
    endif
    endif
    goto rpal ' loop untill a subroutine is called up


    b1:
    counter= 0 ' routine to prevent program from seizing if sensor is not released
    if porta.1= 1 then
    boton=0
    goto avance
    endif
    if porta.1= 0 then counter= counter +1
    pause 50
    if counter= 50 then rutpal
    goto b1

    avance:
    INTCON=%10010000 ‘ enable RB.0 interrupts
    high motor ‘start motor
    goto rutpal ‘ return to main loop

    disable ‘ interrupt handler routine, disable interrupts ' disable all interrupts
    motstop:
    counter= counter+1 ‘ increment count by one
    if counter=> medida then ‘ if count matches setting turn motor off
    low motor
    high brake ‘ apply brake and pause 300 ms
    pause 300
    low brake ‘ turn brake off
    contador= contador+ counter ‘ add count to previous count
    counter=0 ‘ clear counter
    INTCON=%10000000 ‘ disable RB.0 interrupts
    else
    INTCON=%10010000 ‘ if no match then enable rb.0 interrupts and return
    endif
    enable

    Name:  ENCODER WHEEL.jpg
Views: 1368
Size:  703.2 KBName:  ESQUEMA.jpg
Views: 1244
Size:  752.1 KB

  9. #9
    Join Date
    Apr 2012
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    Hi, just an update:

    today i tried a code using polling (i think that is called), and i got better results but still not what i need, these es the part of the code i tried:
    avance:
    ban= encoder
    high motor
    av:
    if ban<>encoder then
    ban=encoder
    counter= counter+1
    endif
    if counter= medida then motstop
    goto av

    motstop:
    low motor
    high brake
    pause 300
    low brake
    contador= contador+ counter
    counter=0
    goto rutpal

  10. #10
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    Hello Don Luis,
    IMHO you need assy interrupts, and I recommend you use Darrel's Instant Interrupts. On Interrupt services the interrupt when it gets around to it, given all the things you have going on, you need interrupts that actually interrupt.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  11. #11
    Join Date
    Apr 2012
    Posts
    14


    Did you find this post helpful? Yes | No

    Unhappy Re: Help whit tmr1 on pic16f877a

    Thanks for answering Archangel.

    I don’t know the meaning of IMHO, but I appreciate your comment, now I am terrified to ask, do I have to do the hole code in assy?, I mean I been working on this project for over a year, you know, bumping my head around to get the hang of pbp, even blowing a couple pics and a few other components, I don’t main, there is no rush, just want to see it completed an working as I want to, I do not know anything about assembler, but yet I willing to learn if that is what it takes, on the meaning time I’ll take a look at Darrel’s interrupts.

  12. #12
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    IMHO = In My Humble Opinion, good luck. Funny I don't even use cell phone . . .

    do I have to do the hole code in assy?
    No ooooooo

    Here is a timer1 demo I made tonight for 16F690
    Code:
    @ __CONFIG _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BOR_OFF & _FCMEN_OFF & _IESO_OFF 
    INCLUDE "DT_INTS-14.bas"    ; Darrel Taylors instant interrupts
    DEFINE OSC 4 
    
    ; * * * * * * * * * * * * * Setup Darrel's Instant Interrupts * * * * * * * *
    
    ASM
    INT_LIST  macro   ; IntSource,        Label,  Type, ResetFlag?
            INT_Handler    TMR1_INT,    _Flash,   ASM,  no
        endm
        INT_CREATE               ; Creates the interrupt processor
    ENDASM
    
    @   INT_ENABLE   TMR1_INT     ; enable external (INT) interrupts
    
    ; * * * * * * * * * * * * * Provide system variables to save return address' * * * *
    ;wsave   VAR BYTE    $20     SYSTEM      ; location for W if in bank0
    wsave   VAR BYTE    $70     SYSTEM      ; alternate save location for W 
    ; * * * * * * * * * * * * SETUP DEBUG Parameters * * * * * * * * * * * * *
    DEFINE DEBUG_MODE  0    ' Debug sending True serial data
    DEFINE DEBUG_REG_PORTA  ' Debug Port = PortA as required by PICKIT2 serial Monitor
    DEFINE DEBUG_BIT 0      ' Debug.bit = PortA.0
    DEFINE DEBUG_BAUD 19200  ' Default baud rate = 9600
    DEFINE DEBUGIN_REG PORTA' Debug Port = PortA as required by PICKIT2 serial Monitor 
    DEFINE DEBUGIN_BIT 1    ' Debugin bit PortA.1
    DEFINE DEBUGIN_BAUD 19200' Default baud rate = 9600
    DEFINE DEBUGIN_MODE 0   ' Debugin receiving data true = 0 inverted = 1
    
    ; * * * * * * * * * * * * Setup Timer 1 registers  * * * * * * * * * * *
    
    TMR1IF var PIR1.0       ' Explain to PBP which bit is the T1IF bit 
    INTCON     = %11010000   ; GIE,PEIE,T0IE,INTE set RABIE,T0IF,INTF,RABIF cleared
    PIR1       = %00000000
    PIE1       = %00000001   ;      -,ADIE  ,RCIE ,TXIE ,SSPIE  ,CCP1IE,TMR2IE,TMR1IE
    T1CON      = %01000101   ; T1GINV,TMR1GE,T1CKP,T1CKP,T1OSCEN,T1SYNC,TMR1CS,TMR1ON
    CM2CON1    = %00000000
    
    
    temp     var word
    overFlow var word
    overFlow      = 0
    temp.highbyte = 0
    temp.lowbyte  = 0
    
    main:
       if temp.lowbyte >= 255 then
            temp.highbyte = temp.highbyte +1
            endif
       if temp >= 65535 then
          overFlow = overFlow + 1 ;track number of temp roll overs
       endif
    debug " Temp Var High = ",#temp.highbyte," Temp Var Low = ",#Temp.Lowbyte," ",10
    
    debug "OverFlow = ",#overFlow," temp var ",#temp,10
    
    
    
     goto main
    ; * * * * * * * * * * * * * End of Main Function * * * * * * * * * * * * *
    
    @ INT_DISABLE  TMR1_INT
    Flash:
            if TMR1IF  then       ; Flash is the ISR 
                temp = temp + 1 ; add 1 to timer roll over count
        endif
    TMR1L = 0                   ; preload timer 0 with ? of 255 allows you to set counts until reset
    TMR1H = 0
    TMR1IF = 0                    ; Clear T1 Interrupt flag bit
     
    @  INT_ENABLE  TMR1_INT
    @  INT_RETURN
    All this does is overflow the timer and display the results in PICKit2 USART display. It has Darrel's Instant Interrupts installed so you can pretty much copy paste, then use your registers as required
    Last edited by Archangel; - 23rd July 2013 at 10:00.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

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


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    Hi Don, here my suggestion. If your max encoder count is not bigger of 65535 then you can feed your encoder pulses directly to timer1 input (pin 15 of you 16f877). Timer1 has to be set as a counter using "T1CON = %00000111" and then you have two ways to control your motor.

    1) You poll the timer1 register TMR1H and TMR1L to see when the count reaches the desired value to stop the motor.
    Or
    2) you use DT interrupt (as already suggested) and you just load the count in Timer1 register (you have to load the complement : 65535-desired count) and wait for the overflow. In other words when the count is reached the value of the timer1 counter will be 65535 and adding one pulses it will overflow invocking the interrupt. In this routine (called ISR) you will stop your motor.

    If your needed count is greater then 2^16 it it still possibile to use timer1 as a counter but in this case interrupt is mandatory.

    Cheers

    Al.
    Last edited by aratti; - 23rd July 2013 at 10:38.
    All progress began with an idea

  14. #14
    Join Date
    Apr 2012
    Posts
    14


    Did you find this post helpful? Yes | No

    Red face Re: Help whit tmr1 on pic16f877a

    Hi guys:

    Aratti; I already tried tmr1 interrupt on overflow, as you are suggesting, I explained that, on my post on July 21st, it’s just that seem to take too long to stop the motor and I get much more than I am barging for, sort of speech, also tried external interrupts on RB.0, and lastly polling from what I got much better results if you like to take a look to that post, I even included the code I used for each attempt.

    Archangel; thank you for that, I already took a look to Darrel’s page and downloaded his .bas files and included, them on the PBP folder, (I feel relief now), but I’ll to try this first, since I got everything setup, and due to that I have fairly good results on polling, using the same encoder disc it measures twice de input because it is counting up on every negative and positive pulse, so just finished while ago a disc with 75 slot’s about half the other one, if still no good output then I try Darrel’s code, I’ll let you all know as soon as I get around it.

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


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    I already tried tmr1 interrupt on overflow, as you are suggesting,
    I suggested timer1 overflow with a true interrupt (Darrel Taylor interrupt) your code didn't use any interrupt.

    You can try to use this simple snippet which uses the timer1 as a counter, without interrupt and works pretty well.

    Code:
    False           con 0
    True            con 1
    Z0               Var Byte
    Cnts            var word
    Tape_Len        Var Word
    
    Logic_1         var portXx  ' any available free input
    
    Motor = False
    Brake = False
    TMR1H = 0
    TMR1L = 0
    
    Main_Loop:
    If ????? goto  Load_Tape
    If ????? goto Set_Tape_L
    goto Main_loop
    
    Set_tape_L:
    Tape_Len = XXXXX ' encoder pulses derived from the tape lenght desired
    return
    
    Start_Motor:
    Brake = False
    Motor = True
    Return
    
    Stop_Motor:
    Motor = false
    Brake = True
    Pause 200
    Brake = False
    T1CON.0 = False
    Return
    
    
    Load_Tape:
     Cnts = 0
    TMR1H = 0
    TMR1L = 0
    T1CON.0 = true
    Resume_Halt:
    Lcdout $FE, 1,   "  Press Yy to stop  "
    Lcdout $FE, $C0, "--------------------"
    Lcdout $FE, $94, "Now Loading Tape ..."
    Lcdout $FE, $D4, "Loaded: ",dec Cnts
    
    Gosub Start_Motor
    
    For Z0 = 0 To 100                               ' 100 millisecs delay
    pause 1
    if Logic_1 = True then Hw_Halt                  ' check if emergency stop is activated
    Next Z0
    
    Winding:                                                ' loading start here
    Cnts.highbyte = TMR1H
     Cnts.lowbyte = TMR1L
             If Cnts => Tape_Len then 
             gosub Stop_Motor                           ' if count = lenght desired stop motor
             goto Main_Loop
             End If
       if Logic_1 = True then Hw_Halt                ' If emergency stop key pressed stop motor
    
    Lcdout $FE, $D4, "Loaded: ",dec Cnts            ' display updated count
    goto Winding
    
    Hw_Halt:
    gosub Stop_Motor
    Emergency_menu:
    1) if ????? then goto Resume_Halt
    2) if ????? then goto Main_Loop
    goto Hw_Halt
    
    End
    Naturally you need to complete the code replacing the parts with ?????? and Xx with reference to your hardware setup.

    Cheers

    Al.
    Last edited by aratti; - 25th July 2013 at 15:48.
    All progress began with an idea

  16. #16
    Join Date
    Apr 2012
    Posts
    14


    Did you find this post helpful? Yes | No

    Default Re: Help whit tmr1 on pic16f877a

    Hi guys:

    Well finally SUCCES, with the new encoder disc and using the polling routine that I have, which is similar to the one Aratti suggested (thank you for that).

    I all ways get the inputted length + 18mm exactly and I figured that it is due to the inertia of the motor before the brake applies and doesn’t matter which method I use still have to deal with it, so I made a compensation routine modifiable by the user that it is subtracted to the inputted length before the motor is started and then added to de counter before its value is displayed on the lcd and orale!!! It works like a charm, never de less I started to study assembly language and to begin with I found an eBook named Designing Embedded Systems with Pic Microcontrollers Principles and Applications by Tim Wilmshurst, so I thank you all for your help with this project and hope count with you on the next one.

Similar Threads

  1. Control de puertos PIC16F877A / Port Control PIC16F877A
    By martintorres in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 4th October 2013, 03:49
  2. Tmr1
    By BobSpencerr in forum General
    Replies: 7
    Last Post: - 13th May 2008, 20:19
  3. Replies: 9
    Last Post: - 4th February 2008, 19:12
  4. problem whit pic18f452
    By ocastrillo in forum General
    Replies: 3
    Last Post: - 9th March 2007, 16:18
  5. TMR1 How it works?
    By ngeronikolos in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 12th January 2007, 14:24

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