Author |
Topic |
|
Consultpinnacle
29 Posts |
Posted - 22 Apr 2004 : 07:47:30
|
We are progressing nicely with our application and are now dabbling into the digital IO using the ADSmartIO library.
With the digital out, we have to write a byte to the port which obviously affects all the bits on that port. However we are really only interested in setting/resetting a particular bit.
How should we approach this issue? Should we read a byte from the port first, then reset the bit we are interested in, then write the whole byte back again?
Are there any other tactics that we should consider?
Thanks
Jim Brock |
|
ctacke
877 Posts |
Posted - 22 Apr 2004 : 09:35:56
|
If you are only using a single bit, and the rest are not connected at all, then I'd simply write 0's to all the other bits. You could even set the direction on all of the unused bits to "input" (though keep in mind that setting them as inputs and writing a "1" to a bit will enable internal pull-ups on the line.
If you need to maintain the state of all the lines, the best route is to read the state at app start-up into a global variable, then use that as a mask for all write operations to the port. |
|
|
Consultpinnacle
29 Posts |
Posted - 22 Apr 2004 : 10:16:05
|
Ok,
So for example, if I was using PC0 and PC1 as digital input and PC2 and PC3 as digital output, then if I want to set PC2 to 1 then what values do I send to PC0, PC1 and PC3 i.e. what is the byte value I need to send to Port C?
Jim |
|
|
akidder
1519 Posts |
Posted - 22 Apr 2004 : 14:09:03
|
Thanks for your note, Jim. You are correct that you'll need to know the current value of the output port before writing back out. Like Chris, I prefer to keep track of the output state in a variable, but I've seen applications where customers simply read back the current value of the port.
It's important to note that when using mixed inputs and outputs on one port of the AVR microcontroller, you need to keep track of which bits are configured as inputs and which of those inputs have pull-ups enabled.
Here's some sample code that illustrates how to do the masking. The ports are configured as you described, and the code assumes that you want to enable the pull-ups on PC0 and PC1.
// Global variables for the I/O routines
BYTE PortCDDRMask=0x0C, // set PC2 and PC3 to outputs, rest are inputs (1=output) PortCPullupMask=0x03, // enable pull-ups on PC0 and PC1 (1=pullup enabled) PortCOutputState=0x00; // current state of outputs (set the initial values here)
...
// Initialization
// set the data direction for the I/Os SIOInitDDRC (PortCDDRMask); // Combine input input bits that need to be written high to enable // pull-ups with the initial value of the outputs. The values can // be added or ORed, since inputs and outputs are mutually exclusive. PortCOutputState = (~PortCDDRMask | PortCPullupMask) | (PortCDDRMask & PortCOutputState) // Set the initial value of pull-ups and outputs SIOWritePortC (PCOutputState);
...
void SetPortCBit (BYTE BitToSet; BOOL SetBitHigh) // BitToSet value from 0 to 7 representing bit to change // SetBitHigh TRUE = set the target bit to logic high { // Create a bitmask for new bit to set. Mask with PortCDDRMask // to avoid interfering with existing input settings OutputBitMask = (0x01 << BitToSet) & PortCDDRMask; if (SetBitHigh) PortCOutputState = PCOutputState | OutputBitMask; else // ... set bit low PortCOutputState = PCOutputState & ~OutputBitMask;
// set the new value on Port C SIOWritePortC (PortCOutputState); }
Edited by akidder 23-Apr-2004: Correct name of SIOWritePort() function |
|
|
Consultpinnacle
29 Posts |
Posted - 23 Apr 2004 : 04:12:27
|
Fabulous stuff!
Thanks
Jim Brock |
|
|
|
Topic |
|
|
|