This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to revalue a symbol in C51?

Hi:
How are you?
We can use "SET" directive in A51 to revalue a symbol such as:
...
x SET 1
...
x SET 2
...
And how can I revalue a symbol in C51? I want to use "#define" but no way.
Please help me.


Parents Reply Children
  • This is what I want C51 to do as A51:
    ;-----------A51 MACRO-------------
    refStart SET 0 ;define start addr
    ;-----my A51 macro "Dim"-------------------
    Dim Macro ref,num
    ref EQU refStart
    refStart Set ref+num
    ENDM
    ;====================================
    ;---now I can use this macro to define my
    ;address
    Dim MyAddr0,1 ;define 1 byte
    Dim MyAddr1,2 ;define 2 bytes after
    ;MyAddr0
    Dim MyAddr2,1
    ......
    ;that will define:
    ; MyAddr0 EQU 0
    ; MyAddr1 EQU 1
    ; MyAddr2 EQU 3
    ; ......
    ;I can not use #define and #undef to do this
    ;How can I do?

  • You may use instead of EQU the SET directive. Symbols defined with SET may change the value.

  • "This is what I want C51 to do as A51"

    Not being familiar with A51 macros, I can't really see what you're trying to do.

    Perhaps if you could explain what you're actually trying to achieve we could come up with some suggestions on how to do that - rather than just trying to emulate A51 macros in C51 (which is quite possibly futile, as A51 macros are very much more powerful than the 'C' preprocessor!)

  • It sounds to me as though David wants to declare a number of symbols, with associated sizes, and keep a running counter of the sum of the sizes to generate the symbol values, so that he doesn't have to do it manually. In other words, he wants to be able to write something like:

    #define Dim(symbol,size)  <magic goes here>
    
    Dim(MyAddr0, 1)
    Dim(MyAddr1, 2)
    Dim(MyAddr2, 2)
    

    to get the effect of:

    #define MyAddr0  0
    #define MyAddr1  1
    #define MyAddr2  3
    

    Unfortunately (or perhaps fortunately), you can't use the C preprocessor to generate more preprocessor directives. That is, I can't write:

    #define Counter 0
    #define Dim(sym,size)     #define sym Counter    #define Counter (Counter + size)
    

    because the body of the macro "Dim" can't contain preprocessor directives. (Even if it worked, you'd get lots of complaints about redefining "Counter".)

    One question is why does this need to be done in the preprocessor? If you wanted those assembler EQUates for a series of variables, then simple variable declaration in C will take care of that:

    U8  MyVar0;
    U16 MyVar1;
    U16 MyVar2;
    

    and if you need their addresses later, just use the address-of (&) operator. If you need a specific start address, put the variables in a special segment and tell the linker where to place them.

    Another alternative, if you don't actually want storage allocated at that series of symbols, but just want the relative offsets, would be to typedef a structure and use the offsetof() macro from stddef.h:

    typedef struct
        {
        U8  MyAddr0;
        U16 MyAddr1;
        U16 MyAddr2;
        } MyStruct;
    
    ...
       o = offsetof(MyStruct, MyAddr0); // 0
       o = offsetof(MyStruct, MyAddr1); // 1
       o = offsetof(MyStruct, MyAddr2); // 3
    

    Given this declaration, you can place the series at a particular address simply by casting a pointer; or you could again declare an actual variable of type MyStruct and tell the linker where to place it.

  • "One question is why does this need to be done in the preprocessor?"

    Yes - that's the point I was trying to make earlier.
    We need David to explain what it is that he's actually trying to achieve

  • Thanks for your help!
    Now I get it, Davis' STRUCT and OFFSETOF is what I want.
    I am trying to define serial addresses in my EEPRom so I can
    visit these addresses in my routine. And each of address contains
    a number of bytes, such as MyAddr0 contains 1 byte,MyAddr1 contains
    2 bytes, MyAddr2 contains 3 bytes...

    I can define these addresses using "#define"
    /*********start define******************************/
    #define MyAddr0 0x00 //MyAddr0 start form 0x00 and use 1 byte
    #define MyAddr1 0X01 //MyAddr1 start form 0x01 and use 2 bytes(0x01 and 0x02)
    #define MyAddr2 0X03 //MyAddr2 start form 0x03 and use 3 bytes(0x03 to 0x05)
    /* ....... */ //now MyAddr3 must start form 0x06
    /*********end define*******************************/

    It will bother me when there are many addresses, but if I write A51
    program, I can use "Dim" MACRO list up to "EQU" these address and "SET"
    the start address to the first no-use byte in EEPRom. "Dim" MACRO is easy
    use :)
    Now I can use Davis' STRUCT and OFFSETOF to do this easily, thank you!