[TIP] Three unique values from a single hard-coded input line

Status
Not open for further replies.

DaveHarper

New member
I am currently using three Teensy 2.0 boards in a project where they each emulate an external device attached to another board being developed. The Teensy 2.0 was chosen because the device being emulated requires 24 I/O lines and there are exactly that many I/O lines around the periphery of the board. I knew I needed a scheme to identify which board was which but also wanted to keep the code common across all three boards, so trying to embed the board number in Flash was out. Further, I've had issues with EEPROM in the past so I was really looking for a hardware solution. Unfortunately, there was only one unused I/O pin left - E6. Fortunately, thanks to the internal input pullup capability of the ATMega32U4 there is a way to accomplish this with a single pin. The datasheet says the pullup value ranges from 20K - 50K ohms. It also states that the minimum value for Vih is (0.2Vcc + 0.9V). Since I'm running at 5V, Vih works out to 1.9V. So the approach becomes to connect E6 to GND on one board, VCC on the second board and on the third board connect E6 to GND through a ~50K resistor. The first two boards will read the I/O pin as 0 or 1 respectively, however, for the third board, it will read a 0 when the internal pullup is deactivated and 1 when it is activated. The code, which stores the value in the global variable boardId, is shown below. Hopefully, someone may find this useful someday.

Dave



Code:
void getBoardID(void) {
  
  DDRE = 0;                                       // set PINE[6] as an input ...
  PORTE = 0;                                 // ... and initially with no pullup
  
  if (PINE & 0x40) {                       // check to see if the pin reads high
    boardId = 1;                                 // it does - we're board #1 ...
    return;                                              // ... and - we're done
  }
  
  PORTE = 0x40;                           // enable the internal pullup resistor
  for (int i = 0; i < 1000; i++) {
    asm("NOP");    // testing has shown some time is needed for things to settle
  }
  if (!(PINE & 0x40)) {                               // does it still read low?
    boardId = 0;                                 // yes - this makes us board #0
  } else {
    boardId = 2;                   // no - it now reads high so this is board #2
  }
  PORTE = 0;                    // we're done with the pullup - turn it back off
}
 
Status
Not open for further replies.
Back
Top