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.
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!
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.
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