PDA

View Full Version : TMR2 not working..



sirvo
- 1st August 2007, 20:39
Hello..

I'm trying to make 16f88 'interrupt' every 500ms. TMR0/1 are busy. So, I've set TMR2 to interrupt every 1ms and then count var TMR2_clock till 500. But, it is interrupting every 3ms or something... Would you help me?



'------- initial --------------------
TMR2_clock VAR WORD
OPTION_REG = %00000000
INTCON = %11000000 ' enable interrupts
TRISB = %00000000 ' portb all output
TRISA = %00111111 ' some analog inputs
ANSEL = %00001111 ' some analog inputs
CMCON = %00000111 ' turn of comparators
ADCON1 = %10000000' right justified
T2CON = %00000011 ' TMR2 prescale 1:16
'---------------------------------------------------
TMR2_clock = 0


Lcdout $FE,1 ' clear screen

PR2 = 194 ' load tmr2 PR2 to reset every 1ms
PIE1.1 = 1 ' enable TMR2 interrupt
PIR1.1 = 0 ' disabled interrupt flag - TMR2
T2CON.2 = 1 ' turn TMR2 on

ON INTERRUPT GOTO tick

MAIN:
' do nothing
GOTO MAIN

DISABLE
tick:
PR2 = 194 'reload PR2
TMR2_clock = TMR2_clock + 1
Lcdout $FE,$A0, DEC TMR2_clock
IF TMR2_clock = 500 THEN
TMR2_clock = 0
' Set some flag..
ENDIF
PIR1.1 = 0
resume
ENABLE


Thanks..!

Sylvio

Darrel Taylor
- 1st August 2007, 21:03
The default LCD_COMMANDUS is 2000 us. (2 ms)
So moving the cursor to a specific location within the ISR makes it wait that much longer before it Resume's.

Add in the 50us for each character displayed, and the 1ms for the interrupt itself, and you get "3ms or something...".

HTH,

sirvo
- 1st August 2007, 21:15
Right.. i just put the LCDOUT command to compare the count with my hand watch. So, the routine is correct.. thanks Darrel.

Sylvio

Darrel Taylor
- 1st August 2007, 21:38
... So, the routine is correct..

Good to go ...
One thing to note ...
You don't need to reload PR2 each time. It doesn't change.
<br>

sirvo
- 1st August 2007, 21:41
0.o I've read that a thousand times and still reloaded..Thanks again..

Sylvio

sirvo
- 1st August 2007, 22:52
HI Again... I have tried again taking the LCDOUT command out of interrupt routine and putting inside the MAIN sub. NOthing! It is running crazy and I've also tried setting postscaler 1:16 or/and prescaler 1:16 and still nothing. Does the code look really correct? What I want is to set any flag every 500ms using TMR2... A little help please?

Thanks again.. Sylvio, :)



'------- initial --------------------
TMR2_clock VAR WORD
OPTION_REG = %00000000
INTCON = %11000000 ' enable interrupts
TRISB = %00000000 ' portb all output
TRISA = %00111111 ' some analog inputs
ANSEL = %00001111 ' some analog inputs
CMCON = %00000111 ' turn of comparators
ADCON1 = %10000000' right justified
T2CON = %00000011 ' TMR2 prescale 1:16 --> TESTED WITH POST and PRESCALER (1:16)
'---------------------------------------------------
TMR2_clock = 0


Lcdout $FE,1 ' clear screen

PR2 = 194 ' load tmr2 PR2 to reset every 1ms
PIE1.1 = 1 ' enable TMR2 interrupt
PIR1.1 = 0 ' disabled interrupt flag - TMR2
T2CON.2 = 1 ' turn TMR2 on

ON INTERRUPT GOTO tick

MAIN:
Lcdout $FE,$A0, DEC TMR2_clock ---> CHANGED
GOTO MAIN

DISABLE
tick:
TMR2_clock = TMR2_clock + 1
IF TMR2_clock = 500 THEN
TMR2_clock = 0
' Set some flag..
ENDIF
PIR1.1 = 0
resume
ENABLE

Darrel Taylor
- 1st August 2007, 23:03
You've just moved the time to write to the LCD to a different place.

When using ON INTERRUPT, it can't handle an interrupt until the current statement has finshed executing.

