Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

HELP with Timer 1 Please

Status
Not open for further replies.

3BABY

Member level 5
Joined
Jan 14, 2011
Messages
91
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
New Zealand
Activity points
2,252
Hi Guys,

im having major difficulty trying to create a delay of 765 Timer1 counts..

i just cannot get the interrupt flag to work..

ive tryed loading the High Byte with 253 as you can see in my code so the Low Byte will count up to 255 3 times.. but in MPLab SIM i cant see the High Byte incrementing and i donot get an interrupt..

i have read the datasheet and checked and re checked..

the only time i can get it to work is if i load timer1 High Byte with 255 and let the Low Byte count up to 255 and then it will set the interrupt bit.. but if I clear the interrupt bit and try to count up to 255 on the Low byte again.. it wont Skip to Next Instruction..

any help would be much appricated

Code:
       		BSF T1CON, RD16         ;= 1                    RD16: 16-Bit Read/Write Mode Enable bit
               BCF T1CON, T1RUN        ;= 0                    T1RUN:   Timer1 System Clock Status bit
               BCF T1CON, T1CKPS1      ;= 0                    T1CKPS1:T1CKPS0: Timer1 Input Clock Prescale Select bits
               BSF T1CON, T1CKPS0      ;= 1
               BCF T1CON, T1OSCEN      ;= 0                    T1OSCEN: Timer1 Oscillator Enable bit
               BCF T1CON, T1SYNC       ;= 0                    T1SYNC: Timer1 External Clock Input Synchronization Select bit
               BCF T1CON, TMR1CS       ;= 0                    TMR1CS: Timer1 Clock Source Select bit
                                                               ;                               1 = External clock from RC0/T1OSO/T13CKI pin (on the rising edge)
                                                               ;                               0 = Internal clock (FOSC/4)
               BCF T1CON, TMR1ON       ;= 0                    TMR1ON: Timer1 On bit




               BSF PIE1, TMR1IE   			; Timer1 interrupt enabled
               BCF     PIR1, TMR1IF                    ; clears timer1 interrupt flag bit



       		MOVLW 0x00             ;loading the Timer Low Byte
       		MOVWF TMR1L    


  
               MOVLW d'253'            ; loading the Timer HIgh Byte
               MOVWF TMR1H                     
      

               BSF T1CON, TMR1ON           ; STARTS TIMER1
AGAIN1  	BTFSS PIR1, TMR1IF
               GOTO AGAIN1

               BCF T1CON, TMR1ON                       ; STOPS TIMER1
               BCF     PIR1, TMR1IF                    ; clears timer1 interrupt flag bit


		;moves onto next part of program
 

Hi,

Assume you are still working on the 4550 ?

You do not show all your code, have you fully enabled the Interrupts ?

Code:
		bsf		INTCON,PEIE		; ENABLE PERIPH INT
		bsf		INTCON,GIE		; ENABLE GLOBAL INT
 

Hi,

Refer to PIC 18F2550,

That is the normal behavior of High-byte of Timer1. Like datasheet says that mapped high-byte (TMR1H) is only a "buffer". Actual high-byte of Timer1 is hidden.

This buffer (TMR1H) is not updated regularly; It happens only when we read/write TMR1L

When we read;
First we read TMR1L, at this moment actual-high byte copy it's value to "buffer TMR1H". Then we can read or see it (in mplab SIM).
Until we don't read TMR1L (like in assembly; movf TMR1L,W) we can't see real value of high-byte in TMR1H register.

If we want to write "actual-high byte";
first write our value (253) to buffer TMR1H (Now actual-high byte doesn't copy 253),
Then we write our value to TMR1L, at this moment value at "buffer TMR1H" will copy to actual high-byte.

So change your code like that and try.

Thank you,
 
Hi,

Assume you are still working on the 4550 ?

You do not show all your code, have you fully enabled the Interrupts ?

Code:
		bsf		INTCON,PEIE		; ENABLE PERIPH INT
		bsf		INTCON,GIE		; ENABLE GLOBAL INT

Hi ..

Yes still working with the 4550.. i have added your code and managed to get Timer1 to work.. but after abit of testing i removed the "Enable Global Int" as when i got the Timer 1 interrupt it send my program back to the start of my MAIN.. i understand what a "global" is but dont understand why it send me back to the start of my MAIN?

thanks for the reply btw :)
 

Hi,

How did you code ISR ?

Since high-priority-interrupt assign program counter to 0x0008, your ISR must be there.
(otherwise uC will do whatever at 0x0008 in program memory, may be your MAIN )

Also I refer TMR1H explanation to 18F2550, it is also valid for 18F4550 without any change.

Thank you,
 

Hi,

As Dinesh says it sounds like you have not set up the ISR correctly.
Have you followed the Microchip Template file ?

Once in the ISR do not 'call' or 'goto' out of it.
 

Attachments

  • 18F4550TEMP.rar
    1.3 KB · Views: 92

for starters i dont understand what an ISR is? thats probably the root of the problem..

in my program i am forced to use another timer while Timer 1 is still running.. Timer 3.. i have set it up in a similar way but cannot get the an interrupt flag to work.. if i use the following code:

a section of the setup
Code:
		BSF PIE2, TMR3IE   			; Timer1 interrupt enabled
		BCF	PIR2, TMR3IF			; clears timer1 interrupt flag bit

		BSF		INTCON, PEIE		; ENABLE PERIPH INT

in the program
Code:
AGAIN2  BTFSS PIR2, 0
	    GOTO AGAIN2

is there some way to handle the interrups of Timer 1 and Timer 3? something todo with the priority's?
 

Hi,

In your code of post_1, TMR1L was written first and then TMR1H; that is incorrect (see post_3 for explanation). Change it as follows.

