Here are a few ways to do this without using a slower osc.
For a PIC12F1822 using a compare interrupt.
And one for the 12F683 using Timer2/PR2 match interrupt;Code:@ __config _CONFIG1, _FOSC_INTOSC & _MCLRE_OFF & _CLKOUTEN_OFF @ __config _CONFIG2, _PLLEN_OFF & _LVP_OFF DEFINE INTHAND HzOut LED VAR PORTA.0 TRISA = 0 ANSELA = 0 ' All digital CCP1CON = %00001011 ' Compare mode with auto reset of Timer1 CCPR1H = $06 ' Load for match every 1,538uS CCPR1L = $02 ' 1,538uS x 2 = 3.076mS. 1/3.076mS = ~325.09 Hz OSCCON = %01101000 ' 4MHz internal osc T1CON = %00000001 ' Enable Timer1, 1:1 rescale PIR1.2 = 0 ' Clear int flag before enabling interrupt PIE1 = %00000100 ' Enable CCP1 interrupt INTCON = %11000000 ' Global & peripheral ints enabled Main: TOGGLE LED ; Do whatever here. You have ~1,538 instruction PAUSE 1000 ; cycles before each interrupt GOTO Main ASM HzOut ; Eats-up 5 instruction cycles MOVLW B'00000100' ; Load WREG with %00000100 for XOR op below XORWF PORTA,F ; Toggle PORTA,2 on each 1/2 cycle BCF PIR1,CCP1IF ; Clear CCP1 interrupt flag RETFIE ; Go get some more ENDASM END
Interrupts are a LOT faster & easier with newer PIC types with auto context save/restore.Code:@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF DEFINE INTHAND HzOut wsave VAR BYTE $70 SYSTEM ssave VAR BYTE BANK0 SYSTEM psave VAR BYTE BANK0 SYSTEM LED VAR GPIO.0 TRISIO = 0 ANSEL = 0 ' All digital CMCON0 = 7 OSCCON = %01100000 ' 4MHz internal osc T2CON = %00111100 ' Enable Timer2, 1:1 prescale / 1:8 postscale PIR1.1 = 0 ' Clear TMR2 int flag before enabling interrupt PIE1 = %00000010 ' Enable TMR2 interrupt INTCON = %11000000 ' Global & peripheral ints enabled PR2 = 191 Main: TOGGLE LED ; Do whatever here. PAUSE 1000 ; GOTO Main ASM HzOut movwf wsave ; Save W swapf STATUS,W ; Swap STATUS to W (swap avoids changing STATUS) clrf STATUS ; Clear STATUS movwf ssave ; Save swapped STATUS movf PCLATH,W ; Move PCLATH to W movwf psave ; Save PCLATH MOVLW B'00000100' ; Load WREG with %00000100 for XOR op below XORWF GPIO,F ; Toggle GPIO,2 on each 1/2 cycle BCF PIR1,TMR2IF ; Clear TMR2 interrupt flag movf psave,W ; Retrieve PCLATH value movwf PCLATH ; Restore it to PCLATH swapf ssave,W ; Retrieve the swapped STATUS value (swap to avoid changing STATUS) movwf STATUS ; Restore it to STATUS swapf wsave,F ; Swap the stored W value swapf wsave,W ; Restore it to W (swap to avoid changing STATUS) retfie ; Go get some more ENDASM END





Bookmarks