Pages: [1]   Go Down
Author Topic: noInterrupts() and Serial.write issues  (Read 981 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 0
Posts: 158
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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");
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 613
Posts: 49270
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17294
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18767
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Apart from this issue:

Code:
  // ***********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).
Logged


Offline Offline
Full Member
***
Karma: 0
Posts: 158
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Apart from this issue:

Code:
  // ***********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! 

Logged

Pages: [1]   Go Up
Jump to: