Go Down

Topic: 16 MHz blink (Read 1 time) previous topic - next topic

ilyazh

Hello! I need to build a 2 channel signal generator with delay from 500 ns to 10 us between the signals. I tried the next program code for blink something (led on 13 pin) with 16 MHz frequency, but oscilloscope shows period about 25 us. What is it? Why isn't 125 ns (62.5*2)?

Code: [Select]


#define ledPin 13

int timer1_counter;
void setup()
{
  pinMode(ledPin, OUTPUT);

 /* // initialize timer1
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;

  // Set timer1_counter to the correct value for our interrupt interval
  timer1_counter = 65535;   // preload timer 65536-16MHz/16Mhz
 
  TCNT1 = timer1_counter;   // preload timer
  TCCR1B |= (1 << CS10);    // 1 prescaler
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  interrupts();*/             // enable all interrupts
}

ISR(TIMER1_OVF_vect)        // interrupt service routine
{
  TCNT1 = timer1_counter;   // preload timer
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
}

void loop()
{
    // your program here...
}


Thanx.

Grumpy_Mike

Because this is a 16MHz processor and the timers can not output something at twice the clock rate which it would have to do to get one cycle, that is a high and a low, to get a 16MHz output.

Grumpy_Mike

Also it takes time to call an interrupt, and also quite a long time for the digital write call, so you are never going to get anywhere even close using that code.

xitami

#3
Nov 28, 2014, 07:07 pm Last Edit: Nov 28, 2014, 07:20 pm by xitami
Code: [Select]
ISR(TIMER1_OVF_vect)        // interrupt service routine
{
  TCNT1 = timer1_counter;   // preload timer
  PINB |= _BV(7);                                // 169.309 kHz,  2.9 uS
//digitalWrite(ledPin, digitalRead(ledPin) ^ 1); //  26.778 kHz, 18.8 uS
}


Code: [Select]
void setup() {
  pinMode(13, OUTPUT); }

void loop() {
    while(1)
      PINB |= _BV(7);  //  2 MHz
}


Code: [Select]
void loop() {
      PINB |= _BV(7);  //  533 kHz
}

SirJoBlack

#4
Jan 04, 2015, 02:58 pm Last Edit: Jan 05, 2015, 08:31 pm by SirJoBlack
I think is better you use Arduino to control external electronic. You may use an external oscillator (oscillators) and a clock divider such as HEF4521B.

Other logic components might be used to address the HEF4521B channels: outputs and input. In this way Arduino could be used to select input and output source.

I hope you find this hint intersting.

MarkT

digitalRead / digitalWrite each take about 4us to execute.  ISR will take a us or two to
enter.

If you want 16MHz you could try and derive it from the Xtal oscillator, but the highest
frequency the chip can produce is 8MHz because that's one transition per master clock.
The timers can do that unaided, just set with MAX=1, OCR=0, fast mode - the counter
will clock 0,1,0,1,0,1 etc.

Perhaps describe in more detail what waveforms you want to generate and we can
figure out if there's a way to do this with the timer hardware...
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Go Up