Fixing millis() overflow: changing millis() and the timer 0 overflow handler so that the millis count is updated in the interrupt, and so we don't need to do a conversion inside millis(). Updated to do list.

This commit is contained in:
David A. Mellis 2008-04-18 21:56:14 +00:00
parent 1a89112e45
commit 7d2a6a115f
3 changed files with 29 additions and 23 deletions

View File

@ -56,7 +56,7 @@
productName = App; productName = App;
productReference = 33DD8FB6096AC8DA0013AF8F /* Arduino.app */; productReference = 33DD8FB6096AC8DA0013AF8F /* Arduino.app */;
productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"> <!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\"> <plist version=\"1.0\">
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
@ -687,6 +687,7 @@
33FFFD3F0965B1E40016AC38 /* Project object */ = { 33FFFD3F0965B1E40016AC38 /* Project object */ = {
isa = PBXProject; isa = PBXProject;
buildConfigurationList = 33FFFD400965B1E40016AC38 /* Build configuration list for PBXProject "Arduino" */; buildConfigurationList = 33FFFD400965B1E40016AC38 /* Build configuration list for PBXProject "Arduino" */;
compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
mainGroup = 33FFFD3D0965B1E40016AC38; mainGroup = 33FFFD3D0965B1E40016AC38;
productRefGroup = 33FFFD3D0965B1E40016AC38; productRefGroup = 33FFFD3D0965B1E40016AC38;

View File

@ -24,26 +24,29 @@
#include "wiring_private.h" #include "wiring_private.h"
// The number of times timer 0 has overflowed since the program started. volatile unsigned long timer0_clock_cycles = 0;
// Must be volatile or gcc will optimize away some uses of it. volatile unsigned long timer0_millis = 0;
volatile unsigned long timer0_overflow_count;
SIGNAL(SIG_OVERFLOW0) SIGNAL(SIG_OVERFLOW0)
{ {
timer0_overflow_count++; // timer 0 prescale factor is 64 and the timer overflows at 256
timer0_clock_cycles += 64UL * 256UL;
while (timer0_clock_cycles > clockCyclesPerMicrosecond() * 1000UL) {
timer0_clock_cycles -= clockCyclesPerMicrosecond() * 1000UL;
timer0_millis++;
}
} }
unsigned long millis() unsigned long millis()
{ {
// timer 0 increments every 64 cycles, and overflows when it reaches unsigned long m;
// 256. we would calculate the total number of clock cycles, then uint8_t oldSREG = SREG;
// divide by the number of clock cycles per millisecond, but this
// overflows too often.
//return timer0_overflow_count * 64UL * 256UL / (F_CPU / 1000UL);
// instead find 1/128th the number of clock cycles and divide by cli();
// 1/128th the number of clock cycles per millisecond m = timer0_millis;
return timer0_overflow_count * 64UL * 2UL / (F_CPU / 128000UL); SREG = oldSREG;
return m;
} }
void delay(unsigned long ms) void delay(unsigned long ms)
@ -122,8 +125,6 @@ void init()
// work there // work there
sei(); sei();
// timer 0 is used for millis() and delay()
timer0_overflow_count = 0;
// on the ATmega168, timer 0 is also used for fast hardware pwm // on the ATmega168, timer 0 is also used for fast hardware pwm
// (using phase-correct PWM would mean that timer 0 overflowed half as often // (using phase-correct PWM would mean that timer 0 overflowed half as often
// resulting in different millis() behavior on the ATmega8 and ATmega168) // resulting in different millis() behavior on the ATmega8 and ATmega168)

View File

@ -1,14 +1,24 @@
0012 arduino 0012 arduino
0012
Add highByte(), lowByte(), and word(high, low) functions.
Add bitRead() and bitWrite() functions (and bitSet() and bitClear()?)
Add Encoder library.
Add String library.
Add Servo library.
Add LiquidCrystal library.
Fix millis() so it overflows on a nice variable-size boundary; see: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1205949448
Move #include <WProgram.h> after other #include's? (prevent it from interfering with standard libraries)
[done] Factor out print statements into a common base class for Serial, LiquidCrystal, etc.
AVR AVR
Fix millis() so it overflows on a nice variable-size boundary; see: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1205949448
Consider moving millis() to timer 1, and configuring it so the interrupt is generated once a millisecond. Consider moving millis() to timer 1, and configuring it so the interrupt is generated once a millisecond.
Problems including WProgram.h twice? Problems including WProgram.h twice?
Add #defines for the analog input pins. Add #defines for the analog input pins.
Add parameter to shiftOut() for specifying a number of bits. Add parameter to shiftOut() for specifying a number of bits.
Add parameter to Serial.print[ln](x, BIN) for specifying number of bits. Add parameter to Serial.print[ln](x, BIN) for specifying number of bits.
Factor out print statements into a common base class for Serial, LiquidCrystal, etc.
Add support for ATmega1280 (e.g. timers, external interrupts, multiple serial ports). Add support for ATmega1280 (e.g. timers, external interrupts, multiple serial ports).
Add weak attribute to signal handlers: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1203798214 Add weak attribute to signal handlers: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1203798214
Incorporate ladyada's new SoftwareSerial library. Incorporate ladyada's new SoftwareSerial library.
@ -20,13 +30,7 @@ Fix delayMicroseconds(0).
Add sleep function(s). Add sleep function(s).
Add SPI library. Add SPI library.
Add pulseOut(), etc. functions from Wiring. Add pulseOut(), etc. functions from Wiring.
Add String library.
Add LiquidCrystal library.
Add Servo library.
Add Encoder library.
Add Ping example. Add Ping example.
Add highByte(), lowByte(), and word(high, low) functions.
Add bitRead() and bitWrite() functions (and bitSet() and bitClear()?)
Include Arduino as AVR-ISP sketch in hardware/firmwares. Include Arduino as AVR-ISP sketch in hardware/firmwares.
Move type definitions into WConstants.h. Move type definitions into WConstants.h.
Change core to use Arduino types (e.g. byte, boolean). Change core to use Arduino types (e.g. byte, boolean).