If you want to have a 1ms interrupt, then nothing else in the program can take more than 1ms to execute, and really should be much less than that.

If you were using ASM interrupts, then it could interrupt the LCDOUT statement, so there wouldn't be a conflict.

Or you could use Instant Interrupts to do the same thing with Basic language interrupts without the ON INTERRUPT.
<br>

sirvo
- 2nd August 2007, 03:27
OK. Let's try the instant interrupts. I have just added the II codes and it looks like this:



@ ERRORLEVEL -306 ; turn off crossing page boundary message
@ __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

ASM
;T0IF = TMR0IF
;T0IE = TMR0IE
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR2_INT, _tick, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR2_INT ; Enable Timer 1 Interrupts

'------- initial --------------------
TMR2_clock VAR WORD
OPTION_REG = %00000000
' INTCON = %11000000 ' enable interrupts ->NOW COMMENTED
TRISB = %00000000 ' portb all output
TRISA = %00111111 ' some analog inputs
ANSEL = %00001111 ' some analog inputs
CMCON = %00000111 ' turn of comparators
ADCON1 = %10000000' right justified
T2CON = %00000011 ' TMR2 prescale 1:16 --> TESTED WITH POST and PRESCALER (1:16)
'---------------------------------------------------
TMR2_clock = 0


Lcdout $FE,1 ' clear screen

PR2 = 194 ' load tmr2 PR2 to reset every 1ms
'PIE1.1 = 1 ' enable TMR2 interrupt -> NOW COMMENTED
'PIR1.1 = 0 ' disabled interrupt flag - TMR2 -> NOW COMMENTED
T2CON.2 = 1 ' turn TMR2 on

'ON INTERRUPT GOTO tick -> -> NOW COMMENTED

MAIN:
Lcdout $FE,$A0, DEC TMR2_clock ---> CHANGED
GOTO MAIN


tick:
TMR2_clock = TMR2_clock + 1
IF TMR2_clock = 500 THEN
TMR2_clock = 0
' Set some flag..
ENDIF
@ INT_RETURN


Well.. the LCD gets cleared. No text at all..

What's wrong?

Thank you.

Sylvio

Darrel Taylor
- 2nd August 2007, 03:59
What pins are the LCD hooked up to?

Without the DEFINES, the LCD defaults to PORTA 0-3 for the data, but those pins are configured for analog.

You had the same settings before and said it was working so I assumed there were defines that you didn't show. But now it looks like there aren't any.
<br>

sirvo
- 2nd August 2007, 04:10
The lcd defines are the same. It's hooked up on PORTB. I did not change defines.
I've added the two .bas instant interrupt files, added the asm code and changed all the interrupt statement to the instant interrupt. I have no ideia where the problem is located to.. i'm still trying to do so..

I still have some doubts about instant interrupts and timer using, like reloading and also configuring Option_reg or intcon...

did not you really read anything wrong in the code posted?

Thanks for the attention Darrel.

Darrel Taylor
- 2nd August 2007, 04:35
The lcd defines are the same. It's hooked up on PORTB. I did not change defines.

That's the part I don't get. There are no DEFINEs for the LCD. So it won't work on PORTB. Unless you just didn't include them in the post.


did not you really read anything wrong in the code posted?

No I don't.
I've run the program here, with a few changes. Using a 16F877.

I did change the $A0 in the LCDOUT statement.
Changed it to $80. All works fine.
<br>

sirvo
- 2nd August 2007, 04:40
That's the part I don't get. There are no DEFINEs for the LCD. So it won't work on PORTB. Unless you just didn't include them in the post.


I'm sorry. I did not post them here, but they are correct.
I'll try again later...I'm sleepy now..

Thank you very much..

sirvo
- 2nd August 2007, 15:24
As I have said, the LCD gets a cleared screen. IN order to test the ASM routine of instant interrupt, I have added 2 LCDOUT commands. The first before the ASM routine and the Second after the ASM ROUTINE.



' LCD defines on portB
' All registers set
' just like the code posted before

Pause 1000

LCDOUT $FE, $80, "TEST 1"

ASM
;T0IF = TMR0IF
;T0IE = TMR0IE
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR2_INT, _tick, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR2_INT ; Enable Timer 1 Interrupts

