Can I assign a char value directly to a bit?
portD.4=0x5;
The overflowing bits would assign from portD.5, .6, .7, and .8
Can I assign a char value directly to a bit?
portD.4=0x5;
The overflowing bits would assign from portD.5, .6, .7, and .8
That particular notation cannot work in GCC. You'd need to add some more "meat" to the implementation to allow it to stand on its own in GCC.
For those compilers that do support such an extension, that notation (or a "meat-added" GCC implementation) would result in the least-significant bit of your byte (0x5 --> '1') being stored in the specified bit; all the rest of the byte would be discarded.
Okay, I'll byte. Why would you want to do this particular operation when there are other, clearer, techniques for setting bits?
Smiley
Those bits control a motor. The other 4 opposite bits on the port control a different motor.
I must change the first four or the last four ALL at one time, without affecting the opposite 4 bits.
Got any advice?
Easier method would be to create a temp char variable, and store the nibble of PORD which you don't want changed. Then change the other nibble to the new data and assign it to PORTD directly - voila, one nibble is changed at the same time with no intermediatry glitches, while the other nible stays constant.
- Dean :twisted:
To set all 4 upper bits:
PORTD |= 0xf0;
To clear all 4 upper bits:
PORTD &= ~0xf0;
For both of these, any bit in the constant that is a 1, that bit in PORTD is affected. All other bits remain as they were.
I took the quote:
I must change the first four or the last four ALL at one time, without affecting the opposite 4 bits.
To mean that the four bits (nibble) need to all be changed at once, with no intermediatry clearing of the nibble directly on the PORT (so correct data is always present with no cleared nibbles). In my example the code would be something like:
unsigned char TempPortD = PORTD; TempPortD &= ~((CLEARUPPERNIBBLE)? 0xF0 : 0x0F); TempPortD |= NEWMOTORDATA; PORTD = TempPortD;
Of course, I may have misinterpreted.
- Dean :twisted:
I see your point, if some of the bits in the nibble need to be set and others cleared. However you don't need to create a separate variable. You could do something like this:
PORTD = (PORTD & 0x0F) | 0x50;
This sets the upper nibble to whatever value you want and keeps the old nibble value.
PORTD = (PORTD & 0x0F) | 0x50;
9e: 8b b1 in r24, 0x0b ; 11
a0: 8f 70 andi r24, 0x0F ; 15
a2: 80 65 ori r24, 0x50 ; 80
a4: 8b b9 out 0x0b, r24 ; 11
My apologies. I stupidly thought that the operations would be performed seperatly rather than all at once before being shifted back into the PORT register. Must be jetlag ;).
- Dean :twisted:
You are correct. Once I change the port to the new data, that will alter the motor leads; any clearing or changing will disrupt the flow.
I will test this operation; thanks for advice.
----------------------------------
Ok - lemme ask this; PORTD is a 8 bit address. Am I able to assign volatile CHAR variables directly the first and second 4-BIT memory addresses, - just as the PORTD variable has been asigned an integer 8-bit value to all 8 bits?
Example:
portDa would be CHAR first 4 bits, and portDb would be CHAR last 4 bits? Is that possible?
Do you mean you have something like:
unsigned char portDa = 0b1101; unsigned char portDb = 0b0101;
(I'm assuming your C compiler can handle the 0b extension for binary numbers just so that what's going in the example is perhaps(?) a little more obvious). And do you mean that you want to then just say:
PORTD = (portDa << 4) | (portDb & 0x0f);
which would combine the two separate 4 bit "halves" into the entire 8 bit port - well that's fine.
BTW, the "& 0x0F" in there might not even be necessary if you know that portDb can't be assigned a value above 0x0F. In that case it's just:
PORTD = (portDa << 4) | portDb;
Cliff
Do you mean you have something like:unsigned char portDa = 0b1101; unsigned char portDb = 0b0101;No.
I want PORTDa behave just as PORTD does, only it will point directly to the first four bits of PORTD, and PORTDb to point directly to the last four bits of PORTD.
When I assign data to PORTDa at runtime:
PORTDa = 0x5; PORTDa = 0x8; PORTDa = 0x0;(same thing with PORTDb):
PORTDb = 0x3; PORTDb = 0x2; PORTDb = 0x7;-They will only affect their respective 4-bit zone, within PORTD
Does that make sense?
I suppose that you could write macros to make your code read this way (or something similar). But I think that you are confused about memory addresses. PORTD is a single memory address, not 8. That memory address contains 8 bits. The AVR has opcodes that allow you to change one bit at a time, but if you want to write more than one bit simultaneously, then you must write all bits.