tmr2 interrupt problem


Closed Thread
Results 1 to 28 of 28

Hybrid View

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


    Did you find this post helpful? Yes | No

    Default

    Dear,

    I still have a problem.

    I have merged all the code and the beginning works fine now.
    It go's to the loop: makes a I2C read.
    Go's to another loop for I2C write(only if needed).

    Then it have to wait for the the interupt.
    At the interrupt is starts to shiftout the data for the display.
    Until here it works fine.

    The problem is: it keeps doing that and NEVER goes back to the loop..

    This didn't I know becose in the testprogram there was noting to do in the loop..

    I can post the code when someone needs it but it's the same as above, only with some onther code inside it.

    Dos anyone know what I do wrong?

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


    Did you find this post helpful? Yes | No

    Default

    ISRs should be keep as short as possible, i feel that what you do inside may need much time than 2mSec?

    If so... you may stop the timer, do your stuff, re-start the timer and clear the interrupt flag.. but yeah you loose all of this needed 2mSec accuracy... even using Darrel's favorite ON INTERRUPT

    Try to reduce your 2mSec to let's say 5-10 mSec
    But that's a feeling. Post your whole code here with the I2C stuff.
    Last edited by mister_e; - 28th December 2007 at 21:24.
    Steve

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

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


    Did you find this post helpful? Yes | No

    Default

    My isr is long, but at 4MHz and no delay instructions it has not to be the problem.
    Well, I tried to set the presale to 1:16. 1:4 had to make a interrupt every 2mSec.
    after that I tried to turn off the timer and after that, turn it back on. All had no effect.
    So, I came back here.

    This is all my code:
    first config, var's and isr
    then main loop
    after that the complete menu
    Much of the code was for a rtc-clock using a lcd. Thats why some of the loops are empty now.

    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
            TMR2ON=0
    'later to use to reduce 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
    
    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
            TMR2 = RELOAD
            TMR2ON = 1        
            TMR2if=0  ' Clear interrupt flag
    
            resume
            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
    
    Segmentswrite2:'write settimevar's to timevar's in bcd
    			CounterA=_hr
    			If SetTime=1 then
    				If CounterA>12 then CounterA=CounterA-12
    				If CounterA=0 then CounterA=12
    				endif
    			Gosub ConvertBCD
    			hr=CounterB
    					' Save the Hours Value
    			If SetTime=1 then
    				hr.6=1
    					' Save the 12 Hour Mode Flag
    				If _hr=>12 then hr.5=1
    					' Save the 'PM' Flag
    				endif
    				'
    				'	Save Minutes
    				'	------------
    			CounterA=_min
    			Gosub ConvertBCD
    			MINs=CounterB
    				'
    				'	Save Seconds
    				'	------------
    			CounterA=_sec
    			Gosub ConvertBCD
    			sec=CounterB
    			'gosub segmentswrite
    return
    
    'paste here the other half of the code
    Last edited by ADCON; - 28th December 2007 at 22:45.

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


    Did you find this post helpful? Yes | No

    Default

    the text wat to long to set in one message


    Code:
    'paste here the above code
    
    SetTimeAndDate: 
    '============= 
    Setup:
        SetTime=hr.6	' Determines 12/24 Hour mode
    	If SetTime=1 then
    				' Regardless of 12/24 options, SetHour always
    				' contains the hours in 24 hour clock format
    				' otherwise there's twice the amount of work
    				' to keep track in the edit routines
    		_hr=(hr>>4)&$01
    				' if 12-hour mode
    		else
    		_hr=(hr>>4)&$03
    				' if 24 hour mode
    		endif
    	_hr=_hr*10+(hr&$0F)
    	If SetTime=1 then
    		If hr.5=1 then
    			If _hr<12 then _hr=hr+12
    				' Add-in the AM/PM indicator
    			else
    			If _hr=12 then _hr=0
    			endif
    		endif
    	_Min=((Mins>>4)&$0F)*10+(Mins&$0F)
    	_Sec=((Sec>>4)&$0F)*10+(sec&$0F)
    	_yr=((yr>>4)&$0F)*10+(yr&$0F)
    	_mon=((mon>>4)&$0F)*10+(mon&$0F)
    	_day=((day>>4)&$0F)*10+(day&$0F)
    		'
    		'	Setup Menu Loop
    		'	---------------
    	CounterC=0		' Set to Start of Setup (seven steps from 0 to 6)
    	TimeOut=0		' Zero the Time-Out counter
    SetupLoop:
    		'
    		'	Now Display the Data
    		'	--------------------
    SetupDisplayLoop:
    			'
    			' 	12/24 Hour Option
    			'	-----------------
    	    '
    		'	The Data-Entry Bit
    		'	------------------
    SetupEntryLoop:         'datainput.
    			'
    			'	Decrement(down) Button Pressed
    			'	------------------------
    	If DecButton=0 then
    				'
    				'	12/24 Clock Selection
    				'	---------------------
    		If CounterC=0 then
    			If SetTime=0 then 
    				SetTime=1
    				else
    				SetTime=0
    				endif
    			endif
    				'
    				'	Decrement Hours
    				'	---------------
    		If CounterC=1 then
                If _hr=0 then
    				_hr=23
    				else
    				_hr=_hr-1
    				endif
    			endif
    				'
    				'	Decrement Minutes
    				'	-----------------
    		If CounterC=2 then
    			If _Min=0 then
    				_Min=59
    				else
    				_Min=_Min-1
    				endif
    			endif
    				'
    				'	Decrement Seconds
    				'	-----------------
    				'	Kinda overkill to include setting seconds,
    				'	but if you got codespace to burn...
    		If CounterC=3 then
    			If _Sec=0 then
    				_Sec=59
    				else
    				_Sec=_Sec-1
    				endif
    			endif
    		gosub Pauseloop
            TimeOut=0
            Goto SetUpDisplayLoop
    		endif
    			'
    			'	Increment(up) Button Pressed
    			'	------------------------
    			' 	This is just like Decrement but opposite...
    	If IncButton=0 then
    				'
    				'	12/24 Clock Selection
    				'	---------------------
    		If CounterC=0 then
    			If SetTime=1 then 
    				SetTime=0
    				else
    				SetTime=1
    				endif
    			endif
    				'
    				'	Increment Hours
    				'	---------------
    		If CounterC=1 then
                If _hr=>23 then
    				_hr=0
    				else
    				_hr=_hr+1
    				endif
    			endif
    				'
    				'	Increment Minutes
    				'	-----------------
    		If CounterC=2 then
    			If _min=>59 then
    				_Min=0
    				else
    				_Min=_Min+1
    				endif
    			endif
    				'
    				'	Increment Seconds
    				'	-----------------
    				'	Kinda overkill to include setting seconds,
    				'	but if you got codespace to burn...
    		If CounterC=3 then
    			If _Sec=>59 then
    				_Sec=0
    				else
    				_Sec=_Sec+1
    				endif
    			endif
    			
    		gosub Pauseloop
            TimeOut=0
    		Goto SetupDisplayLoop
    		endif
    			'
    			'	Set Button Pressed
    			'	------------------
    	If setbutton =0 then
           CounterC=CounterC+1		' Increment Menu Item
    		TimeOut=0
    	endif
    		If CounterC>3 then        'old menu counterC>6#########################
    				' Save Data if all edit items exhaused
    				'
    				'	Save 12/24 Hours to BCD DS1307's Format
    				'	---------------------------------------
    			CounterA=_hr
    			If SetTime=1 then
    				If CounterA>12 then CounterA=CounterA-12
    				If CounterA=0 then CounterA=12
    				endif
    			Gosub ConvertBCD
    			hr=CounterB
    					' Save the Hours Value
    			If SetTime=1 then
    				hr.6=1
    					' Save the 12 Hour Mode Flag
    				If _hr=>12 then hr.5=1
    					' Save the 'PM' Flag
    				endif
    				'
    				'	Save Minutes
    				'	------------
    			CounterA=_min
    			Gosub ConvertBCD
    			MINs=CounterB
    				'
    				'	Save Seconds
    				'	------------
    			CounterA=_sec
    			Gosub ConvertBCD
    			sec=CounterB
    			
    				'
    				'	Do the Business
    				'	---------------
    rtcwrite:
    			I2CWrite DS_SDA, DS_SCL,$D0,$00,[sec,MINs,hr,RTCWDay,day,mon,yr,RTCCtrl]
    			Gosub SetButtonRelease
    			Goto ReDisplay
    			endif
    		Gosub SetButtonRelease
    		Goto SetupLoop	' Loop for Next Menu Item
    		'
    		'	Menu TimeOut Counter
    		'	--------------------
    	gosub Segmentswrite2
    	TimeOut=TimeOut+1        'not jet working good
        If TimeOut>20000 then goto ReDisplay
    				' User paused too long
    				' Return User to Time & Date Display
    				' This will however bounce the User to the original
    				' Setup Menu start point if the DS1307 has not 
    				' been initialised
    	Goto SetupEntryLoop	' Loop for Button Press
    
    Pauseloop: 'some timedelay
    counter3=0
    repeat
        pauseus 10
    until counter3 > 50
    return
    
    'just a routine to make sure you didn't push the button by faulth
    '------------------------------------
    SetButtonRelease: 'delay for button
    	counter3=0
        while setbutton=0
            pauseus 10
        Wend
    	if counter3=>29 then
            repeat
                pauseus 10
            until counter3 > 70
        else 
            goto loop    
        endif
        Return
    
    FindDays:    'deleted
    	Return	
    DisplayMonth:'deleted
    
    DisplaySequence: 'deleted
    	Return
    
    	'
    	'	Subroutine Converts back to BCD
    	'	-------------------------------
    		' CounterA is the entry variable
    		' CounterB holds the converted BCD result on exit
    ConvertBCD:
    	CounterB=CounterA DIG 1
    	CounterB=CounterB<<4
    	CounterB=CounterB+CounterA DIG 0
    	Return
    	
    Redisplay:   'deleted
    return
    
    Am_or_Pm:     'deleted
    return  
    
    coldstart:   'only started when rtc starts from cold
    '--xx--
    _yr=0:_date =0:_mon =0:_day=0:_hr=0:_min=0:_sec=0 
    
    ' The constants below set the RTC to: 16:30:00 on 13-07-2003 
    _yr=$03 
    _mon=$07 
    _date=$13 
    _hr=$16 
    _sec=$00 
    _min=$30 
    I2CWrite DS_SDA, DS_SCL, $D0,$00,[_sec,_min,_hr,_day,_date,_mon,_yr,cntrl] 
    Return
    Last edited by ADCON; - 28th December 2007 at 22:46.

  5. #5
    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.

  6. #6
    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

  7. #7
    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.

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