Go Down

Topic: noInterrupts() and Serial.write issues (Read 1 time) previous topic - next topic

memotick

In my program I am getting two different behaviors regarding Serial writes depending if noInterrupts() is present or not, *even with Interrupts() not present in the code* 

1) If noInterrupts() is present, I get a few characters and then the serial write appears to freeze
2) If noInterrupts() is commented out, the serial write functions properly

Any idea what is going on?  Are serial writes connected to interrupts somehow?

What I'm trying to do is execute an interrupt on an ADC complete while it is free running.
With a prescalar of 128 on an Arduino Uno (16MHz), I expect an interrupt every 100us or so (since it takes 13 clock cycles).

In case anyone wants to see code, I put a stripped down version below.  Oh, and I'm using version 1.03 of the IDE

Thanks in advance,
memotick

Code: [Select]

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

// Every Arduino program must have a setup section
void setup() {

  // ***********here is the problem area *********
  // noInterrupts();
  // ***********here is the problem area *********

  //clear ADCSRA and ADCSRB registers
  ADCSRA = 0;
  ADCSRB = 0;

  // ADCSRA: page 265
  // ADEN: Enable ADC
  sbi(ADCSRA, ADEN);
  // ADATE: ADC auto trigger enable
  sbi(ADCSRA, ADATE);

  // ADMUX page 264
  // select ADC0 channel
  cbi(ADMUX, MUX3);
  cbi(ADMUX, MUX2);
  cbi(ADMUX, MUX1);
  cbi(ADMUX, MUX0);

  // Quiet ADC inputs
  // Check page 266 of the ATmega328p datasheet
  // for more information.
  sbi(DIDR0,ADC5D);
  sbi(DIDR0,ADC4D);
  sbi(DIDR0,ADC3D);
  sbi(DIDR0,ADC2D);
  sbi(DIDR0,ADC1D);
  sbi(DIDR0,ADC0D);

  // Internal pull-ups interfere with the ADC. disable the pull-up on the
  // pin ifit's being used for ADC. either writing 0 to the port register
  // or setting it to output should be enough to disable pull-ups.
  DDRC = 0x00;

  // Set ADC prescalar to 128.  Thus one conversion every
  // (128*13)/16MHz = 104us
  sbi(ADCSRA, ADPS2);
  sbi(ADCSRA, ADPS1);
  sbi(ADCSRA, ADPS0);

  // ADSCRB: page 267
  // ADTST2:0 : ADC trigger select 000=Free running
  cbi(ADCSRB,ADTS2);
  cbi(ADCSRB,ADTS1);
  cbi(ADCSRB,ADTS0);

  Serial.begin(57600); 

  // ADCSRA: page 265
  // ADSC: ADC start conversion and allow ISR to run
  sbi(ADCSRA, ADSC);

  //sei();//enable interrupts

}

////Interrupt Service Routine (ISR)
ISR(ADC_vect) {
  //when new ADC value ready, do something here
}

void loop() {

  Serial.write("Made it in the loop\n");
}


PaulS

Serial data is sent using interrupts. Turning interrupts off prevents sending serial data. There's nothing complicated about it.

retrolefty

Quote
1) If noInterrupts() is present, I get a few characters and then the serial write appears to freeze


This is normal behaviour. The hardware serial library uses interrupts to move data to and from software memory buffers and the USART hardware, so as nointerrupts disables ALL interrupts serial data stops, millis() timer interrupts stops and any user interrupts or pin change interrupts you are using are all prevented from execution until you issue a Interrupts command.


Quote
2) If noInterrupts() is commented out, the serial write functions properly


Again as explained above.

Lefty

Nick Gammon

Apart from this issue:

Code: [Select]

  // ***********here is the problem area *********
  // noInterrupts();
  // ***********here is the problem area *********

...

  Serial.begin(57600); 

  // ADCSRA: page 265
  // ADSC: ADC start conversion and allow ISR to run
  sbi(ADCSRA, ADSC);

  //sei();//enable interrupts


You are hoping for an ADC interrupt but have interrupts off (if you call noInterrupts).
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

memotick


Apart from this issue:

Code: [Select]

  // ***********here is the problem area *********
  // noInterrupts();
  // ***********here is the problem area *********

...

  Serial.begin(57600); 

  // ADCSRA: page 265
  // ADSC: ADC start conversion and allow ISR to run
  sbi(ADCSRA, ADSC);

  //sei();//enable interrupts


You are hoping for an ADC interrupt but have interrupts off (if you call noInterrupts).


Nick,
     Wow, you pay attention to detail! 


Go Up