For example, I have pins 1 and 2 shorted.
pin 1 is set as an output. pin 2 an input.
pin 2 is set to pullup.
I output logic 0 on pin 1.
I read the value from pin 2 and store the result in a variable VAL1.
Now I set pin 1 as a input (and pullup).
I set another pin, say pin 3 to logic 0 (not shorted to anything).
I output logic 0 on pin 3.
I read the value from pin 2 in to a variable VAL2.
Now logically VAL1 should be 0 and VAL2 1. However that doesn't seem to be the case. If I do this I often read 1 for both VAL1 and VAL2. Removing the second read however makes VAL1 revert to it's correct value, EVEN THOUGH BOTH READS SHOULD BE INDEPENDENT!! I've not seen this with the AT90USBKey so it's a bit odd.
The solution I've found is to place a delay loop after the port configuration but before the read, in my code:
inline unsigned char get_scan(unsigned char pin) {
unsigned char p = 1 << pin;
DDR = 0x00 ^ p;
PORTD = 0xFF ^ p;
for(volatile int i=0;i<100;i++);
return ~p & PIND;
}
The volatile is important, if you omit that it doesn't work. I guess the compiler optimizes it out. (volatile tells the compiler some other external code could change this variable so explicitly check it where ever it's referenced).
No comments:
Post a Comment