We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
The definition 'Parameter_Table' has a starange behavior in my code. Is there an error in this code or a bug in C51? In cases 0x20 and 0x21 this code returns quite different (wrong) values compared to cases 0x10 and 0x11 ( or 0x30 and 0x31 ) respectively. Instead of Parameter_Table(PARAMETER_NUMBER-x) it returns something like 'Parameter_Table(-x)+PARAMETER_NUMBER';
#define PARAMETER_SIZE 13 #define PARAMETER_NUMBER 8 union parameter_type { struct { unsigned char start_1; unsigned char params_1[PARAMETER_SIZE]; unsigned int check_1; } parst; unsigned char table[PARAMETER_NUMBER][PARAMETER_SIZE+3]; }; #define Parameter_Start (0x1000) #define Parameter_Table(n) (Parameter_Start+n*(PARAMETER_SIZE+3)) #define Parameter_Check (Parameter_Start+sizeof(union parameter_type)) unsigned int test_defines (unsigned char tmp) { // unsigned int tmpw; switch (tmp) { case 0: tmpw = Parameter_Start; break; case 0x10: tmpw = Parameter_Table(0); break; case 0x11: tmpw = Parameter_Table(1); break; case 0x20: tmpw = Parameter_Table(PARAMETER_NUMBER-8); break; case 0x21: tmpw = Parameter_Table(PARAMETER_NUMBER-7); break; case 0x27: tmpw = Parameter_Table(PARAMETER_NUMBER-1); break; case 0x30: tmp = PARAMETER_NUMBER-8; tmpw = Parameter_Table(tmp); break; case 0x31: tmp = PARAMETER_NUMBER-7; tmpw = Parameter_Table(tmp); break; } return tmpw; }
37: case 0x10: 38: tmpw = Parameter_Table(0); C:0x0DD2 7C10 MOV R4,#koe(0x10) C:0x0DD4 7D00 MOV R5,#B?SMEM(0x00) 39: break; C:0x0DD6 8024 SJMP C:0DFC 40: case 0x11: 41: tmpw = Parameter_Table(1); C:0x0DD8 7410 MOV A,#koe(0x10) C:0x0DDA FC MOV R4,A C:0x0DDB FD MOV R5,A 42: break; C:0x0DDC 801E SJMP C:0DFC 43: case 0x20: 44: tmpw = Parameter_Table(PARAMETER_NUMBER-8); C:0x0DDE 7C0F MOV R4,#0x0F C:0x0DE0 7D88 MOV R5,#TCON(0x88) 45: break; C:0x0DE2 8018 SJMP C:0DFC 46: case 0x21: 47: tmpw = Parameter_Table(PARAMETER_NUMBER-7); C:0x0DE4 7C0F MOV R4,#0x0F C:0x0DE6 7D98 MOV R5,#SCON0(0x98) 48: break; C:0x0DE8 8012 SJMP C:0DFC 49: case 0x27: 50: tmpw = Parameter_Table(PARAMETER_NUMBER-1); C:0x0DEA 7C0F MOV R4,#0x0F C:0x0DEC 7D98 MOV R5,#SCON0(0xF8) 51: break; C:0x0DEE 8012 SJMP C:0DFC
Take a look at the preprocessor output file - I'd guess you might have problems with the macro expansions, possibly due to insufficient parentheses. Stefan
#define Parameter_Table(n) Parameter_Start+n*(PARAMETER_SIZE+3))
#define Parameter_Table(n) (Parameter_Start+(n)*(PARAMETER_SIZE+3))
There's no need for the macros at all; they're getting in the way and causing bugs. Let the compiler handle it.
#define ConfigBaseAddress 0x1000 typedef ParamCheckType ???; // not mentioned in original code posted typedef struct { U8 start; U8 value[PARAMETER_SIZE]; U16 check; } Parameter; typedef struct { Parameter params[PARAMETER_NUMBER]; ParamCheckType check; } ParameterBlock; ParameterBlock config _at_ ConfigBaseAddress ;
Thank all of you for the help. Actually this is a slightly simplified part of a handler for serial EEPROM in an old project. That's why the parameters are in blocks. The more recent version of the project uses the memory class HDATA, the XBANKING.A51-like interface to an EEPROM-handler (C51).