LCDOUT $FE, $80, "TEST 2"

'and the rest of the code goes i here..



Well.. Now the LCD displays only "TEST 1".. it seems that the pointer is stuck in the ASM lines... Anything to say?

Thanks!

sirvo
- 2nd August 2007, 17:41
Darrel.... are you there?

I 'discovered' that if I set PR2 to any number it DO NOT interrupt...
If I let PR2 'unset' it interrupts normal...

In this case I am going to use it in this way, letting TMR2 count until 0FFh. Anyway, do you know what is hapening?

Thanks...

Darrel Taylor
- 2nd August 2007, 17:46
Working on it.

Building a 16F88 breadboard now. (Last couple hours)

I'll get back to you.
<br>

Darrel Taylor
- 2nd August 2007, 18:54
Got it working, and I only found one problem.

The 194 would be for timer 0. Where it counts from that number until it overflows at 256, which takes 62 counts.

Timer 2 works a little different.
It counts from 0 up to the number in PR2, then resets to 0 again.
So 62 is the number for PR2 @ ~1ms. It's actually 62.5, so we may need to drop the prescaler to 4 and use 250 for PR2 if you want more accuracy.

I do not see any problems with the interrupt portions, and it all works fine here. Here's the breadboard I just put together.

<img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1902&stc=1&d=1186076299"> (http://www.pbpgroup.com/files/100_0194.JPG)


And here's the program I'm using ...
<font color="#0000FF"><b><i>; http://www.picbasic.co.uk/forum/showthread.php?t=6818

</i></b></font><font color="#000080">@ ERRORLEVEL -306 </font><font color="#0000FF"><b><i>; turn off crossing page boundary message
</i></b></font><font color="#000080">@ __CONFIG _CONFIG1, _CP_OFF &amp; _DEBUG_OFF &amp; _WRT_PROTECT_OFF &amp; _CPD_OFF &amp; _LVP_OFF &amp; _BODEN_OFF &amp; _MCLR_OFF &amp; _PWRTE_ON &amp; _WDT_OFF &amp; _XT_OSC

</font><font color="#008000"><b>DEFINE </b></font><b>LCD_DREG PORTB </b><font color="#0000FF"><b><i>' LCD data port
</i></b></font><font color="#008000"><b>DEFINE </b></font><b>LCD_DBIT </b><font color="#800000"><b>0 </b></font><font color="#0000FF"><b><i>' LCD data starting bit 0 or 4
</i></b></font><font color="#008000"><b>DEFINE </b></font><b>LCD_RSREG PORTB </b><font color="#0000FF"><b><i>' LCD register select port
</i></b></font><font color="#008000"><b>DEFINE </b></font><b>LCD_RSBIT </b><font color="#800000"><b>4 </b></font><font color="#0000FF"><b><i>' LCD register select bit
</i></b></font><font color="#008000"><b>DEFINE </b></font><b>LCD_EREG PORTB </b><font color="#0000FF"><b><i>' LCD enable port
</i></b></font><font color="#008000"><b>DEFINE </b></font><b>LCD_EBIT </b><font color="#800000"><b>5 </b></font><font color="#0000FF"><b><i>' LCD enable bit
</i></b></font><font color="#008000"><b>PAUSE </b></font><font color="#800000"><b>500 </b></font>: <font color="#008000"><b>LCDOUT </b></font><font color="#800000"><b>$FE</b></font>,<font color="#800000"><b>1 </b></font>: <font color="#008000"><b>PAUSE </b></font><font color="#800000"><b>250 </b></font><font color="#0000FF"><b><i>; Initialize LCD

</i></b></font><b>LED </b><font color="#008000"><b>VAR </b></font><b>PORTA</b>.<font color="#800000"><b>4

</b></font><font color="#008000"><b>INCLUDE </b></font><font color="#FF0000">&quot;DT_INTS-14.bas&quot; </font><font color="#0000FF"><b><i>' Base Interrupt System
</i></b></font><font color="#008000"><b>INCLUDE </b></font><font color="#FF0000">&quot;ReEnterPBP.bas&quot; </font><font color="#0000FF"><b><i>' Include if using PBP interrupts

