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

Limitation of the compiler or what???

Hey folks,

I have a problem really interesting here. My program is really simple, I have just to read some information from analog inputs and send them throught CAN bus. I am using the microcontroller 167.

The source of the main function is showed on next:

void main(void)
{
  ubyte a, b, c, d, e, f, g, h;
  uword Gas = 0;
  uword Brake = 0;

  MAIN_vInit();

  while (1) {      /* loop forever*/

    Gas = ADC_ReadChannel(0);
    Gas = Gas & 0x3ff;
    a = LOWER_BYTE(Gas);
    b = UPPER_BYTE(Gas);

    Brake = ADC_ReadChannel(1);
    Brake = Brake & 0x3ff;
    c = LOWER_BYTE(Brake);
    d = UPPER_BYTE(Brake);

    while ( !CAN1_ubRequestMsgObj(1) );

    CAN1_vLoadData(1,0,a);
    CAN1_vLoadData(1,1,b);
    CAN1_vLoadData(1,2,c);
    CAN1_vLoadData(1,3,d);
    CAN1_vTransmit(1);
  }
} //  End of function main

So, when I test the program in the target hardware, the information that I read in CAN network (I have a monitor program in my PC connected in the CAN net) is supposed to show what I am reading from the analog inputs.

Well, when I read only one analog input and send by CAN, the program work well. But if I am reading two of analong inputs (as in the source code showed) and send these information by CAN, the ouptut comes wrong, always comes like 0xFF. I checked if there is a problem in the CAN drivers, but there is not. The problem is a simple basic operation of bits manipulation. How is it possible?

As I commented, if I commented the lines concerned with Brake analog input, for example, the program works.

//    Brake = ADC_ReadChannel(1);
//    Brake = Brake & 0x3ff;
//    c = LOWER_BYTE(Brake);
//    d = UPPER_BYTE(Brake);
//    CAN1_vLoadData(1,2,c);
//    CAN1_vLoadData(1,3,d);

Could someone explain me why is that? THere is some limitation on the compiler? Looks like a problem in the ocmpiler!

I am using DAvE to generate the drivers for CAN and ADC.

I am looking forward to hearing from someone!

Parents
  • I compiled the peace of code from the last post, I got the same problem (I read everything as 0xFF). I cannot work with ARRAYS or POINTERS. That is unbelievable. I changed the source to prove that:

    void CAN1_vLoadData(ubyte ubObjNr, ubyte pos, ubyte pubData) {
    
      CAN1_OBJ[ubObjNr - 1].MCR = 0xfaff;  // set CPUUPD and NEWDAT
    
        CAN1_OBJ[ubObjNr - 1].Data[pos] = pubData;
    
      CAN1_OBJ[ubObjNr - 1].MCR = 0xf7ff;  // reset CPUUPD
    }
    
    void CAN1_vTransmit(ubyte ubObjNr) {
      CAN1_OBJ[ubObjNr - 1].MCR = 0xe7ff;  // set TXRQ,reset CPUUPD
    }
    
    void main(void) {
      uword Gas = 0;
      uword Brake = 0;
    
      CAN1_vInit();
    
    //  Gas = 0x0123;
    //  Gas = Gas & 0x3ff;
    //  CAN_data.ubData[0] = (ubyte) (Gas);
    //  CAN_data.ubData[1] = (ubyte) (Gas >> 8);
    
      Brake = 0x1356;
      Brake = Brake & 0x3ff;
      CAN_data.ubData[2] = (ubyte) (Brake);
      CAN_data.ubData[3] = (ubyte) (Brake >> 8);
    
      CAN1_vLoadData(1,0,0x01);
      CAN1_vLoadData(1,1,0x02);
      CAN1_vLoadData(1,2,CAN_data.ubData[2]);
      CAN1_vLoadData(1,3,CAN_data.ubData[3]);
      CAN1_vTransmit(1);
      for(;;);
    }
    

    The rest of the source, I kept the same. In this case, I can read {0x01 0x02 0xFF 0xFF}, which makes sense!

    Is there an explanation for that? Is there any FLAG that I have to pass to the Compiler??

Reply
  • I compiled the peace of code from the last post, I got the same problem (I read everything as 0xFF). I cannot work with ARRAYS or POINTERS. That is unbelievable. I changed the source to prove that:

    void CAN1_vLoadData(ubyte ubObjNr, ubyte pos, ubyte pubData) {
    
      CAN1_OBJ[ubObjNr - 1].MCR = 0xfaff;  // set CPUUPD and NEWDAT
    
        CAN1_OBJ[ubObjNr - 1].Data[pos] = pubData;
    
      CAN1_OBJ[ubObjNr - 1].MCR = 0xf7ff;  // reset CPUUPD
    }
    
    void CAN1_vTransmit(ubyte ubObjNr) {
      CAN1_OBJ[ubObjNr - 1].MCR = 0xe7ff;  // set TXRQ,reset CPUUPD
    }
    
    void main(void) {
      uword Gas = 0;
      uword Brake = 0;
    
      CAN1_vInit();
    
    //  Gas = 0x0123;
    //  Gas = Gas & 0x3ff;
    //  CAN_data.ubData[0] = (ubyte) (Gas);
    //  CAN_data.ubData[1] = (ubyte) (Gas >> 8);
    
      Brake = 0x1356;
      Brake = Brake & 0x3ff;
      CAN_data.ubData[2] = (ubyte) (Brake);
      CAN_data.ubData[3] = (ubyte) (Brake >> 8);
    
      CAN1_vLoadData(1,0,0x01);
      CAN1_vLoadData(1,1,0x02);
      CAN1_vLoadData(1,2,CAN_data.ubData[2]);
      CAN1_vLoadData(1,3,CAN_data.ubData[3]);
      CAN1_vTransmit(1);
      for(;;);
    }
    

    The rest of the source, I kept the same. In this case, I can read {0x01 0x02 0xFF 0xFF}, which makes sense!

    Is there an explanation for that? Is there any FLAG that I have to pass to the Compiler??

Children
  • I am not familiar with DAvE, but there are two issues:
    You said that you modified

    void CAN1_vLoadData(ubyte ubObjNr, ubyte *pubData);
    

    as it didn't work. Well, as far as I can see, the message length is set to 8 in CAN1_vInit():

    CAN1_OBJ[0].MCFG =  0x88;
    

    As the buffer in your example has only a length of 2

    ubyte buffer[2] = {0x01,0x02};
    CAN1_vLoadData(1,buffer);
    

    you surely have undefined results for bytes 3 .. 8 when using the original version of CAN1_vLoadData().
    The other issue is about setting CPUUPD / NEWDAT in your modified function. I am not sure if everything works well if you modify these bits for every byte to be loaded.
    Anyway, I don't think that your problem has anything to do with the compiler, but merely with providing proper values to all affected CAN registers.

  • Hey folks,

    I found the problem. I have to declare the variables with "SDATA".

    TCAN1_Obj sdata CAN_data;
    

    So, I can manipulate and read correctly. But I couldn't understand why! I just checked that in the possible memory types.
    http://www.keil.com/support/man/docs/c166/c166_le_sdata.htm