Searching \ for '[PIC]: PIC12F675 TMR0, TMR1 Interrupt control' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/ints.htm?key=interrupt
Search entire site for: 'PIC12F675 TMR0, TMR1 Interrupt control'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: PIC12F675 TMR0, TMR1 Interrupt control'
2009\07\11@044421 by Heinz Czychun

flavicon
face

--Apple-Mail-4-559188363
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
       charset=US-ASCII;
       delsp=yes;
       format=flowed

Hi,
    I'm having a little problem with controlling Timer 0 and Timer 1  
interrupts separately, on a PIC12F675.

    With Timer 1 disabled I'm able to control Timer 0 effectively  
with the INTCON,T0IE bit. Off and on. But when I enable Timer 1,  
Timer 0 also starts up and starts interrupting the processor.

    Is this normal? Is it a known problem? Or am I missing something?

    While it's not a big deal, it can be handled in the isr. But  
it's a headache to trouble shoot and quite disconcerting when you  
expect only one timer to be in operation, and another that should be  
off, is generating interrupts. I'd like TMR1 to be on, and not have  
TMR0 interrupting thr processor

These are my settings

; initialize interrupts
      banksel  INTCON      ; Bank 0
        movlw  b'10100000'
        ;             1-------  (GIE)1=interrupts enabled
        ;             -0------  (PEIE)1=enable peripheral interrupts
        ;             --1-----  (T0IE)0=disable TMR0 overflow  
interrupt      <- controls TMR0 effectively
        ;             ---0----  (INTE)0=disable GP2/INT external  
interrupt
        ;             ----0---  (GPIE)0=disable GPIO port change  
interrupt
        ;             -----0--  (T0IF)0=no on TMR0 overflow
        ;             ------0-  (INTF)0=no GP2/INT external interrupt
        ;            -------0   (GPIF)0=no GPIO port change
        movwf  INTCON

but when

; enable peripheral interrupts
      banksel  PIE1        ; Bank 1
        movlw  b'00000001'
        ;             0-------   0=disable EE write complete interrupt
        ;             -0------   0=disable A/D converter interrupt
        ;             --xx----   not implemented
        ;             ----0---   0=comparator interrupt disabled
        ;             -----xx-   not implemented
        ;             -------1   (TMR1IE)1=enable TMR1 overflow  
interrupt
        ;                          strangely this seems to also  
turns on timer 0
        movwf  PIE1

; initialize TMR1
      banksel  T1CON       ; Bank 0
        movlw  b'00000101'
        ;             x-------    not implemented
        ;             -0------    0=gate disabled
        ;             --00----   11=1:8 prescaler,
        ;                           10 = 1:4,01 = 1:2,00 = 1:1
        ;              ----0---   (T1OSCEN)0=LP oscillator is off
        ;              -----1--   (T1SYNC) 1=external clock input  
not synchronized
        ;              ------0-   (TMR1CS) 0=internal clock
        ;              -------1   (TMR1ON) 1=timer1 enabled
        movwf  T1CON

; initialize interrupts
      banksel  INTCON      ; Bank 0
        movlw  b'01000000'
        ;             0-------  (GIE)1=interrupts enabled
        ;             -1------  (PEIE)1=enable peripheral interrupts
        ;             --0-----  (T0IE)0=disable TMR0 overflow  
interrupt      <-- TMR0 runs irespective of this
        ;             ---0----  (INTE)0=disable GP2/INT external  
interrupt        bit setting
        ;             ----0---  (GPIE)0=disable GPIO port change  
interrupt
        ;             -----0--  (T0IF)0=no on TMR0 overflow
        ;             ------0-  (INTF)0=no GP2/INT external interrupt
        ;             -------0  (GPIF)0=no GPIO port change
        movwf  INTCON

;
; Clear TMR0, its Flag and enable interrupts
;
    clrf  TMR0               ; start timer known state
;
     bcf  INTCON,T0IF        ; clear TMR0 interrupt flag
     bsf  INTCON,GIE         ; enable global interrupts

    complete code attached.

    T0IE becomes effective again if any of the TMR1 control bits are  
cleared to stopping TMR1.

    I have some PIC12F683s coming so I can see if I have the same  
trouble with them.

Thanks,
Heinz Czychun


--Apple-Mail-4-559188363
Content-Transfer-Encoding: quoted-printable
Content-Type: application/octet-stream; x-unix-mode=0644;
       name=BresClk_T1-iNT.ASM
Content-Disposition: attachment;
       filename=BresClk_T1-iNT.ASM

