I have a library where I am using direct port manipulation for digital pins 9 and 10. I want this library to work for both the Arduino Pro Mini (ATmega328P) and the Arduino Mega (ATmega2560). The problem I am running into is if I reference "PORTH" in the libarary it fails to compile for the ATmega328P since it doesn't have a port H.
I have been trying to define the port in the preprocessor and while the code compiles it isn't working correctly. I have attached my most recent code where I am trying to define a macro so that I can use "PIN9_LOW()" and "PIN9_HIGH()" to toggle the pin and the macros would be set appropriately based on what board it was compiled for.
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define PIN9_LOW() "PORTH &= ~_BV(6)"
#define PIN9_HIGH() "PORTH |= _BV(6)"
#define PIN10_LOW() "PORTB &= ~_BV(4)"
#define PIN10_HIGH() "PORTB |= _BV(4)"
#elif defined(__AVR_ATmega328P__)
#define PIN9_LOW() "PORTB &= ~_BV(1)"
#define PIN9_HIGH() "PORTB &= ~_BV(1)"
#define PIN10_LOW() "PORTB &= ~_BV(2)"
#define PIN10_HIGH() "PORTB &= ~_BV(2)"
#endif
This may not be the best way to do it and I am open to other suggestions.
There are functions and arrays for that. See the SoftwareSerial.
https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/libraries/SoftwareSerial/SoftwareSerial.cpp
Or the SoftwareWire:
// Signal differences
// ------------------
// When the AVR microcontroller is set into hardware I2C mode,
// the pins follow the I2C specifications for voltage levels and current.
// For example the current to pull SDA or SCL low is maximum 3mA.
//
// With the Software I2C, a normal pin is used which can sink/source 40mA for a ATmega328P.
// That could increase the voltage spikes and could increase interference between sda and scl.
// The voltage levels are different.
// The timing of the software I2C is also different.
//
// In most cases the software I2C should work.
// With longer wires or with non-matching voltage levels, the result is unpredictable.
//
//
//
// Clock pulse stretching
// ----------------------
// An I2C Slave could stretch the clock signal by keeping the SCL low.
This file has been truncated. show original
It is this section:
port = digitalPinToPort(_sdaPin);
_sdaBitMask = digitalPinToBitMask(_sdaPin);
_sdaPortReg = portOutputRegister(port);
_sdaDirReg = portModeRegister(port);
_sdaPinReg = portInputRegister(port);
Your 328 definitions are identical for LOW and HIGH....
Regards,
Ray L.
Peter_n:
There are functions and arrays for that. See the SoftwareSerial.
But then the port access isn't direct. There is some extra code generated and it is a little bit slower than direct manipulation.
Yes, it's a little slower. Use the defines for max speed, but fix them as RayLivingston wrote.