Code not working..help

Status
Not open for further replies.

Electrix

Member
I have tested two pieces of codes. Timer1 used at 32.678Khz to provide a timer of 16sec. PIC16F73 used. The First Code works..lights up LED after timer elapses..the Second Code does not work..ie PIC does not seem to wake up from sleep. My aim is to wake up the PIC from sleep using Timer1 Interrupt.
Please help !

CODE 1: (Working)
Code:
list		p=16f73		; list directive to define processor
	#include	<p16f73.inc>	; processor specific variable definitions
	
	__CONFIG _CP_OFF

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

;***** VARIABLE DEFINITIONS
w_temp		EQU	0x20		; variable used for context saving
w_temp1		EQU	0xA0		; reserve bank1 equivalent of w_temp 
status_temp	EQU	0x21		; variable used for context saving
pclath_temp	EQU	0x22		; variable used for context saving			

;**********************************************************************
	ORG     0x000             ; processor reset vector

	clrf    PCLATH            ; ensure page bits are cleared
  	goto    main              ; go to beginning of program


	ORG     0x004             ; interrupt vector location

	movwf   w_temp            ; save off current W register contents
	movf	STATUS,w          ; move status register into W register
	bcf     STATUS,RP0        ; ensure file register bank set to 0
	movwf	status_temp       ; save off contents of STATUS register
	movf	PCLATH,w	  ; move pclath register into w register
	movwf	pclath_temp	  ; save off contents of PCLATH register


; isr code can go here or be located as a call subroutine elsewhere


	bcf     STATUS,RP0        ; ensure file register bank set to 0
	movf	pclath_temp,w	  ; retrieve copy of PCLATH register
	movwf	PCLATH		  ; restore pre-isr PCLATH register contents
	movf    status_temp,w     ; retrieve copy of STATUS register
	movwf	STATUS            ; restore pre-isr STATUS register contents
	swapf   w_temp,f
	swapf   w_temp,w          ; restore pre-isr W register contents
	retfie                    ; return from interrupt



main

; remaining code goes here



CLRF T1CON 	; Stop Timer1, Internal Clock Source,
; T1 oscillator disabled, prescaler = 1:1

CLRF TMR1H ; Clear Timer1 High byte register
CLRF TMR1L ; Clear Timer1 Low byte register

CLRF INTCON ; Disable interrupts

BSF STATUS, RP0 ; Bank1

;movlw 0x01	;Enable TMR1 Interrupt
;movwf PIE1
CLRF PIE1 ; Disable peripheral interrupts

BCF STATUS, RP0 ; Bank0
CLRF PIR1 ; Clear peripheral interrupts Flags

MOVLW 0x3E ; External Clock source with oscillator
MOVWF T1CON ; circuitry, 1:8 prescaler, Clock source
; is asynchronous to device
; Timer1 is stopped

BSF T1CON, TMR1ON ; Timer1 starts to increment
;
; The Timer1 interrupt is disabled, do polling on the overflow bit
;
T1_OVFL_WAIT
BTFSS PIR1, TMR1IF
GOTO T1_OVFL_WAIT
;
; Timer has overflowed
;
BCF PIR1, TMR1IF
BANKSEL TRISA
clrf TRISA
BANKSEL PORTA
bsf PORTA,0

END                      ; directive 'end of program'

CODE 2: (Not Working)
Code:
	list		p=16f73		; list directive to define processor
	#include	<p16f73.inc>	; processor specific variable definitions
	
	__CONFIG _CP_OFF

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.






;***** VARIABLE DEFINITIONS
w_temp		EQU	0x20		; variable used for context saving
w_temp1		EQU	0xA0		; reserve bank1 equivalent of w_temp 
status_temp	EQU	0x21		; variable used for context saving
pclath_temp	EQU	0x22		; variable used for context saving			






;**********************************************************************
	ORG     0x000             ; processor reset vector

	clrf    PCLATH            ; ensure page bits are cleared
  	goto    main              ; go to beginning of program


	ORG     0x004             ; interrupt vector location

	movwf   w_temp            ; save off current W register contents
	movf	STATUS,w          ; move status register into W register
	bcf     STATUS,RP0        ; ensure file register bank set to 0
	movwf	status_temp       ; save off contents of STATUS register
	movf	PCLATH,w	  ; move pclath register into w register
	movwf	pclath_temp	  ; save off contents of PCLATH register


; isr code can go here or be located as a call subroutine elsewhere


	bcf     STATUS,RP0        ; ensure file register bank set to 0
	movf	pclath_temp,w	  ; retrieve copy of PCLATH register
	movwf	PCLATH		  ; restore pre-isr PCLATH register contents
	movf    status_temp,w     ; retrieve copy of STATUS register
	movwf	STATUS            ; restore pre-isr STATUS register contents
	swapf   w_temp,f
	swapf   w_temp,w          ; restore pre-isr W register contents
	retfie                    ; return from interrupt



main