;**********************************************************************=0D=
=0A;=20=20=20This=20Program=20uses=20Timer0=20to=20set=20both=20the=20hi=20=
and=20low=20period=20of=20a=20=20=20*=0D=0A;=20=20=20square=20wave=20of=20=
fixed=20frequency.=20Thus=20adjusting=20the=20duty=20cycle.=20=20=20=20*=0D=
=0A;=20=20=20The=20duty=20cycle=20is=20based=20on=20the=20ADC=20value=20=
which=20is=20checked=20during=20=20*=0D=0A;=20=20=20the=20longer=20of=20=
the=20two=20periods.=20The=20varying=20voltage=20is=20displayed=20=20=20=
*=0D=0A;=20=20=20as=20a=20differing=20brightness=20level=20of=20the=20=
DS1=20LED=20of=20the=20LPC=20Board.=20=20*=20=20=0D=0A;=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20*=0D=0A=
;**********************************************************************=0D=
=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20*=0D=0A;=20=
=20=20=20Filename:=09=20=20=20=20675-ADC_sPWM.asm=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20*=0D=0A;=20=20=20=20Date:=20=20=20=20=20=20=20=20=20=20May=2028,=20=
2009=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20*=0D=0A;=20=20=20=20File=20=
Version:=20=20Dev=201.0=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20*=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20*=0D=
=0A;=20=20=20=20Author:=20=20=20=20=20=20=20=20Heinz=20Czychun=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20*=0D=0A;=20=20=20=20Company:=20=20=20=20=20=20=20=
N/A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20*=0D=
=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20*=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20*=0D=0A=
;**********************************************************************=0D=
=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20*=0D=0A;=20=
=20=20=20Files=20required:=20p12f675.inc=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20*=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
12F675.lkr=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20*=0D=0A;=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20*=0D=0A;=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20*=0D=0A=
;**********************************************************************=0D=
=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20*=0D=0A;=20=
=20=20=20Notes:=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20*=0D=0A;=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20*=0D=0A=
;**********************************************************************=0D=
=0A=0D=0A=09list=20=20=20=20=20=20p=3D12f675=20=20=20=20=20=20=20=20=20=20=
=20=20;=20list=20directive=20to=20define=20processor=0D=0A=09#include=20=
<p12f675.inc>=20=20=20=20=20=20=20=20;=20processor=20specific=20variable=20=
definitions=0D=0A=0D=0A=09errorlevel=20=20-302=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20;=20suppress=20message=20302=20from=20list=20file=0D=0A=0D=
=0A=09__CONFIG=20=20=20_CP_OFF=20&=20_CPD_OFF=20&=20_BODEN_OFF=20&=20=
_MCLRE_ON=20&=20_WDT_OFF=20&=20_PWRTE_ON=20&=20_INTRC_OSC_NOCLKOUT=20=20=0D=
=0A=0D=0A;=20'__CONFIG'=20directive=20is=20used=20to=20embed=20=
configuration=20word=20within=20.asm=20file.=0D=0A;=20The=20lables=20=
following=20the=20directive=20are=20located=20in=20the=20respective=20=
.inc=20file.=0D=0A;=20See=20data=20sheet=20for=20additional=20=
information=20on=20configuration=20word=20settings.=0D=0A;=0D=0A;=0D=0A;=20=
Config=20Register=0D=0A;=0D=0A;Bits=2013-12=20-=20BandGap=20calibration=20=
-=2000=20Lowest=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20-=2011=20Highest=0D=0A=
;Bits=2011-=209=20-=20Don't=20Care=0D=0A;=0D=0A;Bit=20=20=20=20=20=208=20=
-=20~CPD:=20Data=20Code=20Protection=20=20=20=20=20-=201=20no=20code=20=
protect=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
-=200=20code=20protect=0D=0A;Bit=20=20=20=20=20=207=20-=20~CP:=20=20=
Program=20=20Code=20Protection=20-=201=20no=20code=20protect=0D=0A;=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20-=200=20code=20=
protect=0D=0A;Bit=20=20=20=20=20=206=20-=20BODEN:=20Brown-out=20Detect=20=
=20=20=20=20=20=20=20-=201=20BOD=20on=0D=0A;=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20-=200=20BOD=20off=0D=0A;Bit=20=20=20=20=20=20=
5=20-=20MCLRE:=20GP3/MCLR=20pin=20function=20=20=20-=201=20~MCLRE=20=0D=0A=
;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20-=200=20no=20=
~MCLRE=0D=0A;Bit=20=20=20=20=20=204=20-=20PWRTE:=20Power-up=20Timer=20=20=
=20=20=20=20=20=20=20=20-=201=20no=20Timer=0D=0A;=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20-=200=20yes=20Timer=0D=0A;Bit=20=20=20=20=
=20=203=20-=20WDTE:=20Watchdog=20Timer=20=20=20=20=20=20=20=20=20=20=20-=20=
1=20yes=20Timer=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20-=200=20no=20Timer=0D=0A;Bits=202=20-=200=20-=20FOSC2:FOSC0:=20=
Oscillator=20=20=20=20=20=20=20=0D=0A;=20=20=20=20=20=20=20=20=20=20=20-=20=
111=20RC=20oscillator:=20CLKOUT=20-=20GP4,=20RC=20-=20GP5=0D=0A;=20=20=20=
=20=20=20=20=20=20=20=20-=20110=20RC=20oscillator:=20I/O=20function=20-=20=
GP4,=20Rc=20-=20GP5=20=0D=0A;=20=20=20=20=20=20=20=20=20=20=20-=20101=20=
INTOSC=20oscillator:=20=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20CLKOUT=20function=20-=20GP4,=20I/O=20function=20-=20GP5=20=0D=0A;=20=
=20=20=20=20=20=20=20=20=20=20-=20100=20INTOSC=20oscillator:=20=0D=0A;=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20I/O=20function=20-=20=
GP4,=20I/O=20function=20-=20GP5=20=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=
-=20011=20EC:=20I/O=20function=20-=20GP4,=20CLKIN=20-=20GP5=20=0D=0A;=20=20=
=20=20=20=20=20=20=20=20=20-=20010=20HS=20oscillator:=20=0D=0A;=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20High=20speed=20crystal/resonator-=20=
GP4=20&=20GP5=0D=0A;=20=20=20=20=20=20=20=20=20=20=20-=20001=20XT=20=
oscillator:=20=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
Crystal/resonator=20-=20GP4=20&=20GP5=0D=0A;=20=20=20=20=20=20=20=20=20=20=
=20-=20000=20LP=20oscillator:=20=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20Low=20power=20crystal=20on=20GP4=20&=20GP5=0D=0A;=0D=0A;=20=
CONFIG=20=97=20CONFIGURATION=20WORD=20(ADDRESS:=202007h)=20=0D=0A;=20=
CONFIG=20Setting=20-=200x01FF=0D=0A;=0D=0A;=20Configured=20for=20Code=20=
Protect=20=20=20=20=20=20=20=20off=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20Data=20EEPROM=20Protect=20off=0D=0A;=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20Brownout=20Detect=20=20=20=20=20off=0D=0A;=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20Master=20Clear=20=20=20=20=20=20=20=
=20on=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20Watchdog=20=
Timer=20=20=20=20=20=20off=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20Power-up=20Timer=20=20=20=20=20=20on=0D=0A;=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20Internal=20Oscillator=20on=20with=20I/O=20on=20=
GP4=20&=20GP5=0D=0A;=0D=0A;=20This=20will=20setup=20the=20F675=20to=20=
loose=20only=20three=20pins=0D=0A;=20Vdd=20=20-=20Pin=201=0D=0A;=20Vss=20=
=20-=20Pin=208=0D=0A;=20MClr=20-=20Pin=204=20(J1-2)=0D=0A;=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20___________=0D=0A;=20=20=20=20=20=20=20=20=20=
Vdd=20-|=201=20=20=20=20=208=20|-=20=20Vss=0D=0A;=20=20=20GP5=20T1CKI=20=
-|=20=20=20=20=20=20=20=20=20|-=20=20GP0=20AN0=20CIN+=0D=0A;=20GP4=20AN3=20=
T1G=20-|=20=20=20=20=20=20=20=20=20|-=20=20GP1=20AN1=20CIN=20VREF=0D=0A;=20=
=20=20=20=20=20=20=20MClr=20-|=204=20=20=20=20=205=20|-=20=20GP2=20AN2=20=
T0CKI=20INT=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20-----------=0D=
=0A;=0D=0A;=20Available=20Pins=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20LPC=20J1=20Connector=20=20=20=20=0D=0A;=0D=0A;=20GP0=20(RA0)=20=
-=20Pin=207=20-=20AN0/CIN+=20=20=20=20=20=20=20=20=20J1=20-=20=207=0D=0A=
;=20GP1=20(RA1)=20-=20Pin=206=20-=20AN1/CIN-/VREF=20=20=20=20J1=20-=20=20=
8=0D=0A;=20GP2=20(RA2)=20-=20Pin=205=20-=20AN2/T0CKI/INT=20=20=20=20J1=20=
-=20=209=0D=0A;=20GP4=20(RA4)=20-=20Pin=203=20-=20AN3/T1G=20=20=20=20=20=20=
=20=20=20=20J1=20-=20=202=0D=0A;=20GP5=20(RA5)=20-=20Pin=202=20-=20T1CKI=20=
=20=20=20=20=20=20=20=20=20=20=20J1=20-=20=201=0D=0A;=0D=0A;=20LPC=20=
Board=20Resources=20=20=20=20=20=20=20=20=20=20=20=20=20=20LPC=20J1=20=
Connector=0D=0A;=20Button=20-=20SW1=20(RA3)=20-=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20J1=20-=20=202=0D=0A;=0D=0A;=20LED=20=20=20=20-=20=
DS1=20(RC0)=20-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20J1=20-=20=
10=0D=0A;=20LED=20=20=20=20-=20DS1=20(RC1)=20-=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20J1=20-=2011=0D=0A;=20LED=20=20=20=20-=20DS1=20=
(RC2)=20-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20J1=20-=2012=0D=
=0A;=20LED=20=20=20=20-=20DS1=20(RC3)=20-=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20J1=20-=20=206=0D=0A;=0D=0A;=20Pot=20=20=20=20-=20RP1=20=
(RA0)=20-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20J1=20-=20=20=
7=0D=0A;=0D=0A;=20Hardware=20considerations:=0D=0A;=20On=20the=20LPC=20=
Board=20the=20LEDs=20are=20not=20connected=20to=20the=20pins=20=
associated=0D=0A;=20with=20the=208-pin=20PICs=20so=20the=20DS1=20LED=20=
must=20be=20jumpered=20to=20GP1=20(pin=206)=0D=0A;=20on=20the=2012F675.=20=
This=20is=20done=20at=20connector=20J1=20by=20connecting=20a=20jumper=20=0D=
=0A;=20wire=20between=20J1-8=20(GP1)=20and=20J1-10=20(RC0=20-=20DS1).=20=
Alternatively=20an=20LED=0D=0A;=20with=20a=20series=20resistor=20can=20=
be=20connected=20to=20J1-8.=20Connect=20this=20just=20=0D=0A;=20like=20=
the=20on-board=20LEDs.=0D=0A;=0D=0A;*****=20VARIABLE=20DEFINITIONS=0D=0A=
#define=20=20=20=20=20LED_DS1=201=20=20=20;=20LED=20connected=20to=20GP1=0D=
=0A;=0D=0A;*******=20Macro=20definitions=20=
**********************************=0D=0A;=0D=0AMOVLF=20=20=20macro=20=20=20=
literal,=20dest=0D=0A=20=20=20=20=20=20=20=20movlw=20=20=20literal=0D=0A=20=
=20=20=20=20=20=20=20movwf=20=20=20dest=0D=0A=20=20=20=20=20=20=20=20=
endm=0D=0A;=0D=0A=
;**********************************************************************=0D=
=0A;=20example=20of=20using=20Shared=20Uninitialized=20Data=20Section=0D=0A=
INT_VAR=09=09UDATA_SHR=090x20=20=20=20=0D=0Aw_temp=09=09RES=20=20=20=20=20=
1=09;=20variable=20used=20for=20context=20saving=20=0D=0Astatus_temp=09=
RES=20=20=20=20=201=09;=20variable=20used=20for=20context=20saving=0D=0A=
;=0D=0AsGPIO=20=20=20=20=20=20=20RES=20=20=20=20=201=20=20=20;=20Shadow=20=
Register=20for=20output=20to=20prevent=0D=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20;=20RMW=20errors=0D=0AXorMask=20=
=20=20=20=20RES=20=20=20=20=201=20=20=20;=20Reg=20to=20hold=20LED=20Mask=20=
bit=0D=0A;=0D=0Arlovrflag=20=20=20RES=20=20=20=20=201=20=20=20;=20flag=20=
to=20signal=20main=20loop=20to=201=20sec=20has=20passed=0D=0A;=0D=0A=
bres_hi=09=09RES=20=20=20=20=201=09;=20hi=20byte=20of=20our=2024bit=20=
variable=0D=0Abres_mid=09RES=20=20=20=20=201=09;=20mid=20byte=0D=0A=
bres_lo=09=09RES=20=20=20=20=201=09;=20lo=20byte=0D=0ATemp_mid=20=20=20=20=
RES=20=20=20=20=201=20=20=20;=20Temperary=20reg=20to=20hold=20the=20=
bres_mid=20value=0D=0A;=0D=0A=
;**********************************************************************=0D=
=0ARESET_VECTOR=09CODE=090x000=09;=20processor=20reset=20vector=0D=0A=20=20=
=20=20goto=20=20=20=20main=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
;=20go=20to=20beginning=20of=20program=0D=0A=0D=0AINT_VECTOR=09=20=20=20=20=
CODE=20=20=20=200x004=20=20=20;=20interrupt=20vector=20location=0D=0A=20=20=
=20=20goto=20=20=20=20iServ=0D=0A;=0D=0Amain=0D=0A;=20Start=20PIC_Setup=0D=
=0A;=0D=0A;=20these=20first=204=20instructions=20are=20not=20required=20=
if=20the=20internal=20oscillator=20is=20not=20used=0D=0A;=0D=0A=20=20=20=20=
=20=20=20=20call=20=20=20=200x3FF=20=20=20=20=20=20=20=20=20=20=20=20;=20=
retrieve=20factory=20calibration=20value=0D=0A=20=20=20=20=20=20=20=20=
banksel=20OSCCAL=20=20=20=20=20=20=20=20=20=20=20;=20select=20register=20=
bank=20that=20contains=20=0D=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;=20OSCCAL=20=
(Bank=201)=20=0D=0A=20=20=20=20=20=20=20=20movwf=20=20=20OSCCAL=20=20=20=20=
=20=20=20=20=20=20=20;=20update=20register=20with=20factory=20cal=20=
value=20=0D=0A=0D=0A;=20***=20Control=20Register=20Initialization=20=
***********=0D=0A;=0D=0A;=20set=20up=20direction=20of=20I/O=20pins=0D=0A=20=
=20=20=20=20=20=20=20banksel=20TRISIO=20=20=20=20=20=20;=20Bank=201=0D=0A=
=20=20=20=20=20=20=20=20movlw=20=20=20b'00000001'=20=0D=0A=20=20=20=20=20=
=20=20=20;=20=20=20=20=20=20=20=20=20xx------=20=20not=20implemented=0D=0A=
=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20--0-----=20=20=
0=3Doutput,=20GP5,=20=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=
=20=20---0----=20=200=3Doutput,=20GP4,=20=0D=0A=20=20=20=20=20=20=20=20;=20=
=20=20=20=20=20=20=20=20----x---=20=20not=20used,=20GP3,=20In=20this=20=
case=20used=20by=20MCLR=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=
=20=20-----0--=20=200=3Doutput,=20GP2,=20=0D=0A=20=20=20=20=20=20=20=20;=20=
=20=20=20=20=20=20=20=20------0-=20=200=3Doutput,=20GP1,=20=0D=0A=20=20=20=
=20=20=20=20=20;=20=20=20=20=20=20=20=20=20-------1=20=201=3Dinput=20for=20=
analog=20input=0D=0A=20=20=20=20=20=20=20=20;=0D=0A=20=20=20=20=20=20=20=20=
movwf=20=20=20TRISIO=0D=0A;=0D=0A;=20set=20up=20Option=20Register=0D=0A=20=
=20=20=20=20=20=20=20clrwdt=09=09=20=20=20=20;clear=20WDT=20prep=20=
prescale=20assign=0D=0A=20=20=20=20=20=20=20=20banksel=20=20OPTION_REG=20=
;=20Bank=201=0D=0A=20=20=20=20=20=20=20=20movlw=20=20=20b'00001000'=20=20=
=20=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=200-------=20=20=
1=3Ddisabled,=20no=20GPIO=20Pull-ups=20=20=20=20=20GPPU:=20GPIO=20=
Pull-ups=20=20=20=20=20=20=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=
=20=20=20-0------=20=200=3Dfalling=20edge=20interrupt,=20=20=20=20=20=20=
INTEDG:=20Interrupt=20Edge=20of=20GP2=0D=0A=20=20=20=20=20=20=20=20;=20=20=
=20=20=20=20=20=20=20--0-----=20=200=3DInternal=20inst=20clock=20=
(CLKOUT),=20=20T0CS:=20TMR0=20Clock=20Source=0D=0A=20=20=20=20=20=20=20=20=
;=20=20=20=20=20=20=20=20=20---0----=20=200=3DInc=20on=20lo^hi=20=
transition=20on=20GP2,T0SE:=20TMR0=20Source=20Edge=0D=0A=20=20=20=20=20=20=
=20=20;=20=20=20=20=20=20=20=20=20----1---=20=201=3DPrescaler=20assigned=20=
to=20WDT,=20=20=20=20=20PSA:=20Prescaler=20Assignment=0D=0A=20=20=20=20=20=
=20=20=20;=20=20=20=20=20=20=20=20=20-----0--=20=20001=20Prescaler=20=
1:4,=20=20=20=20=20=20=20=20=20=20=20=20PS2-PS0:=20Prescaler=20Rate=0D=0A=
=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20------0-=20=20Bits=20=
=20TMR0=20=20=20=20WDT=20=20=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=
=20=20=20=20-------0=20=20000=20=20=20=201:2=20=20=20=201:1=0D=0A=20=20=20=
=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
001=20=20=20=201:4=20=20=20=201:2=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20010=20=20=20=201:8=20=20=20=
=201:4=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20011=20=20=20=201:16=20=20=201:8=0D=0A=20=20=20=20=20=
=20=20=20;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20100=20=
=20=20=201:32=20=20=201:16=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20101=20=20=20=201:64=20=20=201:32=0D=
=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20110=20=20=20=201:128=20=201:64=0D=0A=20=20=20=20=20=20=20=20=
;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20111=20=20=20=20=
1:256=20=201:128=0D=0A=20=20=20=20=20=20=20=20;=0D=0A=20=20=20=20=20=20=20=
=20movwf=20=20=20=20OPTION_REG=20=20=20=20=20=20=20=20=20=20=20=20=20=20=0D=
=0A;=0D=0A;=20set=20up=20comparator=0D=0A=20=20=20=20=20=20=20=20banksel=20=
CMCON=20=20=20=20=20=20=20;=20Bank=200=0D=0A=20=20=20=20=20=20=20=20=
movlw=20=20=20b'00000111'=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=
=20=20=20x-------=20=20not=20implemented=0D=0A=20=20=20=20=20=20=20=20;=20=
=20=20=20=20=20=20=20=20-0------=20=20output=20bit=0D=0A=20=20=20=20=20=20=
=20=20;=20=20=20=20=20=20=20=20=20--x-----=20=20not=20implemented=0D=0A=20=
=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20---0----=20=20=
0=3Dnon-inverted=20output=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=
=20=20=20----0---=20=200=3DVin-=20to=20Cin-=0D=0A=20=20=20=20=20=20=20=20=
;=20=20=20=20=20=20=20=20=20-----111=20=20111=3Dcomparator=20off=0D=0A=20=
=20=20=20=20=20=20=20movwf=20=20=20CMCON=0D=0A;=0D=0A;=20set=20up=20A/D=20=
converter=0D=0A=20=20=20=20=20=20=20=20banksel=20ANSEL=20=20=20=20=20=20=20=
;=20Bank=201=0D=0A=20=20=20=20=20=20=20=20movlw=20=20=20b'00010000'=0D=0A=
=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20x-------=20=20not=20=
implemented=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=
-001----=20=20001=3DFocs/8=20Conversion=20Clock=0D=0A=20=20=20=20=20=20=20=
=20;=20=20=20=20=20=20=20=20=20----0---=20=200=3Ddigital=20I/O,=20GP4,=20=
not=20used=20by=20ADC=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=
=20=20-----0--=20=200=3Ddigital=20I/O,=20GP2,=20not=20used=20by=20ADC=0D=0A=
=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20------0-=20=20=
0=3Ddigital=20I/O,=20GP1,=20not=20used=20by=20ADC=0D=0A=20=20=20=20=20=20=
=20=20;=20=20=20=20=20=20=20=20=20-------0=20=201=3Danalog=20=20I/O,=20=
GP0,=20analog=20input=0D=0A=20=20=20=20=20=20=20=20movwf=20=20=20ANSEL=0D=
=0A;=20=20=20=20=20=20=20=20=0D=0A=20=20=20=20=20=20=20=20banksel=20=
ADCON0=20=20=20=20=20=20;=20Bank=200=0D=0A=20=20=20=20=20=20=20=20movlw=20=
=20=20b'00000000'=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=
0-------=20=200=3Dleft=20justified=20result=0D=0A=20=20=20=20=20=20=20=20=
;=20=20=20=20=20=20=20=20=20-0------=20=200=3DVdd=20is=20voltage=20=
reference=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=
--xx----=20=20not=20implemented=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=
=20=20=20=20=20----00--=20=2000=3Dselect=20channel=200=20(GP0)=0D=0A=20=20=
=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20------0-=20=200=3DA/D=20=
conversion=20not=20started=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=
=20=20=20-------0=20=200=3DA/D=20converter=20module=20is=20in=20=
operation=0D=0A=20=20=20=20=20=20=20=20movwf=20=20=20ADCON0=0D=0A;=0D=0A=
;=20initialize=20output=20pins=0D=0A=20=20=20=20=20=20=20=20banksel=20=
GPIO=20=20=20=20=20=20=20=20;=20Bank=200=0D=0A=20=20=20=20=20=20=20=20=
movlw=20=20=20b'00000000'=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=
=20=20=20xx------=20=20not=20implemented=0D=0A=20=20=20=20=20=20=20=20;=20=
=20=20=20=20=20=20=20=20--0-----=20=200=3Doutput=20low,=20GP5,=20=20=20=20=
=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20---0----=20=20=
0=3Doutput=20low,=20GP4,=20=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=
=20=20=20=20----x---=20=200=3Doutput,=20GP3,=20In=20this=20case=20used=20=
by=20MCLR=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=
-----0--=20=200=3Doutput=20low,=20GP2,=20=0D=0A=20=20=20=20=20=20=20=20;=20=
=20=20=20=20=20=20=20=20------0-=20=200=3Doutput=20low,=20GP1,=20=0D=0A=20=
=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20-------0=20=200=3Doutput=20=
doesn't=20matter=20as=20GP0,=20is=20an=20input=0D=0A=20=20=20=20=20=20=20=
=20movwf=20=20=20GPIO=0D=0A;=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=0D=0A;=20initialize=20interrupts=0D=0A;=20=20=20=20=20=20=20banksel=20=
INTCON=20=20=20=20=20=20;=20Both=20Banks=0D=0A=20=20=20=20=20=20=20=20=
movlw=20=20=20b'11000000'=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=
=20=20=201-------=20=201=3Dinterrupts=20enabled=0D=0A=20=20=20=20=20=20=20=
=20;=20=20=20=20=20=20=20=20=20-1------=20=201=3Denable=20peripheral=20=
interrupts=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=
--0-----=20=200=3Ddisable=20TMR0=20overflow=20interrupt=0D=0A=20=20=20=20=
=20=20=20=20;=20=20=20=20=20=20=20=20=20---0----=20=200=3Ddisable=20=
GP2/INT=20external=20interrupt=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=
=20=20=20=20=20----0---=20=200=3Ddisable=20GPIO=20port=20change=20=
interrupt=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=
-----0--=20=200=3Dno=20on=20TMR0=20overflow=20(TM0IF)=0D=0A=20=20=20=20=20=
=20=20=20;=20=20=20=20=20=20=20=20=20------0-=20=200=3Dno=20GP2/INT=20=
external=20interrupt=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=
=20-------0=20=200=3Dno=20GPIO=20port=20change=0D=0A=20=20=20=20=20=20=20=
=20movwf=20=20=20INTCON=0D=0A;=20=20=20=20=0D=0A=20=20=20=20=20=20=20=20=
banksel=20PIE1=20=20=20=20=20=20=20=20;=20Bank=201=0D=0A=20=20=20=20=20=20=
=20=20movlw=20=20=20b'00000001'=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=
=20=20=20=20=200-------=20=200=3Ddisable=20EE=20write=20complete=20=
interrupt=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=
-0------=20=200=3Ddisable=20A/D=20converter=20interrupt=0D=0A=20=20=20=20=
=20=20=20=20;=20=20=20=20=20=20=20=20=20--xx----=20=20not=20implemented=0D=
=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20----0---=20=20=
0=3Dcomparator=20interrupt=20disabled=0D=0A=20=20=20=20=20=20=20=20;=20=20=
=20=20=20=20=20=20=20-----xx-=20=20not=20implemented=0D=0A=20=20=20=20=20=
=20=20=20;=20=20=20=20=20=20=20=20=20-------1=20=200=3Denable=20TMR1=20=
overflow=20interrupt=0D=0A=20=20=20=20=20=20=20=20movwf=20=20=20PIE1=0D=0A=
;=20=20=20=20=20=20=20=20=0D=0A=20=20=20=20=20=20=20=20banksel=20PIR1=20=20=
=20=20=20=20=20;=20Bank=200=0D=0A=20=20=20=20=20=20=20=20movlw=20=20=20=
b'01000000'=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=
0-------=200=3Dno=20EE=20write=20complete=0D=0A=20=20=20=20=20=20=20=20;=20=
=20=20=20=20=20=20=20=20-1------=201=3Dyes=20A/D=20conversion=20complete=0D=
=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20--xx----=20not=20=
implemented=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=
----0---=200=3Dno=20comparator=20interrupt=0D=0A=20=20=20=20=20=20=20=20=
;=20=20=20=20=20=20=20=20=20-----xx-=20not=20implemented=0D=0A=20=20=20=20=
=20=20=20=20;=20=20=20=20=20=20=20=20=20-------0=200=3Dno=20TMR1=20=
overflow=20()TMR1F=0D=0A=20=20=20=20=20=20=20=20movwf=20=20=20PIR1=0D=0A=
;=0D=0A;=20initialize=20TMR1=0D=0A=20=20=20=20=20=20=20=20banksel=20=
T1CON=20=20=20=20=20=20=20;=20Bank=200=0D=0A=20=20=20=20=20=20=20=20=
movlw=20=20=20b'00000001'=20=20=20=20=0D=0A=20=20=20=20=20=20=20=20;=20=20=
=20=20=20=20=20=20=20x-------=20=20not=20implemented=0D=0A=20=20=20=20=20=
=20=20=20;=20=20=20=20=20=20=20=20=20-0------=20=200=3Dgate=20disabled=0D=
=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20--00----=20=20=
11=3D1:8=20prescaler,=20=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=2010=20=3D=201:4,01=20=3D=201:2,00=20=
=3D=201:1=20=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=20=
----0---=20=200=3DLP=20oscillator=20is=20off=0D=0A=20=20=20=20=20=20=20=20=
;=20=20=20=20=20=20=20=20=20-----0--=20=201=3Dexternal=20clock=20input=20=
not=20synchronized=0D=0A=20=20=20=20=20=20=20=20;=20=20=20=20=20=20=20=20=
=20------0-=20=200=3Dinternal=20clock=0D=0A=20=20=20=20=20=20=20=20;=20=20=
=20=20=20=20=20=20=20-------1=20=201=3Dtimer=20enabled=0D=0A=20=20=20=20=20=
=20=20=20movwf=20=20=20T1CON=0D=0A;=0D=0A;=20PIC=20Register=20Setup=20=
complete=0D=0A=
;_________________________________________________________________________=
_________=0D=0A;=0D=0A=20=20=20=20bsf=20=20XorMask,=20LED_DS1=0D=0A=20=20=
=20=20bsf=20=20GPIO,=20LED_DS1=20=20=20=20;=20start=20with=20LED-DS1=20=
off=0D=0A;=0D=0A;=20Setup=20for=20TMR0=20and=20enable=20interrupts=0D=0A=
;=0D=0A;=20=20=20=20clrf=20=20=20=20TMR0=20=20=20=20=20=20=20=20;=20=
start=20timer=20known=20state=0D=0A;=0D=0A=20=20=20=20bcf=09=20=
INTCON,T0IF=20;=20clear=20TMR0=20interrupt=20flag=0D=0A;=0D=0AMainLoop:=0D=
=0A=0D=0A=20=20=20=20goto=20=20=20=20MainLoop=20=20=20=20;=20go=20back=20=
and=20get=20a=20knew=20ADC=20value=0D=0A;=0D=0A;=20End=20of=20Main=0D=0A=
;_________________________________________________________________________=
_________=0D=0A;=0D=0A;=20Control=20is=20here=20because=20Timer0=20has=20=
rolled=20over=0D=0A;=0D=0AiServ=0D=0A=20=20=20=20movwf=20=20=20w_temp=20=20=
=20=20=20=20=20=20=20=20;=20save=20off=20current=20W=20register=20=
contents=0D=0A=20=20=20=20movf=20=20=20=20STATUS,w=20=20=20=20=20=20=20=20=
;=20move=20status=20register=20into=20W=20register=0D=0A=20=20=20=20=
movwf=20=20=20status_temp=20=20=20=20=20;=20save=20off=20contents=20of=20=
STATUS=20register=0D=0A;=0D=0A=20=20=20=20=20=20bcf=20=20=20INTCON,GIE=0D=
=0A;=0D=0A=20=20=20=20=20btfsc=20=20INTCON,T0IF=0D=0A=20=20=20=20=20=20=
goto=20=20ServiceTimer0=0D=0A=20=20=20=20=20btfsc=20=20PIR1,T1IF=20=20=20=
=20=20=0D=0A=20=20=20=20=20=20goto=20=20ServiceTimer1=0D=0A=0D=0A=20=20=20=
=20=20=20goto=20=20iServ_Exit=0D=0A;=0D=0AServiceTimer1=0D=0A=20=20=20=
banksel=20=20PIR1=0D=0A=09=20=20=20bcf=20=20PIR1,T1IF=09=09;=20clear=20=
TMR1=20interrupt=20flag=0D=0A;=0D=0A;=20=20=20=20=20movlw=20'>'=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=0D=0A;=09=20movwf=20serdata=20=20=20=20=
=20=20=20=20=20=20=20=20=20=0D=0A;=09=20=20call=20serxmt=0D=0A;=0D=0A=09=
;-------------------------------------------------=0D=0A=09;=20Note!=20=
we=20get=20here=20every=2065,536=20instructions,=20we=0D=0A=09;=20can=20=
now=20do=20our=20special=20one=20second=20timing=20system.=09=09=09=09=0D=
=0A=0D=0A=09;=20This=20consists=20of=20three=20main=20steps;=0D=0A=09;=20=
*=20subtract=2065,536=20counts=20from=20our=2024bit=20variable=0D=0A=09;=20=
*=20test=20if=20we=20reached=20the=20setpoint=20(high=20byte=20=3D=200)=0D=
=0A=09;=20*=20if=20so,=20add=201,000,000=20counts=20to=2024bit=20=
variable=20and=20generate=20event.=0D=0A=20=20=20=20;=20*=20assuming=20=
an=204MHz=20clock,=20and=20TMR1=20no=20prescaler,=20ticks=20every=204=20=
Osc=20clocks=0D=0A=20=20=20=20;=20*=201MHz=20operation=0D=0A=09=
;-------------------------------------------------=0D=0A=20=20banksel=20=20=
bres_hi=0D=0A=20=20=20decfsz=20=20bres_hi,f=20=20=20=20=20=20=20=20=20=20=
;=20decrement=20bresenham=20counter=20high=20byte=0D=0A=20=20=20=20=20=
goto=20=20iServ_Exit=20=20=20=20=20=20=20=20=20;=20lf=20non-zero=20exit=20=
isr=0D=0A=0D=0A;=20since=20bres_hi=20is=200=0D=0A;=20so=20a=20sec=20=
elapsed,=20more=20or=20less=0D=0A;=20add=201M=20(0F=2042=2040=20in=20=
hex)to=20bresenham=20accumulator=0D=0A;=0D=0A=20=20=20=20MOVLF=20=200F,=20=
bres_hi=20=20=20=20=20=20=20=20;=20move=20hign=20value=20into=20=
bres-accu=0D=0A=20=20=20=20MOVLF=20=2042,=20Temp_mid=20=20=20=20=20=20=20=
;=20need=20to=20hold=20mid=20count=20in=20a=20temp=20register=0D=0A;=20=
do=20the=20addition=0D=0A=20=20=20=20=20=20bcf=20=20STATUS,=20C=20=20=20=20=
=20=20=20=20=20=20;=20clear=20carry=20flag=0D=0A=20=20=20=20movlw=20=20=
0x40=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;=20get=20low=20value=0D=
=0A=20=20=20=20addwf=20=20bres_lo,=20f=20=20=20=20=20=20=20=20=20;=20add=20=
low=20count=20to=20bres-accu=20low=0D=0A=20=20=20=20skpnc=0D=0A=20=20=20=20=
incf=20=20=20Temp_mid,=20f=20=20=20=20=20=20=20=20;=20if=20overflow=20=
add=201=20to=20counter=20mid=0D=0A=20=20=20=20movf=20=20=20Temp_mid,=20w=20=
=20=20=20=20=20=20=20;=20else=20just=20get=20counter=20mid=0D=0A=20=20=20=
=20addwf=20=20bres_mid,f=20=20=20=20=20=20=20=20=20;=20add=20to=20=
bres-accu=20mid=0D=0A=20=20=20=20skpnc=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20;=20=0D=0A=20=20=20=20incf=20=20=20bres_hi,f=20=
=20=20=20=20=20=20=20=20=20;=20if=20overflow=20add=201=20to=20bres-accu=20=
hi=0D=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20;=20do=201=20sec=20stuff=20here=0D=0A=09=
;-------------------------=0D=0A=09=09=09=09=20=20=20=20=20=20=20=20;=20=
now=20we=20do=20the=20"event"=20that=20we=20do=20every=20one=20second.=0D=
=0A=09=09=09=09=20=20=20=20=20=20=20=20;=20Add=20your=20own=20code=20=
here=20for=20your=20one=20second=20event.=0D=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;=0D=0A=20=20=20=20=20=20=
movf=20XorMask,w=20=20=20=20=20=20=20;=20get=20LED=20Mask=0D=0A=20=20=20=20=
=20xorwf=20GPIO,f=20=20=20=20=20=20=20=20=20=20;=20xor=20(toggle)=20LED=20=
bit=20&=20move=20to=20shadow=20reg=0D=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;=20move=20to=20GPIO=20=
and=20out=20to=20LED=0D=0A=20=20=20=20;=0D=0A=20=20=20=20=20movlw=20=20=
0x01=09=09=20=20=20;=20set=20rollover=20flag=0D=0A=20=20=20=20=20movwf=20=
=20rlovrflag=0D=0A=09;=0D=0A=09=
;-------------------------------------------------=0D=0A=09;=20now=20our=20=
one=20second=20event=20is=20all=20done,=20we=20can=20exit=20the=0D=0A=09=
;=20interrupt=20handler.=0D=0A=09=
;-------------------------------------------------=0D=0A=09=20=20goto=20=20=
iServ_Exit=20=20=20=09=09=09=20=20=20=20=20=20=20=20=0D=0A;=0D=0A=
ServiceTimer0=0D=0A;=20just=20clear=20TMRO=20int=20flag=0D=0A;=0D=0A=20=20=
=20=20=20=20=20bcf=20INTCON,T0IF=0D=0A;=0D=0A;=20=20=20=20=20movlw=20'T'=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=0D=0A;=09=20movwf=20serdata=20=
=20=20=20=20=20=20=20=20=20=20=20=20=0D=0A;=09=20=20call=20serxmt=0D=0A;=0D=
=0AiServ_Exit=0D=0A;=20=20=20=20bcf=20=20=20=20=20INTCON,T0IF=20=20=20=20=
=20;=20flag=20must=20be=20cleared=20in=20software=0D=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;=20=
ready=20for=20next=20inerrupt=0D=0A;=20context=20saving=20is=20not=20=
necessary=20with=20this=20program=0D=0A;=0D=0A=20=20=20=20movf=20=20=20=20=
status_temp,w=20=20=20=20;=20retrieve=20copy=20of=20STATUS=20register=0D=0A=
=20=20=20=20movwf=20=20=20STATUS=20=20=20=20=20=20=20=20=20=20=20;=20=
restore=20pre-isr=20STATUS=20register=20contents=0D=0A=20=20=20=20swapf=20=
=20=20w_temp,f=0D=0A=20=20=20=20swapf=20=20=20w_temp,w=20=20=20=20=20=20=20=
=20=20;=20restore=20pre-isr=20W=20register=20contents=0D=0A;=0D=0A=20=20=20=
=20retfie=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20;=20=
return=20from=20interrupt=0D=0A;=0D=0A;=20End=20of=20Interrupt=20Service=20=
Routine=0D=0A=
;_________________________________________________________________________=
_________=0D=0A;=0D=0A=20=20=20=20END=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20;=20directive=20'end=20of=20program'=0D=0A=0D=0A=0D=0A=0D=0A=

