| 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
 |  | 
	
		|  | 
	
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  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.
 |  | 
	
		|  | 
	
		| 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.
 |  | 
	
		|  | 
	
		| gaugeguy 
 
 
 Joined: 05 Apr 2011
 Posts: 350
 
 
 
			    
 
 | 
			
				|  |  
				|  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. |  | 
	
		|  | 
	
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  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.
 
 | 
 |  | 
	
		|  | 
	
		|  |