send specific number of pulses at a specific frequency

I spent about 2 hours reading the guides and forums about this topic but have not managed to make it work. I want to use my nano to test some digital circuits I’m building. What I want is to see how fast I can make them run as-expected. To do this I want to send a specific number of pulses ( could be any 8 bit number of pulses really ) out of a PIN at a specific frequency. So for instance I want to send 255 pulses out at 10Mhz and then STOP after the 255th pulse… Maybe wait in a loop until the button is pressed and then send the next batch. or change the speed up… etc. This would allow me to inspect the state of the circuit to see if it worked as expected.

After a few hours I figured out how the timer registers work and know how to make it produce a pmw frequency now, but not how to stop after x pulses:

#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIMER1_OVF_vect)
{
 // I'm not sure if I have enough time to run something here
}


void setup ()
{
  pinMode (9, OUTPUT) ;
  TCCR1A = 0xE2 ;  // pins 9, mode 14, fast 16 bit PWM // 11100010
  TCCR1B = 0x1A ;  // clock divided by 8                // 00011(010) last 3 bits
  ICR1  = 20000-1 ;  // 20000 * 8 = 160000 clocks = 10ms
  OCR1A = 10000-1 ;  // 50% duty cycle for pin 9
  TCNT1 = 0x0000 ;  // Set timer to 0. I think it counts 'up' to 20k from here then sets the TOV1 flag
  
  // TIFR1 |= 1 << TOV1;  // resets the TOV1 flag ( top of value for timer 1 )
  // TIMSK1 |= (1<<TOIE1);  // enable timer1 overflow interrupts

}

void loop ()
{}

I want to send 255 pulses out at 10Mhz

On a 16Mhz machine ?// I'm not sure if I have enough time to run something hereFor sure you do not, actually you won't have enough time for the ISR to be called and exited.
So since there is no time to count, your best guess would be to start the pulses and end them after a specific time, hoping that you got the number of pulses correctly.
I could suggest a hardware solution to count the pulses or a faster processor.

Don’t know whether it would be accurate enough but you could try something like this:

void sendPulses(const uint8_t nPin, const uint8_t nPeriodMillis, const uint8_t nNum)
{
    bool bOn = false;
    uint32_t nTrigger = millis() + nPeriodMillis;

    for (uint8_t nI = 0; nI < nNum; nI++)
    {
         if (millis() >= nTrigger)
         {  
             nTrigger = millis() + nPeriodMillis;
             digitalWrite(nPin, bOn);
             bOn = !bOn;
         }
    }
}

Deva_Rishi:
For sure you do not, actually you won’t have enough time for the ISR to be called and exited.
So since there is no time to count, your best guess would be to start the pulses and end them after a specific time, hoping that you got the number of pulses correctly.
I could suggest a hardware solution to count the pulses or a faster processor.

10Mhz was an optimistic value I expect my circuit under test to fail around 8 or less. Conceptually I had thought I could use the Timer1 counter overflow to trigger a count on timer0 which is set for however many pulses I want ( ex 200). Then when timer0 overflows the interrupt is only 1 instruction long which is to unset timer1…

If i set pins 9 and 10 to run out of phase using OCR1a and OCR1b I could push the resulting clock signal through an XOR gate to give me an effective double clock I think… I have a nice selection of 74hc parts laying about to cook that up.

Is this still impossible?

lfjewett:
10Mhz was an optimistic value I expect my circuit under test to fail around 8 or less. Conceptually I had thought I could use the Timer1 counter overflow to trigger a count on timer0 which is set for however many pulses I want ( ex 200). Then when timer0 overflows the interrupt is only 1 instruction long which is to unset timer1..

Good plan, worth a go.

lfjewett:
If i set pins 9 and 10 to run out of phase using OCR1a and OCR1b I could push the resulting clock signal through an XOR gate to give me an effective double clock I think... I have a nice selection of 74hc parts laying about to cook that up.

should work, i try not to mention the obsolete 7400's for the amount of response they generate here on the forum, cause then we have to go into the discussion of the meaning of obsolete. I was even thinking of using 2x dual 4-bit bitshifters to keep track of the number of pulses. and using some more logic to block the pulses to the circuit to be tested. tbh that would mean the arduino is just firing pulses and there are probably devices out there that can do that faster but i think you are on the right track.

Conceptually I had thought I could use the Timer1 counter overflow to trigger a count on timer0 which is set for however many pulses I want ( ex 200). Then when timer0 overflows the interrupt is only 1 instruction long which is to unset timer1..

Rather than use the Timer1 OVF which may introduce some latency, (even if all it s doing is directly writing TCNT0 += 1), can you split the output pulse so that one leg is going to the external clock source pin of Timer0 which can be set to increment TCNT0 on either a rising or falling edge.