--Apple-Mail-4-559188363
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
       charset=US-ASCII;
       format=flowed





--Apple-Mail-4-559188363
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

2009\07\11@053124 by Justin Richards

face picon face
Hi Heinz,

my knowledge here is limited to beginner hobbyist so treat my comments
accordingly.

My experience has been I can disable tmr0 and use timer1.

I am curious why you clear the int flag if you dont want to use it.

; Setup for TMR0 and enable interrupts
;
;    clrf    TMR0        ; start timer known state
;
   bcf     INTCON,T0IF ; clear TMR0 interrupt flag
;

Cheers Justin


2009/7/11 Heinz Czychun <spam_OUThczychunTakeThisOuTspamlks.net>

{Quote hidden}

> -

2009\07\11@060951 by Rikard Bosnjakovic

picon face
On Sat, Jul 11, 2009 at 10:44, Heinz Czychun<.....hczychunKILLspamspam@spam@lks.net> wrote:

> But when I enable Timer 1, Timer 0 also starts
> up and starts interrupting the processor.

Timer0 cannot be turned off until you put the processor to sleep,
which you don't do in your code. However, I have never heard of a case
where T0IE being enabled when Timer1 is started.

In your code:

   bcf         INTCON,T0IF ; clear TMR0 interrupt flag
