Using Timer0-overflow in INT2

General discussion on mikroPascal for AVR.
Post Reply
Author
Message
Sascha
Posts: 17
Joined: 01 Jun 2008 23:00
Location: Germany

Using Timer0-overflow in INT2

#1 Post by Sascha » 15 Jun 2008 23:50

Hello,

Hanging on a problem using interrupts with an Mega16... I want to decode a DCF77 signal (german time signal from AM). For this I use INT2 which will be called on falling edge. This works. In the IRQ2-routine I activate Timer0 with IRQ on Overflow. This works not :-( The overflow IRQ will never be called.
If I activate Timer outside from IRQ2 everything works fine.

See the code (it is no complete code, just the way...)

Code: Select all

procedure Int_2;  org INT2addr;
Begin
 GICR.5:=0;           // INT2 Disable
 Multip:=0;           // Timer-Overlow Counter
 TIMSK.1:=1;          // ENable Timer0
 While Pinb.2=0 do Delay_us(1);  //Wait until Portb.2 gets High
 TIMSK.1:=0;         // Stop Timer0
 t:=TCNT0;             // Now got the time Portb.2 was low.
 TT:=(Multip*255)+T;   // Multip was Increased each time a timer overflow occured.
 WordToStr(TT,strTT);
 Usart1_Write_Text(strTT);
 GICR.5:=1;      // INT2 Enable
end;

Procedure Timer_1; org OVF0addr;
 Inc(Multip);  
end;


begin
 MCUCSR.6:=0;    // INT2 Config auf falling edge
 GICR.5:=1;      // INT2 Enable
 DDRb.2:=0;
 Portb.2:=0;
 TCCR0 :=  5;  // start timer with 1024 prescaler
 Multip:=0;
 SREG.7:=  1;  // enable global interrupt


If False then Begin  // Dummy calls for Linker
 ByteToStr(T,StrT);
 WordToStr(T,StrT);
 USART1_Write_Text('dummy');
end;

While True do nop;
end.
First I tried to use the 16bit Timer1. Probably this would work for me, because there won't be an overflow, but I even don't get it to work :-(
(TCNT1H and TCNT1L have always the same values and an overflow nerver occurs)

I'm soooo excited on the next release/beta of mP which will be hopefully published still this month :-) Ok, next month would be early enough if you can give me a workaround for the above problem ;-)

TIA
Sascha

Sascha
Posts: 17
Joined: 01 Jun 2008 23:00
Location: Germany

#2 Post by Sascha » 16 Jun 2008 01:23

Oops, a mistake..

Code: Select all

TIMSK.1:=1;          // Must be  TIMSK.0:=1;

But still doesn't work.

Sascha[/code]

Sascha
Posts: 17
Joined: 01 Jun 2008 23:00
Location: Germany

#3 Post by Sascha » 19 Jun 2008 19:37

Getting no answer, no help, no support for my problem... Hm, thats life... But I remember someone said - "In future all of our compilers will have the same quality and treatment." It seems that the future has not began until now....

Life is to search for an other solution, too. The simple answer is using Bascom. My current project (an DCF77-alarm clock, with 10digit Keypad, MP3 capability, 7 different alarm times...) will probably need a multiprocessor layout... So, the MP3 thing will be done with mPascal, maybe...

Sascha

User avatar
milan
mikroElektronika team
Posts: 1013
Joined: 04 May 2006 16:36
Contact:

#4 Post by milan » 25 Jun 2008 14:53

Hi,

sorry for the late reply.
We are working on a big revision of our AVR compilers, we are making a huge redesign and we expect that to fix most of the reported bugs.

I can't compile your code, can you make and post example that can reproduce the problem.

Sascha
Posts: 17
Joined: 01 Jun 2008 23:00
Location: Germany

#5 Post by Sascha » 25 Jun 2008 23:44

Ok, below the program... I use it with an Mega16 clocked at 16Mhz. Using the 8bit Timer0 with 1024 clock divider, a delay of about 18 ms will produce a Timeroverflow.

The code is now configured for using irq on overflow. You will see, that Multip will never be increased. But if you Disable Timer2 and uncomment code in the main loop, it will.

Code: Select all


program TimerTest;

Var
 Multip:Word;
 strT:String[3];
 StrMultip:String[20];
 t:Byte;

Procedure Timer_0; org OVF0addr;
begin
 Inc(Multip);
end;



procedure Int_2;  org INT2addr;
Begin
 Usart1_Write_Text('INT2 ');
 GICR.5:=0;                    // INT2 Disable
 Multip:=0;
 TCNT0:=0;                     //Reset Timer Value
 TIFR.0:=1;                   // Reset "Overflow happend"
 TIMSK.0:=1;                  // Enable IRQ on Overflow

 Delay_ms(18);

 t:=TCNT0;                    //Read Timer0 Value
 TIMSK.0:=0;                  // Disable IRQ on overflow
 ByteToStr(T,StrT);
 ByteToStr(Multip,StrMultiP);
 Usart1_Write_Text(strMultip);
 Usart1_Write_Text(' ');
 Usart1_Write_Text(strT);
 Usart1_Write_Text(''+#13+#10);
 GICR.5:=1;      // INT2 Enable
end;


begin
 Usart1_Init(9600);

 TCCR0 :=  5;  // start timer with 1024 prescaler
 MCUCSR.6:=0;    // INT2 Config auf Falling=0 Rising=1
 GICR.5:=1;      // INT2 Enable
// GICR.5:=0;  // Variation2 - without timer...
 SREG.7:=  1;  // enable global interrupt


While true do
Begin
   nop;
// Usart1_Write_Text('Main ');
// Multip:=0;
// TCNT0:=0;                     //Reset Timer Value
// TIFR.0:=1;                   // Reset "Overflow happend"
// TIMSK.0:=1;                  // Enable IRQ on Overflow

// Delay_ms(18);

// t:=TCNT0;                    //Read Timer0 Value
// TIMSK.0:=0;                  // Disable IRQ on overflow
// ByteToStr(T,StrT);
// ByteToStr(Multip,StrMultiP);
// Usart1_Write_Text(strMultip);
// Usart1_Write_Text(' ');
// Usart1_Write_Text(strT);
// Usart1_Write_Text(''+#13+#10);
// Delay_ms(300);
end;


If False then Begin
 ByteToStr(T,StrT);
 Usart1_Write_Text('OVER');
end;
end.



milan wrote:
We are working on a big revision of our AVR compilers, we are making a huge redesign and we expect that to fix most of the reported bugs.
I know. Read it so often the last weeks... Suprise me and show something more than promises. :->
PS: Please answer my other question about Mega644p support, too


Sascha

User avatar
milan
mikroElektronika team
Posts: 1013
Joined: 04 May 2006 16:36
Contact:

#6 Post by milan » 26 Jun 2008 09:21

Hi,
ATmega16 Datasheet wrote:•Bit 7 – I: Global Interrupt Enable
The Global Interrupt Enable bit must be set for the interrupts to be enabled.
The individual interrupt enable control is then performed in separate control registers.
If the Global Interrupt Enable Register is cleared, none of the interrupts
are enabled independent of the individual interrupt enable settings.
The I-bit is cleared by hardware after an interrupt has occurred, and is set by the RETI instruction to enable subsequent interrupts.
The I bit can also be set and cleared by the application with the SEI and CLI instructions,
as described in the Instruction Set Reference.
Add SEI inside INT2 ISR

Code: Select all

procedure Int_2;  org INT2addr;
Begin
 SEI;                                 // added
 Usart1_Write_Text('INT2 ');
 ...
I tried it on EasyAVR5A, Multip is not zero anymore.

Sascha
Posts: 17
Joined: 01 Jun 2008 23:00
Location: Germany

#7 Post by Sascha » 26 Jun 2008 21:05

Hi,
milan wrote: Add SEI inside INT2 ISR
Ahh, f***! Yes, now it works! Thanks!

Setting all the timer and IRQ registers are really cryptic. Would be a good idea to do it in more pascal way... Just so, that user don't need to fight with the datasheet and puzzle out the correct register.

Sascha

Post Reply

Return to “mikroPascal for AVR General”