; remaining code goes here
	
	

CLRF T1CON 	; Stop Timer1, Internal Clock Source,
; T1 oscillator disabled, prescaler = 1:1

CLRF TMR1H ; Clear Timer1 High byte register
CLRF TMR1L ; Clear Timer1 Low byte register

CLRF INTCON ; Disable interrupts

BSF STATUS, RP0 ; Bank1

movlw 0x01	;Enable TMR1 Interrupt
movwf PIE1
;CLRF PIE1 ; Disable peripheral interrupts

BCF STATUS, RP0 ; Bank0
CLRF PIR1 ; Clear peripheral interrupts Flags

MOVLW 0x3E ; External Clock source with oscillator
MOVWF T1CON ; circuitry, 1:8 prescaler, Clock source
; is asynchronous to device
; Timer1 is stopped

BSF T1CON, TMR1ON ; Timer1 starts to increment
;
; The Timer1 interrupt is disabled, do polling on the overflow bit
;
;T1_OVFL_WAIT
;BTFSS PIR1, TMR1IF
;GOTO T1_OVFL_WAIT
;
; Timer has overflowed
;
sleep
nop

		BCF PIR1, TMR1IF
		BANKSEL TRISA
		clrf TRISA
		BANKSEL PORTA
		bsf PORTA,0
		


	END                       ; directive 'end of program'
 
Both of your codes have no correct ending. I'm surprised that one of them even works.

The END directive is telling the MPASM that your code ends, but you have to actually do something in the code to prevent the PIC from executing instructions down the line. You can try something like:

GOTO $
 

i do not think that is a serious problem..the code works without the GOTO $, anyways thanks for pointing out..But in my second code the PIC does not come out of sleeo..have I done it right ?
 
I've only looked through it briefly, but I think you should first get it working with the interrupt and not using sleep. Then you can add the sleep part. Changing two things at once make it difficult to find the source of the problem.

Also, I just noticed two things:

1) Are you setting the T1SYNC bit? You need to set this bit so that Timer1 is NOT synchronized with the internal clock. Obviously, if you're synced with the internal clock and you put it to sleep....guess what happens?

2) Are you setting the TMR1CS bit? You need to set this bit so that Timer1 uses your external 32kHz crystal and not the internal system clock.

Check out Section 6.0 of the datasheet for information on the Timer1 Module.

Mike
 

Yes I have done both : I wrote 0x3E into T1CON register..
both still can't figure out the problem :roll:
 

Yes I have done both : I wrote 0x3E into T1CON register..
both still can't figure out the problem :roll:
 

Have you tried adding this anyway?, how do you know the PIC isn't coming out of sleep?, as your program stands it will run from the beginning again if it does come out of sleep (as you don't have anything preventing it at the end of the program, the program counter will run back round to zero).
 
A very common mistake is to forget to enable the global interrupt enable GIE and the peripheral interrupt enable PEIE bits in the INTCON register before going to SLEEP.
 
Finally..my punishment for not reading the datasheet throughly

Yes, I forgot the


movlw b'01000000'
movwf INTCON

Since i'm not going to the int vector location, i did not set the GIE bit. So, now my code is complete (apart from goto $+1) and the PIC does come out of sleep.

Nigel, there is one thing in your post I'm confused about, you said if goto $+1 is missing you say the PC rolls back and does everything all over, I agree that happens, but even with goto $+1, that can happen, right ? becaouse say i'm on the last locn. FFFF after that it would add 1 and PC would become 0000..please clarify this ... :roll:
[/code]
 
Electrix said:
becaouse say i'm on the last locn. FFFF after that it would add 1 and PC would become 0000..please clarify this ... :roll:

Well, if you're out of program memory, you have a bigger problem to worry about!... you probably need to shop around for a bigger PIC

But why goto $+1? Doesn't make much sense. Nigel suggested goto $, which is an endless loop that would still work even at the very last memory word location...
 

As Joel said, I never suggested 'goto $+1', but 'goto $' which is an endless loop - without that the program will restart as the program counter loops back to zero.

'Goto $+1' would be no help at all, it would simple continue as if it wasn't there.
 
It will take just milliseconds for the PIC to loop back to the starting point if there is no GOTO $ instruction.

For a PIC like F877 running at 20MHz, with 8K instructions memory, it will take just 1.64ms or less to loopback.

A GOTO $+1 helps a little bit by lengthening the time to 3.3ms.
 
eblc1388 said:
For a PIC like F877 running at 20MHz, with 8K instructions memory, it will take just 1.64ms or less to loopback.

A GOTO $+1 helps a little bit by lengthening the time to 3.3ms.

No it doesn't :lol:

It will only add 0.2uS to the time taken without it (one extra instruction cycle - difference between a NOP and a GOTO).
 
Nigel Goodwin said:
No it doesn't :lol:

You're absolutely right. I have somehow have in my mind all the remaining instructions being GOTO $+1.

I don't believe it myself.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…