MainLoop:
   goto    MainLoop    ; go back and get a knew ADC value

just before the bcf, try adding a "bcf INTCON, T0IE" as well and see
if that helps. I'm aware you clear the IE earlier, but clearing it
again won't hurt.


--
- Rikard - http://bos.hack.org/cv/

2009\07\11@061257 by Jinx

face picon face
> ; initialize interrupts
>        banksel  INTCON      ; Bank 0
>          movlw  b'10100000'
>          ;             1-------  (GIE)1=interrupts enabled
>          ;             -0------  (PEIE)1=enable peripheral interrupts
>          ;             --1-----  (T0IE)0=disable TMR0 overflow  
> interrupt      <- controls TMR0 effectively

Heinz,

INTCON,T0IE = 0 disables TMR0 interrupts. IE = 0 for any
interrupt source disables it. source As TMR0 has no off/on control
it will start generating interrupts as soons as T0IE and GIE are set

2009\07\11@063654 by Heinz Czychun

flavicon
face
Hi Justin,

On 11-Jul-09, at 5:31 AM, Justin Richards wrote:

> Hi Heinz,
>
> my knowledge here is limited to beginner hobbyist so treat my comments
> accordingly.
>
> My experience has been I can disable tmr0 and use timer1

        That's my view. After all the INTCON,T0IE bit should disable  
