Go Down

Topic: Arduino Mega board taking 7 microsec for timer interrupt with No prescaling  (Read 671 times) previous topic - next topic

prakashvenugopal

Hi,

    I am using the Arduino Mega 2560 board to generate the 1 usec timer interrupt.
 For 1 count, i.e     timer1_counter = 65534, it is taking  7 usec to go to the timer interrupt routine.
I need 1 usec timer interrupt to scan my Program. Let us know if i am making any mistake.
What is the Problem.?

Here is the code:

Code: [Select]
cli();
TCCR1A = 0x00;
TCCR1B = 0x00;
// Set timer1_counter to the correct value for our interrupt interval
//timer1_counter = 65534;
TCNT1 = timer1_counter; // preload timer
TCCR1B |= (1 << CS10); // No prescaling
//TCCR1B = 0x01;  //No prescaling
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt
//TIMSK1 = 0x01 ; //set TOIE1 // enable timer overflow interrupt
sei();



Code: [Select]
ISR(TIMER1_OVF_vect) // interrupt service routine
{
TCNT1 = timer1_counter; // preload timer
//digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
PORTB=0Xff;
PORTB=0X00;
}


Kindly let us know.

Regards,
V. Prakash


GolamMostafa

@OP

You are driving TC1 by 16 MHz clock. You want the TOV1 to happen after the elapse of 1 us time. Therefore, the TC1 will have to count only 1 pulse to undergo overflow/rollover. So, the pre-set value for TCNT1 would be:

Code: [Select]
0x10000 = pre-set count + number_of_pulse_to_count
==> pre-set count = 0x10000 - 1
==> pres-et count = 0xFFFF

TCNT1 = 0xFFFF;      //load the pre-set count

prakashvenugopal

Hi,

Thanks for the reply. I tried with

TCNT1 = 65534 (0xFFFE) , it takes 2.88 usec to enter into the timer interrupt routine and complementing the port
TCNT1 = 65535 (0xFFFF) , it takes 2.94 usec to enter into the timer interrupt routine and complementing the port.

But i need to scan my program with 1 usec. what is the solution? How can i do this? Please let us know.

Code: [Select]
cli();
TCCR1A = 0x00;
TCCR1B = 0x00;
// Set timer1_counter to the correct value for our interrupt interval
timer1_counter = 65535;
TCNT1 = timer1_counter; // preload timer
TCCR1B |= (1 << CS10); // No prescaling
//TCCR1B = 0x01;  //No prescaling
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt
//TIMSK1 = 0x01 ; //set TOIE1 // enable timer overflow interrupt
sei();



Code: [Select]
ISR(TIMER1_OVF_vect) // interrupt service routine
{
TCNT1 = timer1_counter; // preload timer
//digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
PORTB=0Xff;       //port high
PORTB=0X00;      //port low
}


Kindly let us know.

Regards,
V. Prakash

cattledog

Quote
But i need to scan my program with 1 usec.
What does this mean--"Scan"?

Why do you want to toggle PORTB every microsecond? What else is your program doing?

westfw

Quote
I need 1 usec timer interrupt
You're can't realistically get an interrupt every microsecond on a 16MHz AVR.
It takes 8 cycles (minimum) just to enter and exit the interrupt - that's half of your cycle budget.

Your recent code ends up looking like:

ISR(TIMER1_OVF_vect) // interrupt service routine
{
 576:   1f 92           push    r1
 578:   0f 92           push    r0
 57a:   0f b6           in      r0, 0x3f
 57c:   0f 92           push    r0
 57e:   11 24           eor     r1, r1
 580:   8f 93           push    r24
 582:   9f 93           push    r25
TCNT1 = timer1_counter; // preload timer
 584:   80 91 1c 01     lds     r24, 0x011C    ;2 cycles
 588:   90 e0           ldi     r25, 0x00      ;1 cycle
 58a:   90 93 85 00     sts     0x0085, r25    ;2 cycles
 58e:   80 93 84 00     sts     0x0084, r24    ;2 cycles
//digitalWrite(ledPin, digitalRead(ledPin) ^ 1)
PORTB=0Xff;
 592:   8f ef           ldi     r24, 0xFF       ; 1 cycle
 594:   85 b9           out     0x05, r24       ; 1 cycle

PORTB=0X00;
 596:   15 b8           out     0x05, r1        ; 1 cycle
}

 598:   9f 91           pop     r25
 59a:   8f 91           pop     r24
 59c:   0f 90           pop     r0
 59e:   0f be           out     0x3f, r0
 5a0:   0f 90           pop     r0
 5a2:   1f 90           pop     r1
 5a4:   18 95           reti