</i></b></font><font color="#008000"><b>ASM
</b></font><font color="#0000FF"><b><i>;T0IF = TMR0IF
;T0IE = TMR0IE
</i></b></font><font color="#000080">INT_LIST macro </font><font color="#0000FF"><b><i>; IntSource, Label, Type, ResetFlag?
</i></b></font><font color="#000080">INT_Handler TMR2_INT, _tick, PBP, yes
endm
INT_CREATE </font><font color="#0000FF"><b><i>; Creates the interrupt processor
</i></b></font><font color="#008000"><b>ENDASM
</b></font><font color="#000080">@ INT_ENABLE TMR2_INT </font><font color="#0000FF"><b><i>; Enable Timer 1 Interrupts

'------- initial --------------------
</i></b></font><b>TMR2_clock </b><font color="#008000"><b>VAR WORD
</b></font><b>OPTION_REG </b>= <font color="#800000"><b>%00000000
</b></font><b>TRISB </b>= <font color="#800000"><b>%00000000 </b></font><font color="#0000FF"><b><i>' portb all output
</i></b></font><b>TRISA </b>= <font color="#800000"><b>%00111111 </b></font><font color="#0000FF"><b><i>' some analog inputs
</i></b></font><b>ANSEL </b>= <font color="#800000"><b>%00001111 </b></font><font color="#0000FF"><b><i>' some analog inputs
</i></b></font><b>CMCON </b>= <font color="#800000"><b>%00000111 </b></font><font color="#0000FF"><b><i>' turn of comparators
</i></b></font><b>ADCON1 </b>= <font color="#800000"><b>%10000000</b></font><font color="#0000FF"><b><i>' right justified
</i></b></font><b>T2CON </b>= <font color="#800000"><b>%00000011 </b></font><font color="#0000FF"><b><i>' TMR2 prescale 1:16
'---------------------------------------------------
</i></b></font><b>TMR2_clock </b>= <font color="#800000"><b>0

</b></font><font color="#008000"><b>LCDOUT </b></font><font color="#800000"><b>$FE</b></font>,<font color="#800000"><b>1 </b></font><font color="#0000FF"><b><i>' clear screen

</i></b></font><b>PR2 </b>= <font color="#800000"><b>62 </b></font><font color="#0000FF"><b><i>' load tmr2 PR2 to reset every 1ms
</i></b></font><b>T2CON</b>.<font color="#800000"><b>2 </b></font>= <font color="#800000"><b>1 </b></font><font color="#0000FF"><b><i>' turn TMR2 on

</i></b></font><b>MAIN</b>:
<font color="#008000"><b>LCDOUT </b></font><font color="#800000"><b>$FE</b></font>,<font color="#800000"><b>$80</b></font>, <font color="#008000"><b>DEC </b></font><b>TMR2_clock</b>,<font color="#FF0000">&quot; &quot; </font><font color="#0000FF"><b><i>;---&gt; CHANGED
</i></b></font><font color="#008000"><b>GOTO </b></font><b>MAIN


tick</b>:
<b>TMR2_clock </b>= <b>TMR2_clock </b>+ <font color="#800000"><b>1
</b></font><font color="#008000"><b>IF </b></font><b>TMR2_clock </b>= <font color="#800000"><b>500 </b></font><font color="#008000"><b>THEN
</b></font><b>TMR2_clock </b>= <font color="#800000"><b>0
</b></font><font color="#008000"><b>TOGGLE </b></font><b>LED
</b><font color="#0000FF"><b><i>' Set some flag..
</i></b></font><font color="#008000"><b>ENDIF
</b></font><font color="#000080">@ INT_RETURN
</font>

The LED flashes at almost 1 hz, and the numbers on the LCD are counting away.

I say "almost" due to the Timer 2 prescaler. For better accuracy, use ...
T2CON = %00000001 ' TMR2 prescale 1:4
PR2 = 250 ' load tmr2 PR2 to reset every 1ms

sirvo
- 2nd August 2007, 20:31
Hi.
Darrel, my native language isnīt english and because of that there are some words still not added in my english vocabulary but I am really amazed to see someone like you that helped me a lot and obtained nothing for it. Thank you very much for working on TMR2 stuffs and solving my problem.

Darrel Taylor
- 2nd August 2007, 23:17
You're welcome Sylvio.

I hope that means you have it working too.

Regards,