tmr2 interrupt problem


Closed Thread
Results 1 to 28 of 28

Hybrid View

  1. #1
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    i see you use some GOSUBs & Return in your ISR... not a good idea to me...

    Observe the way your program will flow, assuming there's no problem with the use of Gosub and Return (erm), your program will execute all lines.. and finally jump to...
    Code:
            counter = %11111111 'to take care that no segment is blinking harder
            todec = %00000000'todec >> 4 
            gosub segmentsshiftout
            
    segmentsshiftout:
            SHIFTOUT PORTB.0, PORTB.1, LSBFIRST,[counter\8,segments\8]   'data, clock
            pulsout PORTA.4,1        
            return        
    it's kinda dangerous here... once it have execute once the segmentsshiftout sub, it will execute it once again and meet a RETURN without a GOSUB... where the program branch now??? i guess at the begining of your ISR... or.. mmm... resume to your main loop, but as you NEVER EVER clear the interrupt flag, it will automatically jump back to your ISR.

    try to add a GOTO after your last GOSUB segmentsshiftout, which will send it at the end of your ISR...
    Code:
            counter = %11111111 'to take care that no segment is blinking harder
            todec = %00000000'todec >> 4 
            gosub segmentsshiftout
    
    	GOTO RESUME_ISR	' <-- Add this
    	
    segmentsshiftout:
            SHIFTOUT PORTB.0, PORTB.1, LSBFIRST,[counter\8,segments\8]   'data, clock
            pulsout PORTA.4,1        
            return        
    	'
    	'
    	'
    	'
    	'
    RESUME_ISR: ' <-- And this
            TMR2 = RELOAD
            TMR2ON = 1        
            TMR2if=0  ' Clear interrupt flag
    
            resume
            enable
    Last edited by mister_e; - 29th December 2007 at 00:48.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  2. #2
    Join Date
    Dec 2007
    Location
    The Netherlands, Groningen
    Posts
    16


    Did you find this post helpful? Yes | No

    Default

    thanks,

    here s my progress for now:
    First I added the lines you gave me. unfortunatly it didn't work.
    I put somethings at a more logical place(tmr2if=0 at the top of isr)
    Then I replaced all the gosubs by the real text. it cost me for aboud 500 words more but luckily there was enough space at the 628 (i haven't a 648 at stock).
    Then I began thinking aboud the stackadresses. But that was not the option because there was not a gosub at the loop so the only things at the stack had to be the adress for the return after the interrupt and max 1 gosub adress from inside the ISR.

    When I looked at the helpfile I got an idea. It is also possible to place a label after the resume command. I added loop after the resume command and it works for now.

    >>The only problem now is that after the 'resume loop' command I have just 2msec to change my settings:P That is not possible but maby you get now an adea for what I'm doing wrong.

    So, I tried that at the prevous version of the program. This works the same, so with the gosubs inside the ISR.

    Here is my code for now: under the loop didn't I change anything so that is not posted.

    Code:
     @ device pic16F628a, INTRC_OSC_NOCLKOUT
     @ device pic16F628a, MCLR_ON
     @ device pic16F628a, LVP_OFF
     @ device pic16F628a, WDT_OFF
     @ device pic16F628a, PWRT_ON
     @ device pic16F628a, BOD_OFF'ON   
    INCLUDE "modedefs.bas"  'for shiftout
    pause 50
    
    ' Defines 
    ' ---------------- 
    'I2C pins
    DS_SCL VAR PORTA.0 	' I2C clock pin 
    DS_SDA VAR PORTA.1 	' I2C data pin 
    'RTC CON %11010000 	' RTC device address (byte addressing) not needed
    
    'Setting the RTC so we can get out 1Hz tick output 
    '------------------------------------------------- 
    ' -------------- RTC definitions ----------------- 
    SecReg 	CON $00 	' seconds address (00 - 59)
    ' MSB of SecReg must be set to a 0 to enable RTC 
    MinReg CON $01 	    ' minutes address (00 - 59) 
    HourReg CON $02 	' hours address (01 - 12) or (00 - 23) 
    DayReg CON $03 	    ' day address (1 - 7) 
    DateReg CON $04 	' date address (01 - 28/29, 30, 31) 
    MonthReg CON $05 	' month address (01 - 12) 
    YearReg CON $06 	' year address (00 - 99) 
    ContReg CON $07 	' control register 
    RTCflag CON 0 		' RTC flag (location 0 of internal EEPROM) 
    cntrl CON %00010000 ' sets the SQW/OUT to 1Hz pulse, logic level low 
    
    ' The variable below holds the values entered: 
    'menu var's
    _sec 	VAR BYTE ' $00 set seconds 
    _min 	VAR BYTE ' $56 set minutes 
    _hr 	VAR BYTE ' $23 set hour 
    _day 	VAR BYTE ' $06 set day 
    _date 	VAR BYTE ' $28 set date 
    _mon 	VAR BYTE ' $02 set month 
    _yr 	VAR BYTE ' $03 set year 
    
    'rtc var's
    sec 	VAR BYTE ' seconds 
    MINs 	VAR BYTE ' minutes 
    hr 	    VAR BYTE ' hours 
    day 	VAR BYTE ' day 
    date 	VAR BYTE ' date 
    mon 	VAR BYTE ' month 
    yr 	    VAR BYTE ' year 
    
    'button input     
    '-------------------
    	SetButton var PORTa.7	' Press to Set/memorise Button
        DecButton var PORTa.3	' Press to Decrement Button
    	IncButton var PORTa.2	' Press to Increment Button
    
    'other var's
    '------------------
    	CounterA var byte       ' General purpose Variable
    	CounterB var byte       ' General purpose Variable
    	CounterC var byte       ' General purpose Variable
        CounterD var byte       ' General purpose Variable
        ButtonRepeat con 200	' Timeperiod (in mS for Edit Buttons auto-repeat
        			         	' should you want to hold them down...
        RTCCtrl var byte        ' Control
        TimeOut var word        ' Variable for SetUp Menu Time-Out
        SetTime var byte	    ' 12/24 Hour Clock
        RTCWDay var byte	    ' Weekday 
        timeformat var word     ' place for displaying am/pm
        counter var byte
        counter2 var byte
        counter3 var word       ' delaycounter
        counter4 var word       ' counter at redisplayloop
        segments var byte
        myBCD var byte
        toDEC var byte 
        
    'I/O pins
    'port conditions
    '---------------        
            CMCON=7
            TRISA=0
            TRISB=0
            PORTA=0
            PORTB=0
    
    'timer and interruptconditions
    '----------------      
            PIE1 =  %00000010
                    '0------- Disable EE write complete interrupt
                    '-0------ Disable comparator interrupt
                    '--0----- Disable USART receive interrupt
                    '---0---- Disable USART transmit interrupt
                    '----x--- unimplemented
                    '-----0-- Disable CCP1 interrupt
                    '------1- Enable TMR2 to PR2 match interrupt
                    '-------0 Disable TMR1 overflow interrupt
                    
            T2CON = %00000010
                    'X------- Unimplemented
                    '-0000--- postscale 1:1
                    '-----0-- Timer2 off
                    '------10 prescaler 1:16
                                       
            GIE     VAR INTCON.7
            PEIE    VAR INTCON.6
            TMR2IF  VAR PIR1.1
            TMR2ON  VAR T2CON.2
            RELOAD CON 131
            
            ON INTERRUPT GOTO ISR
            TMR2 = RELOAD
            PR2 = 0   ' load period register for 2mSec 
            PEIE = 1    ' Enable peripheral interupt
            GIE = 1     ' enable Global interrupt
            TMR2ON = 1  ' TMR2 ON
            GOTO LOOP                
    
            disable
            ISR:             'interruptroutine
            TMR2if=0  ' Clear interrupt flag        
            TMR2ON=0
    'counter3 to reduce later the isr text. then only shiftout the var's
    if counter3=>200 then 'number of shiftouts
    counter3=0
    else 
    counter3=counter3+1
    endif
    
    'hours
    'the one that is 0 wil blink
    'for segments the opposite
    counter = %01111111     '1 segment
    toDEC = hr
    if hr.6=1 then          '12 uurs mode
        todec = todec <<3
        todec = todec >>7
    else                    '24 uurs mode
        todec = todec <<2
        todec = todec >>6
    endif
    gosub findsegments
    if hr.6 = 1 then        'add in the am/pm indication
        if hr.5 = 1 then
            segments.7 = %1
        endif
    endif
    gosub segmentsshiftout
    
    counter = %10111111 '2 segment
    toDEC = hr
    toDEC = toDEC << 4 'shiftout unusable data
    todec = todec >> 4 'shiftback usable data
    gosub findsegments
    if portA.6 = 1 then segments.7 = %1    'add the blinkin dot
    gosub segmentsshiftout
    
    'minits
    counter = %11011111  '3 segment
    toDEC = MINs
    todec = todec >> 4 'shiftback usable
    gosub findsegments
    gosub segmentsshiftout
    
    counter = %11101111    '4 segment
    toDEC = MINs
    todec = todec << 4 'shiftout unusable data
    todec = todec >> 4  
    gosub findsegments
    gosub segmentsshiftout
    
    'seconds
    counter = %11110111    '5 segment
    toDEC = sec
    todec = todec >> 4 'shiftback usable
    gosub findsegments
    gosub segmentsshiftout
    
    counter = %11111011 '6 segment
    toDEC = sec
    todec = todec << 4 'shiftout unusable data
    todec = todec >> 4 
    gosub findsegments
    
    if hr.6=1 then      'mode indication
    segments.7=%1
    endif
    gosub segmentsshiftout
    
    counter = %11111111 'to take care that no segment is blinking harder
    todec = %00000000'todec >> 4 
    gosub segmentsshiftout
    GOTO RESUME_ISR	' <-- Add this
    
    segmentsshiftout:
    SHIFTOUT PORTB.0, PORTB.1, LSBFIRST,[counter\8,segments\8]   'data, clock
    pulsout PORTA.4,1        
    return        
    
    findsegments:
    if todec=%00000000 then '0
        segments = %01111110
        endif
    if todec=%00000001 then  '1
        segments = %00110000
        endif
    if todec=%00000010 then  '2
        segments = %01101101
        endif
    if todec=%00000011 then  '3
        segments = %01111001
        endif
    if todec=%00000100 then   '4
        segments = %00110011
        endif
    if todec=%00000101 then   '5
        segments = %01011011
        endif
    if todec=%00000110 then   '6
        segments = %01011111
        endif
    if todec=%00000111 then   '7
        segments = %01110000
        endif
    if todec=%00001000 then   '8
        segments = %01111111
        endif
    if todec=%00001001 then   '9
        segments = %01111011
        endif
    return
            RESUME_ISR: ' <-- And this
            TMR2ON=1
            TMR2 = RELOAD
            resume loop
            enable
        
    LOOP:
    I2CRead DS_SDA,DS_SCL,$D0,$00, [sec,MINs,hr,day,date,mon,yr] ' Read Ds1307 
    	If sec.7=1 then goto coldstart	
        If setbutton = 0 then       'if setbutton is pressed
            _hr=hr
            _min=MINs
            _sec=sec
         gosub SetButtonRelease    
         Gosub SetTimeAndDate 'after release    
       endif
    counter3=0
    repeat     'show the segments for 5 times.
    pauseus 10    
    until counter3 > 5
    GoTo Loop 
    end

  3. #3
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Well, believe it or not, and if MPLAB StopWatch don't lie, your ISR need 4.6 mSec to execute... and usually you want to reload the timer before re-starting it.

    Do you have any schematic of your thing and a brief description of what you want to do?
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  4. #4
    Join Date
    Dec 2007
    Location
    The Netherlands, Groningen
    Posts
    16


    Did you find this post helpful? Yes | No

    Default

    Thanks, I didn't know how long the ISR really was.
    Now we know this, there are a couple of possible solutions..
    make the timer longer to 6 or 8 mSec, restart and reload the timer after the ISR or make the ISR less long.

    I tried to restart the timer after the ISR(above post) but that didn't work.. Suprisingly did it work somehow when the end of the ISR was 'resume loop'. Then was the program able to make a I2C-read from the RTC and update the var's.

    So, the first possible solution is to make longer the timer to let's say 8mSec and afther that reduce the length of the ISR and posible to set the timer back to 2mS.

    The ISR is doing a lot of work every time and that is not necessary do execute every time. The lookup for segments is not deeded everytime but can be executed in the program somewhere else and 1 in the 10 times of shiftout is also very acurate(I'm not placing it in a nucear powerplant... ) So the only thing left for the ISR to do is shiftout the segmentsdata.

    I had problems with var's I did change at the mainloop. He didn't update them by the shiftout.

    So, when I place this T2CON = %00000010 is the presale to 1:16 and is the timer about 8mSec, right? Then it have to work anyway?

    about the schematic: a ds1307 is connected to A0 & A1. the two 74HC595 are placed at B0 & B1. The pushbuttons for the menu are at port A2, A3 & A7. All including external pullups. For the 7segmentsdisplays are resistors added. The 7segmentsdisplays are Common Cathode and connected with a BC557C to the GND. The PIC16f628 is working at it's internal oscillator. And a smal capacitor of 0,1uF added from V+ to GND near the IC's. So, it's all very basic and there isn't more to tell about the schematic.

    Can you also measure how long it takes for a I2C-read and write? Because, when I delete it from the mainloop the ISR can use other var's from the loop...
    Last edited by ADCON; - 30th December 2007 at 12:00.

  5. #5
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    To measure how long a single code line or chunk of code need toexecute, you have several method
    1: Scope method
    you Set/Clear an I/O before and after a code chunk, then you measure it with a scope

    2: MPLAB StopWatch
    You set a breakpoint at the end of the code chunk you want to measure, You set the PC at the start of the code chunk, then you click on Run at PC (refer to MPLAB help file)

    3: use a PIC timer
    Same concept as StopWatch but you need to send the results to a LCD or via serial communication. The following link explain it better

    instruction execution time
    http://www.picbasic.co.uk/forum/showthread.php?t=365

    i'll try to figure out what the heck happen here... would be nice if i had those shift register
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  6. #6
    Join Date
    Dec 2007
    Location
    The Netherlands, Groningen
    Posts
    16


    Did you find this post helpful? Yes | No

    Default

    thanks, I use microcodestudio but this is a reason to look for MPlab.
    Microcodestudio sadly don't have a timerfunction. A time ago did I look for MPlab but it looked a lot harder to work with to me.

    The shiftregisters works simple. It is data+clock and when all data is loaded a puls so the latches reset to the new value.
    Maby you do have Proteus VSM? I mean that they have also this registers(haven't a lisence myself). The datasheet is here: http://www.alldatasheet.com/datashee...S/74HC595.html

    The RTC I used is a DS1307 from Maxim-ic.com but that works fine..

  7. #7
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Proteus VSM any sim E+457810214

    sorry not for me.

    Yeah i know those shift register and i know what a shift register is, what i meant is that it would be great if i had them in stock to build the circuit and test it in a real environment.

    I'm not a Sim fan... i know a few people using it for all their design and they seems to be more than happy with it.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

Similar Threads

  1. Problem with Interrupt on PIC18F4620 PORTB
    By rookie in forum Off Topic
    Replies: 1
    Last Post: - 22nd March 2007, 01:34
  2. Problem with PBP interrupt and Serin, please help
    By rgregor in forum mel PIC BASIC
    Replies: 0
    Last Post: - 22nd August 2006, 19:02
  3. Interrupt Problem
    By Kamikaze47 in forum mel PIC BASIC Pro
    Replies: 15
    Last Post: - 16th November 2005, 20:58
  4. Interrupt stack overflow problem with Resume {label}
    By Yuantu Huang in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 3rd May 2005, 01:17
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

Members who have read this thread : 0

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