the TMR0 interrupts what ever TMR1 is doing.

>
> I am curious why you clear the int flag if you dont want to use it.
>
> ; Setup for TMR0 and enable interrupts
> ;
> ;    clrf    TMR0        ; start timer known state
> ;
>     bcf     INTCON,T0IF ; clear TMR0 interrupt flag


        That was just my attempt to ensure,  that at least at that  
point in the program, there was no
errant TMR0 flag set.
> ;
>
> Cheers Justin
>
Thanks for your comments,
Heinz

2009\07\11@071754 by Heinz Czychun

flavicon
face
Hi Rikard,

On 11-Jul-09, at 6:09 AM, Rikard Bosnjakovic wrote:

> On Sat, Jul 11, 2009 at 10:44, Heinz Czychun<hczychunspamKILLspamlks.net> wrote:
>
>> But when I enable Timer 1, Timer 0 also starts
>> up and starts interrupting the processor.
>
> Timer0 cannot be turned off until you put the processor to sleep,
> which you don't do in your code.

       Yes, sorry poor wording. Timer 0 is running, but when I  
reprogram the PIC
with Timer 1 enabled (both running and interrupting), Timer 0 also  
starts interrupting
even with the INTCON,T0IE bit cleared.

> However, I have never heard of a case
> where T0IE being enabled when Timer1 is started.

       Ok so this is unusual.
{Quote hidden}

        Tried your suggestion and yes it didn't hurt, but also  
didn't change the situation.
> -
> - Rikard - http://bos.hack.org/cv/
>
Thanks,
Heinz

2009\07\11@071759 by Heinz Czychun

flavicon
face
Hi Jinx,

On 11-Jul-09, at 6:11 AM, Jinx wrote:

{Quote hidden}

       Yes, that was my observations. I could control the TMR0  
interrupts with the INTCON,T0IE
setting. But when I reprogrammed for Timer 1 enabled, and  
interrupting, the setting of the
INTCON,T0IE became irrelevant. Timer 0 would always start generating  
interrupts.

Thanks,
Heinz


2009\07\11@074529 by Peter van Hoof

face picon face

Do you have the luxury of checking your code with another chip
even a similar chip of the same family? What does the code do if you
run it on a simulator (oshonsofts pic sim ide is pretty good with timer simulation)

I have never come across it myself but you could have a defective chip.


Peter van Hoof


{Original Message removed}

2009\07\11@082618 by Tamas Rudnai

face picon face
On Sat, Jul 11, 2009 at 12:17 PM, Heinz Czychun <.....hczychunKILLspamspam.....lks.net> wrote:

>        Yes, sorry poor wording. Timer 0 is running, but when I
> reprogram the PIC
> with Timer 1 enabled (both running and interrupting), Timer 0 also
> starts interrupting
> even with the INTCON,T0IE bit cleared.
>

Hi Heinz,

You do not have the T0IE enabled, but you still check the T0IF in your ISR
routine. T0IF is independent from interrupt, it only tells if the Timer0 was
overflowed or not. What happens is that you get an interrupt from Timer1,
but then the ISR routine realizes that the Timer0 had an overflow as well
therefore you treat the interrupt as it was generated by the Timer0.

Tamas

2009\07\11@082639 by Jinx

face picon face
Heinz, have you tried separating out the BSF GIE ? I generally
clear all the IE and IF bits, then set required IE, then set GIE

2009\07\11@085236 by Jan-Erik Soderholm

face picon face
Tamas Rudnai wrote:
> On Sat, Jul 11, 2009 at 12:17 PM, Heinz Czychun <EraseMEhczychunspam_OUTspamTakeThisOuTlks.net> wrote:
>
>>        Yes, sorry poor wording. Timer 0 is running, but when I
>> reprogram the PIC
>> with Timer 1 enabled (both running and interrupting), Timer 0 also
>> starts interrupting
>> even with the INTCON,T0IE bit cleared.
>>
>
> Hi Heinz,
>
> You do not have the T0IE enabled, but you still check the T0IF in your ISR
> routine. T0IF is independent from interrupt, it only tells if the Timer0 was
> overflowed or not. What happens is that you get an interrupt from Timer1,
> but then the ISR routine realizes that the Timer0 had an overflow as well
> therefore you treat the interrupt as it was generated by the Timer0.
>
> Tamas

