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;
productReference = 33DD8FB6096AC8DA0013AF8F /* Arduino.app */;
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\">
<dict>
<key>CFBundleDevelopmentRegion</key>
@ -687,6 +687,7 @@
33FFFD3F0965B1E40016AC38 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 33FFFD400965B1E40016AC38 /* Build configuration list for PBXProject "Arduino" */;
compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 0;
mainGroup = 33FFFD3D0965B1E40016AC38;
productRefGroup = 33FFFD3D0965B1E40016AC38;

View File

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

View File

@ -1,14 +1,24 @@
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
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.
Problems including WProgram.h twice?
Add #defines for the analog input pins.
Add parameter to shiftOut() for specifying a 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 weak attribute to signal handlers: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1203798214
Incorporate ladyada's new SoftwareSerial library.
@ -20,13 +30,7 @@ Fix delayMicroseconds(0).
Add sleep function(s).
Add SPI library.
Add pulseOut(), etc. functions from Wiring.
Add String library.
Add LiquidCrystal library.
Add Servo library.
Add Encoder library.
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.
Move type definitions into WConstants.h.
Change core to use Arduino types (e.g. byte, boolean).