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

C166 Var verses immediate as index value

Hi All, I'm having a real hard time coming up with a reason why using a local var as an index into a struct fails but that same line with an immediate value specified works properly. Here's what I mean..

void main(void)
	{
	unsigned char cTemp, cValue;

// Do whats required to get under way.
//----------------------------------------------------------------------------
 	MAIN_System_Init();


// Endless While loop that the micro runs forever (hopefully).
//----------------------------------------------------------------------------
	while(gcTRUE)
		{
		cValue = 0x0C;

		cTemp = *port[0x0C].lsr;
		cTemp = *port[0x0C].txrx;

		cTemp = *port[cValue].lsr;
		cTemp = *port[cValue].txrx;

		}
	}

The first two reads to cTemp work properly (with the value 0x0C specified) but the following two reads using the cValue variable as the index fail? BTW, The reason that I say they fail is that the reads should generate an external bus read to a uart register. The first two reads generate a chip select and the second two do not. I've tried changing compiler optimizations and options but I'm running out of ideas. I'm using ver 4.20c of the C compiler and version 4.20 of most everything else. Any suggestions would be really appreciated. Thanks. ~Tim

  • From the code you provide, I cannot tell if *port is declared volatile. If not, the compiler simply says, "Why bother doing this again?"

    - Mark

  • To be sure, try an immediate value that is different from that of cValue. In this case, the compiler would not have an excuse for omitting the piece of code.

  • Thanks for the replies. The struct is declared as volatile and I had reduced optimization all the way to zero with no change. After a day of beating on it and talking to Boniface at Keil I decided on a whim to just create a new project reusing in the exact same source code files and that cured it. I was suspicious of hardware (i.e. external ram) problems causing this but no matter which module I put those 4 lines of code in the result was the same (no external read for the second two). Thanks again for the replies..

    ~Tim

  • The first thing I would do is look at the generated code. I think it's much easier than looking at external bus accesses and gives much more information.
    And another thing. Once I had this weird problem when display in my target worked in debugger mode (running off external RAM) and refused to work when running from internal flash. The reason was that the microcontroller does not release chip select between two accesses to external bus if it runs off internal flash. It's perfectly correct and documented. I had two insert dummy accesses two XRAM to release the chip select. Maybe that's the reason why you can't see enough transitions on chip select?
    Regards,
    - Mike

  • I just compiled the following:

    unsigned char lsr = 12;
    unsigned char txrx = 34;
    
    struct ct_st
      {
      unsigned char *lsr;
      unsigned char *txrx;
      };
    
    
    volatile struct ct_st port [] =
      {
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
        { &lsr, &txrx },
      };
    
    
    void main(void)
    	{
    	unsigned char  cTemp, cValue;
    
    // Do whats required to get under way.
    //----------------------------------------------------------------------------
    // 	MAIN_System_Init();
    
    
    // Endless While loop that the micro runs forever (hopefully).
    //----------------------------------------------------------------------------
    	while(1)
    		{
    		cValue = 0x0C;
    
    		cTemp = *port[0x0C].lsr;
    		cTemp = *port[0x0C].txrx;
    
    		cTemp = *port[cValue].lsr;
    		cTemp = *port[cValue].txrx;
    
    		}
    	}
    

    and got the following output:

                 ; FUNCTION main (BEGIN  RMASK = @0x4022)
                                               ; SOURCE LINE # 33
                                               ; SOURCE LINE # 34
                                               ; SOURCE LINE # 44
    0000         ?C0003:
                                               ; SOURCE LINE # 46
                                               ; SOURCE LINE # 48
    0000 F2F13000 R    MOV       R1,port+030H
    0004 A9A1          MOVB      RL5,[R1]
    ;---- Variable 'cTemp' assigned to Register 'RL5' ----
                                               ; SOURCE LINE # 49
    0006 F2F13200 R    MOV       R1,port+032H
    000A A9A1          MOVB      RL5,[R1]
                                               ; SOURCE LINE # 51
    000C F2F13000 R    MOV       R1,port+030H
    0010 A9A1          MOVB      RL5,[R1]
                                               ; SOURCE LINE # 52
    0012 F2F13200 R    MOV       R1,port+032H
    0016 A9A1          MOVB      RL5,[R1]
                                               ; SOURCE LINE # 54
    0018 0DF3          JMPR      cc_UC,?C0003
                 ; FUNCTION main (END    RMASK = @0x4022)
    

    These look AOK to me.

    Jon