Even if you were to get rid of the context save and restore (which is almost possible, given that you don't do any math), you still have the code in red, which is 10 cycles.   And the cpu will execute at least one instruction in between interrupts, so that's at least 19 cycles, which is more than 1 microsecond...

Edit: oops - that timing calculation is for an ATmega328.  It'll be somewhat slower on an ATmega2560.

prakashvenugopal

Hi,

    Thanks for the reply. Not only Port complement is my task. I have to do my whole logic in 1 usec timer interrupt.

So from the post, i understand that in Atmega 2560 with 16mhz cannot be used for 1 usec timer interrupt

Shall i go with Arduino Due board with 84Mhz. Is this possible?

I had interface the Sainsmart 3.2" TFT Touchscreen with Atmega 2560 and i already did all the code for the same.

Here is the link for Sainsmart 3.2" TFT Touchscreen with Atmega 2560  Board.

https://www.amazon.in/SainSmart-Display-Adjustable-Arduino-Mega2560/dp/B008FWSH3C

Shall i replace the Atmega 2560 Board with Arduino Due board. Is it compatible with the Sainsmart display.

Please let us know the Arudino Due board is Hardware and software compatible with Sainsmart 3.2" Touchscreen Display?

As i did all my code with Atmetga 2560 board, shall i use my directly use this code to Arduino Due board?
Please let us know.

Regards,
V. Prakash



Grumpy_Mike

Quote
Please let us know the Arudino Due board is Hardware and software compatible with Sainsmart 3.2" Touchscreen Display?
Probably it is not. A Due ( which is now obsolete ) runs on 3V3 and so does all the signals. Where as the Mega runs from 5V.

As to the software then it depends if any of it uses direct port addressing and things like timers, if so then it is not software compatible either.

Quote
I have to do my whole logic in 1 usec timer interrupt.
So kind of you to let us know so late in this thread. Glad to see your are keeping what you call "my whole logic" a secrete, otherwise we might have been able to help more. 

prakashvenugopal

Hi,

 Thanks for the reply. There is nothing secret in it. I have to turn ON the LEDs with the settings :1 to 9999. minimum :1 usec to Maximum: 9.9msec. 

So there is any solution for this problem to arrive it with 1 usec resolution.? If Arduino Due is obsolete, Please let us know which board can be used which supports Sainsmart 3.2" TFT touchscreen and also the 1usec timer interrupt.

Regards,
V. Prakash


westfw

Timer1 should be able to do it (in hardware), if you can live with the constrained output pin.
It should have 500ns resolution (clocked with F_CPU/8) - you can clock at the full F_CPU rate (16MHz), but then you wouldn't be able to set 9999us in the 16bit counter field.


https://playground.arduino.cc/Code/Timer1/

Grumpy_Mike

Quote
I have to turn ON the LEDs with the settings :1 to 9999. minimum :1 usec to Maximum: 9.9msec.
You want to turn on an LED for a period of 1uS! Why is that and what will it do for you?

Quote
Please let us know which board can be used which supports Sainsmart 3.2" TFT touchscreen and also the 1usec timer interrupt.
There isn't one. The form factor has changed, all the fast boards are Uno shaped or smaller and they all run off 3V3 and not 5V.

So you will have to do some mechanical adaptation and logic level shifting to get anything to drive one these days.

prakashvenugopal

Quote
You want to turn on an LED for a period of 1uS! Why is that and what will it do for you?
To reduce the current consumption.



Quote
There isn't one. The form factor has changed, all the fast boards are Uno shaped or smaller and they all run off 3V3 and not 5V.

So you will have to do some mechanical adaptation and logic level shifting to get anything to drive one these days.
Do you have any example of some mechanical adaptation and logice level shifting to drive. Please share. it will be helpful for me to do it.

Regards,
V. Prakash

Grumpy_Mike

Quote
To reduce the current consumption.
OH FFS - do you have any idea what you are doing? As well as reducing the current you will be reducing the brightness to virtually zero.

Quote
Do you have any example of some mechanical adaptation
No. But is is simply a matter of wiring the pins used on the shield to the corresponding pins through the appropriate level shifter.

Quote
ogice level shifting to drive
You could use bi-directional logic level shifters but it is a bit of a waste as you only want single direction level shifters. But I will suppose that using them will not require you to actually think.
https://www.rapidonline.com/adafruit-757-logic-level-converter-i2c-safe-bi-directional-4-channel-75-0567

For 3V3 signals to 5V signals use a 74HCT14 powered by 5V. For a 5V to 3V3 use a voltage divider with 1K down to ground and 510R in line with the 5V signal.

Smajdalf

If your aim is dimming a LED you may use a hardware timer to generate the pulse. Arduino Uno is more than capable for this.

OH FFS - do you have any idea what you are doing? As well as reducing the current you will be reducing the brightness to virtually zero.
OP wants probably PWM the LED with frequency 100Hz. 1us pulse means 0.01% duty. It may seem very low but it is only 4 orders of magnitude less compared to the full brightness. Far from "virtually zero", the dynamic range of human eye is much wider.
How to insert images: https://forum.arduino.cc/index.php?topic=519037.0

prakashvenugopal

Hi,

      Thanks for the reply.

Quote
prakashvenugopal created a new thread (well three of them actually) for this topic:
https://forum.arduino.cc/index.php?topic=617473
I am not able to open this link. If i try to open the above link, it is showing the Error screen. I had attached the Error screen for your reference. Please clear.

Regards,
V. Prakash



Go Up