A classic example where you had *one* interrupt running
just OK and then, when adding a second interrupt source,
didn't add tests on xxIE-flags to the ISR... :-)

So test the xxIE flag *first* then test the xxIF flag.
If one xxIE flag is cleared, just jump to the next source.

That is :

 is T0IE set ? (interrupt enabled for TMR0)
 if no, goto test_tmr1
 if yes, check TOIF and run TMR0 ISR if set.

test_tmr1:
 is T1IE set ? (interrupt enabled for TMR1)
 if no, finish ISR (or goto next source/xxIE flag)
 if yes, check T1IF and run TMR1 ISR if set.

And so on for any number of interrupt sources.

Jan-Erik.



2009\07\11@101147 by Rikard Bosnjakovic

picon face
On Sat, Jul 11, 2009 at 13:17, Heinz Czychun<hczychunspamspam_OUTlks.net> wrote:

>         Tried your suggestion and yes it didn't hurt, but also
> didn't change the situation.

Weird.

A workaround for this is to rewrite your ISR. If you are never going
to use the Timer0-interrupts you could simply ignore them. They will,
in the strange environment of yours, trigger the IF of Timer0. What
you can do in the ISR is clearing T0IF. So, your ISR could be
rewritten to this:

iServ
   movwf   w_temp          ; save off current W register contents
   movf    STATUS,w        ; move status register into W register
   movwf   status_temp     ; save off contents of STATUS register

   bcf     INTCON, T0IF    ; clear Timer0-IF

   btfsc  PIR1,T1IF        ; check Timer1-IF
    goto  ServiceTimer1

   goto  iServ_Exit

You will waste some cycles when Timer0 triggers but in case you cannot
disable T0IE this could be a solution.


--
- Rikard - http://bos.hack.org/cv/

2009\07\11@110544 by olin piclist

face picon face
Heinz Czychun wrote:
> With Timer 1 disabled I'm able to control Timer 0 effectively with the
> INTCON,T0IE bit. Off and on. But when I enable Timer 1, Timer 0 also
> starts up and starts interrupting the processor.
>
> Is this normal? Is it a known problem? Or am I missing something?

I'm guessing you aren't checking the IE bits for the disabled interrupts
so you get into a infinite interrupt if the IF bit for a disabled
interrupt gets set.

There are a number of issues with your code, however, before we can look at
that.  On the good side you seem to have paid attention to banking and did a
nice job of documenting bit settings.  That puts you ahead of 95% of newbies
already.  On the flip side there are some serious problems.  I didn't look
at the code in detail, so here is only what jumped out:

> ;***** VARIABLE DEFINITIONS
> #define LED_DS1 1            ;LED connected to GP1

This is not a variable at all.  You have defined a inline string
substitution macro.  They can be useful, but should only be used when really
needed.  If you just want to define a symbolic integer constant, do it right
and use EQU.  This isn't C.

> INT_VAR  UDATA_SHR 0x20

Bad idea.  I doubt you really need this to be specifically at location 20h,
so don't force it there.  This happens to work on this chip, but will
needless break on other chips that have the unbanked memory in a different
location.

> RESET_VECTOR CODE 0x000      ;processor reset vector
>          goto    main        ;go to beginning of program

This particular chip may have only one page, so you can get away with it
here, but that doesn't make it a good idea.  Use PAGESEL before the GOTO.
It won't emit code when the PIC only has a single page, but keeps this
from being a lurking bug if the code is ever moved to a larger PIC.

> INT_VECTOR CODE  0x004       ;interrupt vector location
>          goto    iServ

Never do this.  Some code will live at the interrupt vector, so it might as
well be the one routine that benefits from being there.  In addition, this
code is broken on any PIC with more than one page since it relies on PCLATH
at the time of the interrupt.  And no, using PAGESEL before the GOTO doesn't
fix it either because that corrupts PCLATH before the interrupt routine has
chance to save it.

> main

This should be in a separate section so that the linker can place it where
it wants to.  Right now your code actually forces it to be immediately after
the interrupt vector, which makes no sense.

>          movlw   b'00001000'
>          ;         0-------  1=disabled, no GPIO Pull-ups     GPPU: GPIO
Pull-ups
>          ;         -0------  0=falling edge interrupt,      INTEDG:
Interrupt Edge of GP2
>          ;         --0-----  0=Internal inst clock (CLKOUT),  T0CS: TMR0
Clock Source
>          ;         ---0----  0=Inc on lo^hi transition on GP2,T0SE: TMR0
Source Edge
>          ;         ----1---  1=Prescaler assigned to WDT,     PSA:
Prescaler Assignment
>          ;         -----0--  001 Prescaler 1:4,            PS2-PS0:
Prescaler Rate
>          ;         ------0-  Bits  TMR0    WDT
>          ;         -------0  000    1:2    1:1
>          ;                   001    1:4    1:2
>          ;                   010    1:8    1:4
>          ;                   011    1:16   1:8
>          ;                   100    1:32   1:16
>          ;                   101    1:64   1:32
>          ;                   110    1:128  1:64
>          ;                   111    1:256  1:128

The comment says 1:4 prescaler but the code says differently.  Since the
low 3 bits are all one field they should be documented as a single field,
not 3 individual bits.

>          bcf     INTCON, GIE

This makes no sense in the interrupt routine.  Read the manual.  GIE is
cleared by the hardware when the interrupt is taken, so this is a waste of
time.

>          btfsc   INTCON, T0IF
>          goto    ServiceTimer0
>          btfsc   PIR1, T1IF
>          goto    ServiceTimer1

Here is the cause of the symptoms I think.  As I guessed, you are jumping
to the interrupt service routines only if the IF bit is set and not
checking the IE bit.  That means that the timer 0 interrupt service
routine will be run even when its interrupt is disabled when you get here
for other reasons, which in this case is a timer 1 interrupt.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\07\11@112202 by olin piclist

face picon face
Rikard Bosnjakovic wrote:
> You will waste some cycles when Timer0 triggers but in case you cannot
> disable T0IE this could be a solution.

I admittedly didn't read your post in detail, but this bit jumped out as
superstition-based programming.  Why would you think or even imagine that
one couldn't disable T0IE?  That makes no sense.  BCF INTCON,T0IE will
absolutely positively disable T0IE.  Read the manual instead of waving dead
fish.

Note however that T0IE has nothing to do with T0IF getting set when timer 0
wraps.  It only controls whether a interrupt is generated for that reason.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\07\11@123451 by Gerhard Fiedler

picon face
Heinz Czychun wrote:

>> INTCON,T0IE = 0 disables TMR0 interrupts. IE = 0 for any interrupt
>> source disables it. source As TMR0 has no off/on control it will
>> start generating interrupts as soons as T0IE and GIE are set
>
> Yes, that was my observations. I could control the TMR0 interrupts
> with the INTCON,T0IE setting. But when I reprogrammed for Timer 1
> enabled, and interrupting, the setting of the INTCON,T0IE became
> irrelevant.

Note that the ...IE flags only determine whether the corresponding ...IF
flags generate an interrupt when set. That's why you have to check both
the ...IF and the ...IE flags in an interrupt routine if you want to
disable an interrupt in firmware.


> Timer 0 would always start generating interrupts.

What do you mean by this? That T0IF is set in the interrupt routine, or
that the interrupt was caused by T0IF being set? These two are
different. Unless you actually shut down timer 0 (e.g. by not having
anything connected to T0CKI and setting T0SS), the T0IF flag will be set
sooner or later. If T0IE is 0, this will not cause an interrupt -- but
it still will be set. And if another interrupt flag causes an interrupt,
you will see it in the interrupt routine.

So... if you don't care about timer 0, don't check T0IF and it being set
won't bother you. If you want to disable and enable the timer 0
interrupt in your firmware, you need to check both T0IF and T0IE in the
interrupt routine and only consider a timer 0 interrupt if both are set.
This goes pretty much for all PIC interrupts.

Check out the timer 0 (4-1) and interrupt logic (9-10) block diagrams in
the data sheet.

Gerhard

2009\07\11@133543 by Dwayne Reid

flavicon
face
At 02:44 AM 7/11/2009, Heinz Czychun wrote:
>Hi,
>     I'm having a little problem with controlling Timer 0 and Timer 1
>interrupts separately, on a PIC12F675.
>
>     With Timer 1 disabled I'm able to control Timer 0 effectively
>with the INTCON,T0IE bit. Off and on. But when I enable Timer 1,
>Timer 0 also starts up and starts interrupting the processor.

I see a couple of things worth looking at:

        movlw  b'10100000'
>         ;             1-------  (GIE)1=interrupts enabled
>         ;             -0------  (PEIE)1=enable peripheral interrupts
>         ;             --1-----  (T0IE)0=disable TMR0 overflow

1) You say in the line above that "0 disables TMR0 overflow" but you
are setting to be a "1".  Check to make sure that it really is a "0".

2) Do NOT check T0IF within your Interrupt Service Routine if you
aren't using it!  Here's why: T0IF will ALWAYS become set each and
every time TMR0 rolls over from 0xFF to 0x00.  However, if T0IE isn't
set, it won't cause an interrupt.

If you check T0IF, you will most likely find that it is
set.  However, that's NOT what caused the interrupt if T0IE has not
been enabled (=1).

Hope this helps!

dwayne



--
Dwayne Reid   <@spam@dwaynerKILLspamspamplanet.eon.net>
Trinity Electronics Systems Ltd    Edmonton, AB, CANADA
(780) 489-3199 voice          (780) 487-6397 fax
http://www.trinity-electronics.com
Custom Electronics Design and Manufacturing

2009\07\11@154742 by Ruben Jönsson

