Added support for extra analog inputs and pwms on ATmega168.

This commit is contained in:
David A. Mellis 2006-10-15 11:45:26 +00:00
parent debec4e37f
commit 41d86d5a75
3 changed files with 73 additions and 26 deletions

View File

@ -5,8 +5,6 @@ can be connected to software on your computer (e.g. Flash, Processing, MaxMSP).
The boards can be assembled by hand or purchased preassembled; the open-source
IDE can be downloaded for free.
Arduino is an open source project, owned by nobody and supported by many.
For more information, see the website at: http://www.arduino.cc/
or the forums at: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl
@ -24,15 +22,36 @@ FTDI chip on the board. These can be found in the drivers/ directory.
Arduino board and point the Windows Add Hardware wizard to the FTDI USB
Drivers directory.
* On the Mac, mount the FTDIUSBSerialDriver_v2_0_1.dmg disk image and run the
* On the Mac, mount the FTDIUSBSerialDriver_v2_1_6.dmg (on PPC Macs) or the
FTDIUSBSerialDriver_v2_2_6_Intel.dmg (on Intel Macs) disk image and run the
included FTDIUSBSerialDriver.pkg. Also run the macosx_setup.command (after
moving the Arduino distribution to your /Applications folder). It corrects
permission on a few files for use with the serial port and will prompt you
for your password. You may need to reboot after running this script.
CREDITS
Arduino is an open source project, owned by nobody and supported by many.
The Arduino team is composed of Massimo Banzi, David Cuartielles, Tom Igoe,
Gianluca Martino, and David A. Mellis.
Nicholas Zambetti has contributed from the beginning.
Yaniv Steiner and Giorgio Olivero have been supporting the project and are
working at using it with the Instant Soup platform.
Arduino uses the GNU avr-gcc toolchain, uisp, avr-libc, avrlib, and code
from Processing and Wiring.
UPDATES
0005
0006
Added support for analog inputs 6 and 7 and pwm on pins 5 and 6 on the
on the ATmega168 used in the Arduino Mini (extra analog inputs not available
in DIP ATmega168s).
0005 - 2006.09.26
Applied patch from Hans Steiner to improve Linux support by searching for avr
tools in the user's path instead of expecting them at a fixed location.
@ -112,15 +131,3 @@ This is the first released of the unified IDE + language library
it's a terrible hack... but it works. at the moment it's in alpha stage
but it can be used to work.
The processing preprocessor is included but not used.
CREDITS
The Arduino team is composed of Massimo Banzi, David Cuartielles, Tom Igoe,
Gianluca Martino, and David A. Mellis.
Nicholas Zambetti has contributed from the beginning.
Yaniv Steiner and Giorgio Olivero have been supporting the project and are
working at using it with the Instant Soup platform.
Arduino uses the GNU avr-gcc toolchain, uisp, avr-libc, avrlib, and code
from Processing and Wiring.

View File

@ -109,15 +109,21 @@ int analog_out_pin_to_timer_array[NUM_DIGITAL_PINS] = {
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
// on the ATmega168, digital pin 3 has pwm
// on the ATmega168, digital pin 3 has hardware pwm
#if defined(__AVR_ATmega168__)
TIMER2B,
#else
NOT_ON_TIMER,
#endif
NOT_ON_TIMER,
// on the ATmega168, digital pins 5 and 6 have hardware pwm
#if defined(__AVR_ATmega168__)
TIMER0B,
TIMER0A,
#else
NOT_ON_TIMER,
NOT_ON_TIMER,
#endif
NOT_ON_TIMER,
NOT_ON_TIMER,
TIMER1A,
@ -161,6 +167,10 @@ pin_t analog_in_pin_to_port_array[NUM_ANALOG_IN_PINS] = {
{ PC, 3 },
{ PC, 4 },
{ PC, 5 },
#if defined(__AVR_ATmega168__)
{ NOT_A_PIN, 6 },
{ NOT_A_PIN, 7 },
#endif
};
pin_t *analog_in_pin_to_port = analog_in_pin_to_port_array;

View File

@ -94,6 +94,12 @@ void digitalWrite(int pin, int val)
cbi(TCCR1A, COM1B1);
#if defined(__AVR_ATmega168__)
if (analogOutPinToTimer(pin) == TIMER0A)
cbi(TCCR0A, COM0A1);
if (analogOutPinToTimer(pin) == TIMER0B)
cbi(TCCR0A, COM0B1);
if (analogOutPinToTimer(pin) == TIMER2A)
cbi(TCCR2A, COM2A1);
@ -126,6 +132,12 @@ int digitalRead(int pin)
cbi(TCCR1A, COM1B1);
#if defined(__AVR_ATmega168__)
if (analogOutPinToTimer(pin) == TIMER0A)
cbi(TCCR0A, COM0A1);
if (analogOutPinToTimer(pin) == TIMER0B)
cbi(TCCR0A, COM0B1);
if (analogOutPinToTimer(pin) == TIMER2A)
cbi(TCCR2A, COM2A1);
@ -194,6 +206,16 @@ void analogWrite(int pin, int val)
// set pwm duty
OCR1B = val;
#if defined(__AVR_ATmega168__)
} else if (analogOutPinToTimer(pin) == TIMER0A) {
// connect pwm to pin on timer 0, channel A
sbi(TCCR0A, COM0A1);
// set pwm duty
OCR0A = val;
} else if (analogOutPinToTimer(pin) == TIMER0B) {
// connect pwm to pin on timer 0, channel B
sbi(TCCR0A, COM0B1);
// set pwm duty
OCR0B = val;
} else if (analogOutPinToTimer(pin) == TIMER2A) {
// connect pwm to pin on timer 2, channel A
sbi(TCCR2A, COM2A1);
@ -328,15 +350,14 @@ SIGNAL(SIG_OVERFLOW0)
unsigned long millis()
{
// timer 0 increments every 8 cycles, and overflows when it reaches 256.
// we calculate the total number of clock cycles, then divide by the
// number of clock cycles per millisecond.
//return timer0_overflow_count * 8UL * 256UL / (F_CPU / 1000UL);
// 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);
// calculating the total number of clock cycles overflows an
// unsigned long, so 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 * 8UL * 2UL / (F_CPU / 128000UL);
// 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);
}
void delay(unsigned long ms)
@ -441,11 +462,20 @@ int main(void)
// timer 0 is used for millis() and delay()
timer0_overflow_count = 0;
// set timer 0 prescale factor to 8
// 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)
#if defined(__AVR_ATmega168__)
sbi(TCCR0A, WGM01);
sbi(TCCR0A, WGM00);
#endif
// set timer 0 prescale factor to 64
#if defined(__AVR_ATmega168__)
sbi(TCCR0B, CS01);
sbi(TCCR0B, CS00);
#else
sbi(TCCR0, CS01);
sbi(TCCR0, CS00);
#endif
// enable timer 0 overflow interrupt
#if defined(__AVR_ATmega168__)