Exact match. Not showing close matches.
PICList
Thread
'[PIC]: PIC12F675 TMR0, TMR1 Interrupt control'
2009\07\11@044421
by
Heinz Czychun
|
--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
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_OUThczychunTakeThisOuT
lks.net>
{Quote hidden}> 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
>
>
>
>
>
>
> -
2009\07\11@060951
by
Rikard Bosnjakovic
On Sat, Jul 11, 2009 at 10:44, Heinz Czychun<.....hczychunKILLspam
@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
> ; 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
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
|
Hi Rikard,
On 11-Jul-09, at 6:09 AM, Rikard Bosnjakovic wrote:
> On Sat, Jul 11, 2009 at 10:44, Heinz Czychun<hczychun
KILLspamlks.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}>
> 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.
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
Hi Jinx,
On 11-Jul-09, at 6:11 AM, Jinx wrote:
{Quote hidden}>> ; 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
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
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
On Sat, Jul 11, 2009 at 12:17 PM, Heinz Czychun <.....hczychunKILLspam
.....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
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
Tamas Rudnai wrote:
> On Sat, Jul 11, 2009 at 12:17 PM, Heinz Czychun <EraseMEhczychunspam_OUT
TakeThisOuTlks.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
On Sat, Jul 11, 2009 at 13:17, Heinz Czychun<hczychun
spam_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
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
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
|
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
|
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@dwaynerKILLspam
planet.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
|
{Quote hidden}> 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
>
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
KILLspamrubenKILLspam
pp.sbbs.se
==============================
2009\07\11@154750
by
Ruben Jönsson
|
{Quote hidden}> 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
>
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
RemoveMErubenTakeThisOuT
pp.sbbs.se
==============================
2009\07\11@173327
by
Heinz Czychun
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
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
|
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
> 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
|
Hi Jinx,
On 12-Jul-09, at 12:50 AM, Jinx wrote:
{Quote hidden}>> 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
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
|
>
> 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
spamBeGonerubenspamBeGone
pp.sbbs.se
==============================
2009\07\12@035710
by
Ruben Jönsson
|
{Quote hidden}> Hi Jinx,
>
> On 12-Jul-09, at 12:50 AM, Jinx wrote:
>
>
> 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.
>
>
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
TakeThisOuTrubenEraseME
spam_OUTpp.sbbs.se
==============================
2009\07\12@044756
by
Jan-Erik Soderholm
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
On Sun, Jul 12, 2009 at 5:21 AM, Heinz Czychun <RemoveMEhczychun
TakeThisOuTlks.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
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
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
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
|
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
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
> 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
>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...