MOVLW d'253' ; loading the Timer HIgh Byte
MOVWF TMR1H

MOVLW 0x00 ;loading the Timer Low Byte
MOVWF TMR1L

At first try don't use interrupt priority. Configure and enable timer1 & 2 in main_code. Associate interrupt service routine(ISR) in ROM location 0x0008. Then check check intended interrupt flags. If found a flag call relevant function.you
Your program can be started like below,

Code:
        CODE                                         ;starting of instructions, variables are defined earlier
MAIN_CODE	CODE	0x0000       ;In starting ROM-address direct to MAIN_START where main coding is at
	goto	MAIN_START
	
ISR_VECTOR	CODE	0x0008       ;In an interrupt, program-code-pointer comes here then directed to function INTERRUPT_VECTOR
	goto	INTERRUPT_VECTOR


MAIN_CODE
;Configure, enable timers and other code.......
................
................

INTERRUPT_VECTOR
; Check PIR2,TMR3IF for Timer3 and PIR1, TMR1IF for Timer1 and call relevant functions.
.................
................
END

Use following tool to get configuration values for timers relevant registers.
**broken link removed**
 

Hi,

In your code of post_1, TMR1L was written first and then TMR1H; that is incorrect (see post_3 for explanation). Change it as follows.

MOVLW d'253' ; loading the Timer HIgh Byte
MOVWF TMR1H

MOVLW 0x00 ;loading the Timer Low Byte
MOVWF TMR1L

At first try don't use interrupt priority. Configure and enable timer1 & 2 in main_code. Associate interrupt service routine(ISR) in ROM location 0x0008. Then check check intended interrupt flags. If found a flag call relevant function.you
Your program can be started like below,


Use following tool to get configuration values for timers relevant registers.
**broken link removed**

thank for the reply,

ive changed the Timer Low & High Byte loads and they are working now, i have also enabled
Code:
		BSF		INTCON, PEIE		; ENABLE PERIPH INT
		BSF		INTCON, GIE		    ; ENABLE GLOBAL INT

and used the interrupt vector.. and that works good for Timer 1.. what i dont understand is how do i get out of the "INTERRUPT_VECTOR" subroutine.. i think im confused with what wp100 said (below), and how do i reset the GLOBAL INTERRUPT?

wp100 said:

Hi,

As Dinesh says it sounds like you have not set up the ISR correctly.
Have you followed the Microchip Template file ?

Once in the ISR do not 'call' or 'goto' out of it.

does this mean at ORG 0x0008 or after youve BRA to "INTERRUPT_VECTOR"?

the problem i have now is i get the interrupt for Timer 1 the program goes to ORG 0x0008 then BRA to INTERRUPT_VECTOR and then check the flags to figure out which timer finished.. then i GOTO "start_timer3" .. it starts counting but i cant get an interrupt when i rolls over.. it just keeps counting?

thankyou for your replys.. they have been helpfull :)
 

thank for the reply,

and used the interrupt vector.. and that works good for Timer 1.. what i dont understand is how do i get out of the "INTERRUPT_VECTOR" subroutine.. i think im confused with what wp100 said (below), and how do i reset the GLOBAL INTERRUPT?

RETFIE is the command to exit from interrupt.(see datasheet for more info) When you enter to ISR (ie. program counter branches to 0x0008 when interrupt was detected) uC automatically disables GLOBAL INTERRUPT (ie GIE=0). At the end, when you return with RETFIE command uC automatically enables it (ie GIE=1).


the problem i have now is i get the interrupt for Timer 1 the program goes to ORG 0x0008 then BRA to INTERRUPT_VECTOR and then check the flags to figure out which timer finished.. then i GOTO "start_timer3" .. it starts counting but i cant get an interrupt when i rolls over.. it just keeps counting?

thankyou for your replys.. they have been helpfull :)

I think you have got it now, Timer3 was started INSIDE the "interrupt routine" where GIE=0, so timer3 can't trigger interrupt. Hope this helps you to solve it.
 

could anyone help me with this problem?

if i try this i get a value of "01000011" in VAR2 .. when it should be "00000100" correct? according to MPLAB SIM
Code:
			MOVLW b'01000100'	;manually loading VAR1			
			MOVWF VAR1, F	


			MOVLW VAR1

			 ANDLW b'00000111'
                  	MOVWF VAR2, F

any help would be much appreciated :)
 

Hi,

You are using the movlw VAR1, that does not retrieve the data from VAR1, it loads the memory address of VAR1 to W.

Movlw is used to load data eg. movlw 0x03 or movlw "K"

Use movf VAR1, W and it will work fine.

No need to use ,F after a movwf instrcution, source and destination already specified

If you use MPLABs Sim and open a Watch Window with Wreg, VAR1 and VAR2, you can single step though the code and see the registers changing.
 

Hi,

You are using the movlw VAR1, that does not retrieve the data from VAR1, it loads the memory address of VAR1 to W.

Thanks for the quick reply :cool:.. it seems im still abit confused between the difference in retrieving data and the memory address..
 

Hi,

Normally you do not bother with the Variables memory address, the whole point of you giving the variable a name,VAR1, is that the system takes care of the address for you.

All you have to do is define to the system what area of Ram it has to use for storing the variables.

So you tell it to start at Ram location 000h then it places your variables sequencially in that area.

All you need to do is movwf VAR1 to write data into it,
or movf VAR1,W to read it back out - though the data still remains in VAR1.

You used the movlw VAR1 which cause the system to load the memory address of VAR1, not its data.

You use movlw when you want to manually load in to W, a particular value like you did in your opening line
MOVLW b'01000100'
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top