View previous topic :: View next topic |
Author |
Message |
rbarbali
Joined: 17 Dec 2015 Posts: 8
|
Problem calling subroutine |
Posted: Thu Aug 11, 2022 9:10 am |
|
|
HI all.
I have a question, I have 2 structs, and I can't call a subroutine with one of them. Is it a C limitation or a CCS limitation, or I am the limitation?
I get compiler error (A numeric expression must appear here) with:
WriteEeprom(0x04, enabled_WD);
but not with:
WriteEeprom(0x03, enabled_RF.z1);
This is the program:
Code: |
//ccs 5.091
//real hardware
#include <18f45k40.h>
typedef struct
{
int8 z1: 1;//lsb
int8 z2: 1;
int8 z3: 1;
int8 tamper: 1;
int8 reserved: 4;
} zonesWD;
zonesWD enabled_WD;//remote_enable: set by g100
typedef struct
{
int8 z1;//bit0-bit7= z11-z12-z13-z14-z15-z16-z17-z18
int8 z2;//bit0-bit7= z21-z22-z23-z24-z25-z26-z27-z28
int8 z3;//bit0-bit7= z31-z32-z33-z34-z35-z36-z37-z38
} rf_zone;
rf_zone enabled_RF;
//**************************************************************************
void WriteEeprom(int8 addr, int8 value)
{
disable_interrupts(GLOBAL);
write_eeprom(addr, value);
enable_interrupts(GLOBAL);
}
//********************************
void main(void)
{
int8 aux8;
enabled_WD = 0x88;
enabled_RF.z1 = 0x99;
//I can do this:
WriteEeprom(0x03, enabled_RF.z1);
//But I can't do this:
WriteEeprom(0x04, enabled_WD);
//Workaround:
aux8 = enabled_WD;
WriteEeprom(4, aux8);
while(1);
}
|
Thanks in advance |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Thu Aug 11, 2022 10:23 am |
|
|
The write_eeprom function expects to receive a single 8bit value.
Your first example gives it this.
On your second example, the name of a structure (without a element name),
is a C shortcut for the address of the structure. Not an 8bit value.
(This is actually one of these things that is rather undefined, so
'dangerous'). Some C's support this not all do.
Write it by using a pointer an de-referencing this:
WriteEeprom(0x04, *((int *)&enabled_WD));
Which forces the address to be taken, cast to be to an int, then takes
the contents of this and passes it to the write function. |
|
![](templates/subSilver/images/spacer.gif) |
rbarbali
Joined: 17 Dec 2015 Posts: 8
|
|
Posted: Fri Aug 12, 2022 6:42 am |
|
|
Quote: | WriteEeprom(0x04, *((int *)&enabled_WD)); |
It works OK. Very interesting!
Thank you. |
|
![](templates/subSilver/images/spacer.gif) |
gaugeguy
Joined: 05 Apr 2011 Posts: 296
|
|
Posted: Fri Aug 12, 2022 7:50 am |
|
|
Another way using standard C elements would be to add a union so that one element is the bit structure and the other is the full word/byte. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Fri Aug 12, 2022 9:52 am |
|
|
Yes, that is the sneaky/best way of doing this:.
Code: |
union {
int8 byteval;
zonesWD enabled_WD;//remote_enable: set by g100
} WD;
//Then use
WD.zoneWD.z1 //etc to access the bits
WD.byteval //to access the byte equivalent value.
|
|
|
![](templates/subSilver/images/spacer.gif) |
|