flavicon
face
{Quote hidden}

On a similar problem I just couldn't figure out why all of a sudden SLEEP woke
up at once when it was supposed to be woken up by the WDT after about 18ms. It
turned out to be that I had enabled timer0 to make interrupts (TOIE=1 GIE=1)
and I just cleared GIE when done before going to sleep thinking that since
timer0 isn't running while at sleep anyway I didn't need to care about TOIE.
However, timer0 did roll over after I cleared GIE but before going into sleep.
This didn't generate an interrupt but since the TOIF flag got set, sleep exited
at once.

This was clearly explained in figure 9-10 in the datasheet.

/Ruben

==============================
Ruben Jönsson
AB Liros Electronic
Box 9124, 200 39 Malmö, Sweden
TEL INT +46 40142078
FAX INT +46 40947388
KILLspamrubenKILLspamspampp.sbbs.se
==============================

2009\07\11@154750 by Ruben Jönsson

flavicon
face
{Quote hidden}

On a similar problem I just couldn't figure out why all of a sudden SLEEP woke
up at once when it was supposed to be woken up by the WDT after about 18ms. It
turned out to be that I had enabled timer0 to make interrupts (TOIE=1 GIE=1)
and I just cleared GIE when done before going to sleep thinking that since
timer0 isn't running while at sleep anyway I didn't need to care about TOIE.
However, timer0 did roll over after I cleared GIE but before going into sleep.
This didn't generate an interrupt but since the TOIF flag got set, sleep exited
at once.

This was clearly explained in figure 9-10 in the datasheet.

/Ruben

==============================
Ruben Jönsson
AB Liros Electronic
Box 9124, 200 39 Malmö, Sweden
TEL INT +46 40142078
FAX INT +46 40947388
RemoveMErubenTakeThisOuTspampp.sbbs.se
==============================

2009\07\11@173327 by Heinz Czychun

flavicon
face
Hi,

      Thanks for all the excellent comments, let me go away a bit  
and refine my model of the PIC interrupt structure (and relocatable  
coding).

Regards,
Heinz


2009\07\11@202942 by Jinx

face picon face
BTW Heinz, I wrote

> have you tried separating out the BSF GIE ? I generally clear
> all the IE and IF bits, then set required IE, then set GIE

The reason I mention this is because other PIC users and I have
seen some funny things happen at the silicon level with SFR bits
set in a particular order, even though there is absolutely nothing
wrong, (theoretically - ie there's no datasheet reason given not to
do it), with that order

2009\07\12@002133 by Heinz Czychun

flavicon
face
Hi,
      In summary what I now think is correct:

1)  What I am seeing is normal behaviour.

2)  T0IF gets set every time Timer 0 rolls over

3)  2 above is only an issue if another peripheral causes an  
interrupt, then T0IF must be explicitly dealt with. Since Timer 0 is  
not easily turned off.

4)  I can only stop Timer 0 by:
 a) putting the chip to sleep
not very practical since the chip can't do much while asleep, and  
Timer 0 will start running again when the chip awakens.
 b) setting it as a counter and not using the input pin
 b1) setting it to an analogue input should work (input reads as zero)
Not practical on the 12F675 as it's AN2 and am not sure if AN2 can be  
an analogue input while AN0 & AN1 are Digital???
 b2) not sure if setting it to an output would also work??? Would  
the counter still register output transitions?

5)  So I'm left with dealing with the T0IF bit, when in the interrupt  
service routine.

I must say I was initially confused by the mention of T0IE, by Tamas,  
Jan-Erik, and Olin perhaps others. After all, hadn't I cleared this  
bit in the beginning, and so shouldn't this be a set (clear, in this  
instance) and forget item, right?

I think I understand it now. My confusion was I didn't understand the  
changing significance of the interrupt enable bits (eg T0IE) and  
interrupt flag bits (eg TOIF). Their significance changes depending  
on whether execution is in the main code, or in the interrupt service  
routine.

In the main code the interrupt enable bits are significant in that  
they will prevent a peripheral from generating an interrupt. So the  
interrupt flag bits can safely be ignored.

Once an interrupt (any interrupt) forces execution of the interrupt  
service routine the interrupt enable bits become useful flags to tell  
which peripheral's service request should be honoured. But now the  
interrupt flag bits (all that are set) become significant and cannot  
be ignored. Whether the peripheral's interrupt enable bit is set or  
not it's interrupt flag bit must be cleared or the processor will be  
hung repeatedly reentering the interrupt service routine.

That's the way I see what the manual is trying to explanation. Does  
that sound right?

In this particular instance it is prohibitively difficult to stop  
TMR0, and so I have to live with adding code that when it reads T0IF  
set it clears it. I can safely ignore the T0IE bit because I know I  
don't want the PIC to take action on it's rollover.


Thanks again for all your help,
Regards,
Heinz



2009\07\12@005039 by Jinx

face picon face
> 5)  So I'm left with dealing with the T0IF bit, when in the interrupt  
> service routine.
>
> T0IE ..shouldn't this be a set (clear, in this instance) and forget item

Yes

You need to distinguish between what causes an interrupt and what
is set when the ISR is entered. For example, RB0 has the associated
INT0IF and INT0IE flags. If INT0IE isn't set, then INT0IF can't
cause an interrupt, even though it may be set. If an interrupt is caused
by a timer then you may find all kinds of other IFs, like INT0IF, set
if you look for them. But they are of no consequence if you are not
interested in them as interrupt sources. And, for example, it is often
the case that you'd poll an IF, like a timer, in a non-critical instance
when you don't want to use an interrupt but simply need to know
that an event occurred

2009\07\12@032456 by Heinz Czychun
flavicon
face
Hi Jinx,

On 12-Jul-09, at 12:50 AM, Jinx wrote:

{Quote hidden}

     Ok, then I'm assuming your in the interrupt service routine,  
right?

> then you may find all kinds of other IFs, like INT0IF, set
> if you look for them. But they are of no consequence if you are not
> interested in them as interrupt sources.

    I disagree here they, the IFs, are very significant because you  
won't get out of the isr without clearing them.

    I see it as a dyke or dam. All is ok as long as all the water is  
kept out, no interrupts are allowed to happen. But once that first  
crack happens, an interrupt occurs, all the set IFs are suddenly seen  
by the cpu and need to be cleared before it can get back to the main  
code again. And your code has to tell it to do this. That's how  
interprete all the warnings in the manual about TMR0 settings its  
TOIF regardless of the TOIE, and that this must be cleared in 'your'  
software.

    I think that's why uChip has added an on bit to most (all?)  
peripherals, so they never can set their IFs when off, so don't need  
to be dealt with in the isr.  Timer0 being a legacy sort of  
peripheral (the first one?) doesn't have such a nicety.


>
> And, for example, it is often
> the case that you'd poll an IF, like a timer, in a non-critical  
> instance
> when you don't want to use an interrupt but simply need to know
> that an event occurred

    Yes that works because you never entered into an isr.
Heinz


2009\07\12@034943 by Ruben Jönsson

flavicon
face
>
> In the main code the interrupt enable bits are significant in that  
> they will prevent a peripheral from generating an interrupt. So the  
> interrupt flag bits can safely be ignored.
>
> Once an interrupt (any interrupt) forces execution of the interrupt  
> service routine the interrupt enable bits become useful flags to tell  
> which peripheral's service request should be honoured. But now the  
> interrupt flag bits (all that are set) become significant and cannot  
> be ignored. Whether the peripheral's interrupt enable bit is set or  
> not it's interrupt flag bit must be cleared or the processor will be  
> hung repeatedly reentering the interrupt service routine.
>

Since a new interrupt won't be generated if its IE bit is clear there will be
no new interrupt generated so the interrupt will not be reentered if only the
IF bit without its IE bit is set. Figure 9-10 in the datasheet explains this
(and the wake up from sleep) better than with 1000 words. The IF bit should not
be cleared in the ISR if the IE bit is not set since the non ISR code could
look for this bit. I have actually done this where timer0 caused interrupts to
generate notes of a certain frequency in a buzzer while the main program
checked for other conditions, including timer1 with its IF bit, to tell when to
stop playing one note and go on to the next.

Here is one way to efficiently check both IE and IF bits for timer0:

isr_tmr0_start
 btfsc  INTCON,TIOE
 btfss  INTCON,TOIF
 goto   isr_tmr0_end
isr_tmr0_on
 bcf    INTCON,TOIF
 ;rest of tmr0 isr here
isr_tmr0_end
 ;check other interrupt sources here
 ...

Note also that you have three conditions to check for with the periferal
interrupts: In addition to the IE and IF bits there is also the PEIE bit.

==============================
Ruben Jönsson
AB Liros Electronic
Box 9124, 200 39 Malmö, Sweden
TEL INT +46 40142078
FAX INT +46 40947388
spamBeGonerubenspamBeGonespampp.sbbs.se
==============================

2009\07\12@035710 by Ruben Jönsson

flavicon
face
{Quote hidden}

This is not in accordance with figure 9-10 in the datasheet for the 12f629/675.
When the IE bit is not set, the IF bit by itself can not cause the execution of
the ISR (either once or reentering it).

/Ruben
==============================
Ruben Jönsson
AB Liros Electronic
Box 9124, 200 39 Malmö, Sweden
TEL INT +46 40142078
FAX INT +46 40947388
TakeThisOuTrubenEraseMEspamspam_OUTpp.sbbs.se
==============================

2009\07\12@044756 by Jan-Erik Soderholm

face picon face
Heinz Czychun wrote:

> I think I understand it now. My confusion was I didn't understand the  
> changing significance of the interrupt enable bits (eg T0IE) and  
> interrupt flag bits (eg TOIF). Their significance changes depending  
> on whether execution is in the main code, or in the interrupt service  
> routine.

