jakeselectronics
Member
Hey everyone.
Ok my concept is simple; generate a pulse (roughly long enough to flash an LED and see it, say 100mS?) at a fairley accurate interval of 1 second.
Been done a million times before I know, but its my first so I learning.
I have successfully generated a flashing LED, but it seems to be flashing every 2 seconds.
I can understand that my Timer1 is overflowing at 65,535 and not 32,768 counts as it is 16 bits and this probably explains the x2 flash rate but I'm not sure how to work around this.
I have:
LED on PORTB, bit 0
32.768kHz crystal on RB6 RB7
TMR1CS: 1 = External clock from pin RB6/T1OSO/T1CKI/PGC (on the rising edge) - (Timer1 Clock Source Select bit)
T1SYNC: 1 = Do not synchronize external clock input (Timer1 External Clock Input Synchronization Control bit)
T1OSCEN: 1 = Oscillator is enabled (Timer1 Oscillator Enable Control bit)
T1CKPS<1:0>: 00 = 1:1 Prescale value (Timer1 Input Clock Prescale Select bits)
Here is my code.
Ok my concept is simple; generate a pulse (roughly long enough to flash an LED and see it, say 100mS?) at a fairley accurate interval of 1 second.
Been done a million times before I know, but its my first so I learning.
I have successfully generated a flashing LED, but it seems to be flashing every 2 seconds.
I can understand that my Timer1 is overflowing at 65,535 and not 32,768 counts as it is 16 bits and this probably explains the x2 flash rate but I'm not sure how to work around this.
I have:
LED on PORTB, bit 0
32.768kHz crystal on RB6 RB7
TMR1CS: 1 = External clock from pin RB6/T1OSO/T1CKI/PGC (on the rising edge) - (Timer1 Clock Source Select bit)
T1SYNC: 1 = Do not synchronize external clock input (Timer1 External Clock Input Synchronization Control bit)
T1OSCEN: 1 = Oscillator is enabled (Timer1 Oscillator Enable Control bit)
T1CKPS<1:0>: 00 = 1:1 Prescale value (Timer1 Input Clock Prescale Select bits)
Here is my code.
Code:
LIST P=PIC16F628A
INCLUDE P16F628A.INC
__CONFIG _CP_OFF & _CPD_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDTE_OFF & _INTOSC_OSC_NOCLKOUT
ERRORLEVEL -302 ;Eliminate bank warning
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; PIC16F628A Microcontroller ;
; ____ ____ ;
; VREF/AN2/RA2 -| 1 - 18 |- RA1/AN1 ;
; CPM1/AN3/RA3 -| 2 17 |- RA0/AN0 ;
; CMP2/T0CKI/RA4 -| 3 16 |- RA7/OSC1/CLKIN ;
; VPP/MCLR/RA5 -| 4 15 |- RA6/OSC2/CLKOUT ;
; VSS -| 5 14 |- VDD ;
; INT/RB0 -| 6 13 |- RB7/T1OSC1/PGD ;
; DT/RX/RB1 -| 7 12 |- RB6/T1OSCO/T1CLKI/PGC ;
; CK/TX/RB2 -| 8 11 |- RB5 ;
; CCP1/RB3 -|_9____10_|- RB4/PGM ;
; ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CBLOCK H'20' ; Commence defining following constant block at RAM address H'20'
DELAYGPR1 ; Variable used for temporary information storage in the delay subroutines
DELAYGPR2 ; Variable used for temporary information storage in the delay subroutines
DELAYGPR3 ; Variable used for temporary information storage in the delay subroutines
FLAGS
ENDC
W_ISR EQU H'70' ; For context saving. Ensures GPR is accessible from any Bank. See Memory Map of 628A
S_ISR EQU H'71' ; For context saving. Ensures GPR is accessible from any Bank. See Memory Map of 628A
P_ISR EQU H'72' ; For context saving. Ensures GPR is accessible from any Bank. See Memory Map of 628A
F_ISR EQU H'73' ; For context saving. Ensures GPR is accessible from any Bank. See Memory Map of 628A
ORG H'000' ; Processor reset vector location. On power up, the program jumps here
GOTO SETUP ;
ORG H'004' ; Interrupt vector location. When an Interrupt occurs, the program jumps here
; Save
MOVWF W_ISR ; Save W to W_ISR
SWAPF STATUS, W ; Use SWAPF instruction so status bits don't change
MOVWF S_ISR ; Save Status to S_ISR
CLRF STATUS ; Switch to Bank 0
MOVF PCLATH, W ; Move PCLATH to W register
MOVWF P_ISR ; Save PCLATH to P_ISR
CLRF PCLATH ; Force page 0
MOVF FSR, W ; Move FSR to W register
MOVWF F_ISR ; Save FSR to F_ISR
; Interrupt content
BSF PORTB, 0
CALL DELAY_100mS
BCF PORTB, 0
; RESTORE
BCF PIR1, TMR1IE ; Clear TMR1 interrupt flag while still in Bank 0
MOVF F_ISR, W ; MOVE F_ISR to W
MOVWF FSR ; Restore FSR
MOVF P_ISR, W ; MOVE P_ISR to W
MOVWF PCLATH ; Restore PCLATH
SWAPF S_ISR, W ; Undo previous SWAPF, place result in W
MOVWF STATUS ; Restore STATUS
SWAPF W_ISR, F ; Use SWAPF instruction so status bits don't change
SWAPF W_ISR, W ; Undo previous SWAPF and restore W register
RETFIE ; Return From Interrupt
SETUP ; This routine sets up the Microcontroller's Inputs and Outputs
MOVLW H'07' ; Turn Comparators off and enable pins for I/O functions
MOVWF CMCON ;
BSF STATUS, RP0 ; Bank 1
MOVLW B'00010000' ;
MOVWF TRISA ;
MOVLW B'11000000' ;
MOVWF TRISB ;
BCF STATUS, RP0 ; Bank 0
CLRF PORTA ;
CLRF PORTB ;
CLRF FLAGS ;
TIMER_1_SETUP
MOVLW B'00001110' ; R/W-POR State Bit Name: Bit Description - Setting
MOVWF T1CON ; -------0 R/W-0 TMR1ON: Timer1 On bit (0 = Stops Timer1)
; ------1- R/W-0 TMR1CS: Timer1 Clock Source Select bit (1 = External clock from pin RB6/T1OSO/T1CKI/PGC (on the rising edge))
; -----1-- R/W-0 T1SYNC: Timer1 External Clock Input Synchronization Control bit (1 = Do not synchronize external clock input)
; ----1--- R/W-0 T1OSCEN: Timer1 Oscillator Enable Control bit (1 = Oscillator is enabled)
; --00---- R/W-0 T1CKPS<1:0>: Timer1 Input Clock Prescale Select bits (00 = 1:1 Prescale value)
; 00------ R/W-0 Unimplemented: Read as ‘0’
CONFIGURE_INTERRUPT
BSF INTCON, GIE ; Enable Global Interrupts
BSF INTCON, PEIE ; Enable Peripheral Interrupts
BSF STATUS, RP0 ; Bank 1
BSF PIE1, TMR1IE ; Enable TMR1IE - TMR1 Overflow Interrupt Enable bit
BCF STATUS, RP0 ; Bank 0
CLRF PIR1 ; Clear Peripheral Interrupt Flags
BSF T1CON, TMR1ON ; Start TMR1
LOOP_PROG
NOP ; Do nothing
GOTO LOOP_PROG
DELAY_100mS ; Actual delay = 0.1 seconds = 100000 cycles
MOVLW 0X1F ;
MOVWF DELAYGPR1 ;
MOVLW 0X4F ;
MOVWF DELAYGPR2 ;
DELAY_100mS_0
DECFSZ DELAYGPR1, F ;
GOTO $+2 ;
DECFSZ DELAYGPR2, F ;
GOTO DELAY_100mS_0 ;
GOTO $+1 ; 99998 CYCLES
RETURN ; 4 cycles (including call)
END ; Directive 'end of program'