I do not think so. For one thing, the processor itself can not
tell if it is in the "main" code or in the "ISR". It's just a
logical way of splitting the code. The "interrupt" itself is
more or less a simple GOTO to h'0004' with a few additional
bits set/cleared on the way. There is no way for either
the processor or your code to know/see that it is currently
inside the part of your code that you has called "the ISR"...

So, no, nothing in the processor changes in the way it works
dependig in what part of the code is executing.

> In the main code the interrupt enable bits are significant in that  
> they will prevent a peripheral from generating an interrupt. So the  
> interrupt flag bits can safely be ignored.

Yes.

> Once an interrupt (any interrupt) forces execution of the interrupt  
> service routine the interrupt enable bits become useful flags to tell  
> which peripheral's service request should be honoured.

Correct.

> But now the  
> interrupt flag bits (all that are set) become significant and cannot  
> be ignored.

If the xxIE bit is cleared, they can still be ignored.

> Whether the peripheral's interrupt enable bit is set or  
> not it's interrupt flag bit must be cleared or the processor will be  
> hung repeatedly reentering the interrupt service routine.

No, a set xxIF bit will not reenter the ISR if the xxIE bit is cleared.
Clearing a xxIF bit that you are not using is a waste of time.

>
> That's the way I see what the manual is trying to explanation. Does  
> that sound right?
>
> In this particular instance it is prohibitively difficult to stop  
> TMR0, and so I have to live with adding code that when it reads T0IF  
> set it clears it. I can safely ignore the T0IE bit because I know I  
> don't want the PIC to take action on it's rollover.

Simply clear T0IE and TMR0 should/will not generate any interrupt.

I think that you have to come up with a simple test-case that shows
what you think you are seeing.

Jan-Erik.

2009\07\12@060559 by Tamas Rudnai

face picon face
On Sun, Jul 12, 2009 at 5:21 AM, Heinz Czychun <RemoveMEhczychunspamTakeThisOuTlks.net> wrote:

> 1)  What I am seeing is normal behaviour.
>
> 2)  T0IF gets set every time Timer 0 rolls over


Yes, that's correct


> 3)  2 above is only an issue if another peripheral causes an
> interrupt, then T0IF must be explicitly dealt with. Since Timer 0 is
> not easily turned off.


You do not have to deal with T0IF, simply just ignore it in the ISR. That's
one of the disadvantage of the non-vectored interrupt controller of the PIC.
When an interrupt occurs you always have to figure out what caused the
interrupt. Testing T0IF is just a way polling if Timer0 caused the
interrupt, but if T0IE was not set there is no reason to do this testing.



> 4)  I can only stop Timer 0 by:


Don't worry about stopping Timer0. Just let it rolling over and over again
and ignore T0IF.

In the main code the interrupt enable bits are significant in that
> they will prevent a peripheral from generating an interrupt. So the
> interrupt flag bits can safely be ignored.


That's correct


> Once an interrupt (any interrupt) forces execution of the interrupt
> service routine the interrupt enable bits become useful flags to tell
> which peripheral's service request should be honoured. But now the
> interrupt flag bits (all that are set) become significant and cannot
> be ignored. Whether the peripheral's interrupt enable bit is set or
> not it's interrupt flag bit must be cleared or the processor will be
> hung repeatedly reentering the interrupt service routine.


Only when the appropriate IE bit is set. For example if T0IE is clear you
will get no interrupt at any time because of T0IF is set.

Tamas

2009\07\12@071933 by Heinz Czychun

flavicon
face
Hi Guys,
      Me bad. Jinx and others I apologize. Please disregard my  
previous ravings. They were based on bad assumptions about what I was  
observing.

      I had an LED connected to GP1 as described, and it was  
flickering, I took this to mean that TMR0 was activating the  
interrupt, even though I had its T0IE cleared.  A quick calculation  
showed me that even with the full prescaler divide by (256) the LED  
would still be flashing at 1000s of Hz. This would of course look  
like a solid on, and not a flicker. I was able to get a scope on GP1  
and there is no sign of any signal in the 1000s of Hz range.

     Now to track down the real cause of the flickering after  
getting some sleep.

Thanks again for all your time,
Heinz

2009\07\12@073228 by Jan-Erik Soderholm

face picon face
Heinz Czychun wrote:
> Hi Guys,
>        Me bad. Jinx and others I apologize. Please disregard my  
> previous ravings. They were based on bad assumptions about what I was  
> observing.
>
>        I had an LED connected to GP1 as described, and it was  
> flickering, I took this to mean that TMR0 was activating the  
> interrupt, even though I had its T0IE cleared.  A quick calculation  
> showed me that even with the full prescaler divide by (256) the LED  
> would still be flashing at 1000s of Hz. This would of course look  
> like a solid on, and not a flicker. I was able to get a scope on GP1  
> and there is no sign of any signal in the 1000s of Hz range.
>
>       Now to track down the real cause of the flickering after  
> getting some sleep.
>
> Thanks again for all your time,
> Heinz

WDT enabled ?
Open input pin(s) (or even an open MCLR?).
Runaway code that makes the program re-initialize ?

2009\07\12@084853 by olin piclist

face picon face
Heinz Czychun wrote:
> Once an interrupt (any interrupt) forces execution of the interrupt
> service routine the interrupt enable bits become useful flags to tell
> which peripheral's service request should be honoured.

Yes, if your code enables/disables specific interrupts on the fly.  Most PIC
projects use a fixed set of interrupts.  In that case you don't need to
check any IE bits because any condition that could cause a interrupt is
always enabled.  Even if your code enables/disables some interrupts, you
only have to check the IE bits of those interrupts in the interrupt routine
before reacting to their IF bits.

> But now the
> interrupt flag bits (all that are set) become significant and cannot
> be ignored.

No.  Only the ones that might be enabled (have their IE bits set).

> Whether the peripheral's interrupt enable bit is set or
> not it's interrupt flag bit must be cleared or the processor will be
> hung repeatedly reentering the interrupt service routine.

No.  If a peripheral's IE bit is cleared, that peripheral will not cause a
interrupt.  The IF bit of such a peripheral is irrelevant to the interrupt
routine.  In fact, it would be bad for the interrupt routine to clear such
IF bits because that peripheral might be used via polling in the foreground
code.

Here is the interrupt routine code snippet for checking for the timer 0
interrupt when this could be enabled/disabled on the fly:

;
;   Check for timer 0 rollover.  This interrupt could be disabled.
;
        btfss   intcon, t0ie ;timer 0 interrupt enabled ?
        goto    no_tmr0     ;no
        btfsc   intcon, t0if ;timer 0 didn't interrupt ?
        goto    intr_tmr0   ;did interrupt, go service it
no_tmr0                      ;timer 0 didn't do it


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\07\12@104154 by Gerhard Fiedler

picon face
Heinz Czychun wrote:

>> then you may find all kinds of other IFs, like INT0IF, set
>> if you look for them. But they are of no consequence if you are not
>> interested in them as interrupt sources.
>
> I disagree here they, the IFs, are very significant because you won't
> get out of the isr without clearing them.

This is wrong. If an IE bit is not set, you can safely ignore the
corresponding IF bit. This IF bit won't generate an interrupt; this is
why you can ignore it and exit the interrupt routine with the bit set.


> I think that's why uChip has added an on bit to most (all?)
> peripherals, so they never can set their IFs when off, so don't need
> to be dealt with in the isr.  Timer0 being a legacy sort of
> peripheral (the first one?) doesn't have such a nicety.

Difficult to know why Microchip does things, but in general the
peripheral enable bits serve the purpose of reducing current draw if you
don't need that peripheral.

It's simple, and it seems you haven't "got" it yet... If you want to
enable/disable an interrupt in firmware, you need to look at both IE and
IF bits for that interrupt in the interrupt routine when deciding
whether to execute the associated interrupt action. For all interrupts
that are always enabled (in your firmware), you just need to look at
their IF bit in the interrupt routine when deciding whether to execute
the associated interrupt action. For all other interrupts (that is, the
ones you don't need), it is safe (and the usual thing to do) to just
ignore their IF bit (and of course make sure their IE bit is 0).

Gerhard

2009\07\12@175144 by olin piclist

face picon face
Heinz Czychun wrote:
>      I disagree here they, the IFs, are very significant because you
> won't get out of the isr without clearing them.

Wrong.  The IF bits have nothing to do with interrupts if the corresponding
IE bits are not set.  Read the interrupt section of the datasheet again.
All of it.  Carefully.

>      I see it as a dyke or dam. All is ok as long as all the water is
> kept out, no interrupts are allowed to happen. But once that first
> crack happens, an interrupt occurs, all the set IFs are suddenly seen
> by the cpu and need to be cleared before it can get back to the main
> code again.

I have no idea where you got that from, but again, it's just plain wrong.

>      I think that's why uChip has added an on bit to most (all?)
> peripherals, so they never can set their IFs when off, so don't need
> to be dealt with in the isr.

No, it's to save power when they are not in use.  Setting the IF bit causes
no harm if the IE bit is not set and no code is specifically looking at the
IF bit.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\07\12@193854 by Jinx

face picon face
>        Me bad

No worries Heinz. I've done worse. And we had a good chat
about interrupts. Best of luck

2009\07\13@063021 by Alan B. Pearce

face picon face
>Yes, that was my observations. I could control the TMR0
>interrupts with the INTCON,T0IE setting. But when I
>reprogrammed for Timer 1 enabled, and interrupting, the
>setting of the INTCON,T0IE became irrelevant. Timer 0
>would always start generating interrupts.

I haven't read through your code, but this sounds to me like a basic
misunderstanding of how the hardware works.

The T0IF will ALWAYS get set when T0 overflows. It is just that the T0IE
flag doesn't let the T0IF flag set the interrupt that causes the code to go
to the interrupt routine.

So when you are looking for the T1 interrupt, you have to check the T0IE
flag first to see if that is set, and if not, you want to ignore the T0IF
interrupt flag, and check for the T1IE and T1IF flags.

More... (looser matching)
- Last day of these posts
- In 2009 , 2010 only
- Today
- New search...