I am using s08dz48 controller.
I have configured CAN module to transmit data.
Below are the settings
OSC CLK=4M, No PLL used
clk to CAN from OSC.
CAN configured at 250KBPS
CAN module is working and I am able to send required data bytes(0 to 7) on bus.
The problem is that I am receiving garbage data OR 0x00 on bus.
This is because the the transmit data registers does not cantain the desired value.
This can be seen in debug window, whenever data is assigned to CANtxdata register, it does not get loaded to cantxdata register.
Is there any problem with clock.
Thanks in advance.
Hi Folks!. i been working for a while with a JM128 Coldfire V1 microcontroller. this time, i need to talk with a MPPT module that uses CAN to send telemetry information (temperature, current, voltage, etc.). i used as template a CAN library made to HCS08 microcontrollers. if i made polling over nodes ID, i can get the whole think work flawless. but, this MPPT module needs a remote frame request to send its data trought the bus.
how can i get this to work? its just as easy as setting RTR bit to 1?
this is my routine.
CAN initialization routine (using 12Mhz external oscillator, i get 10.66 us bit time or 93.75kbits/s of baudrate.)
void CAN_Init(unsigned char loopback){
CANCTL0 |= CANCTL0_INITRQ_MASK; // Solicitud para entrar en modo Inicialización.
while(!CANCTL1_INITAK); // Espere hasta que entre en modo Inicializacion
if(loopback & 0x01 == 0x01){
CANCTL1 = CANCTL1_CANE_MASK | CANCTL1_LOOPB_MASK; //Si está activado modo LoopBack.
}
else{
CANCTL1 = CANCTL1_CANE_MASK; //Modo normal activado
}
CANBTR0 = 0xC7; // Ajuste el preescaler del modulo.
// One sample per bit, TSEG1 = 10, and TSEG2 = 3.
// CANBTR1 = 0x3A;
CANBTR1_SAMP = 0;
CANBTR1_TSEG_10 = 10;
CANBTR1_TSEG_20 = 3;
CANIDAC = 0x10; // seleccione cuatro filtros de 16 bits.
CANIDAR0 = 0x00; // Borre los registros de filtros.
CANIDAR1 = 0x00;
CANIDAR2 = 0x00;
CANIDAR3 = 0x00;
CANIDAR4 = 0x00;
CANIDAR5 = 0x00;
CANIDAR6 = 0x00;
CANIDAR7 = 0x00;
CANIDMR0 = 0xff; // Acepte todos los mensajes de entrada
CANIDMR1 = 0xff;
CANIDMR2 = 0xff;
CANIDMR3 = 0xff;
CANIDMR4 = 0xff;
CANIDMR5 = 0xff;
CANIDMR6 = 0xff;
CANIDMR7 = 0xff;
CANCTL0 &= ~CANCTL0_INITRQ_MASK; // Solicitar salida del modo de inicializacion.
while(CANCTL1_INITAK); // espere hasta que MSCAN entre en modo normal
while(!CANCTL0_SYNCH); // espere hasta que MSCAN se sincronice con bus.
// Reset the receiver wake-up, CAN status change, overrun,
// and receiver full interrupt flags.
CANRFLG |= CANRFLG_WUPIF_MASK;
CANRFLG |= CANRFLG_CSCIF_MASK;
CANRFLG |= CANRFLG_OVRIF_MASK;
CANRFLG |= CANRFLG_RXF_MASK;
// Enable the receive buffer full interrupt.
CANRIER |= CANRIER_RXFIE_MASK;
}
CAN Send routine:
unsigned char CAN_Send(unsigned long id, unsigned char priority, unsigned char length, unsigned char *txdata) {
unsigned char index;
unsigned char txbuffer = {0};
if(!CANTFLG){ // Están llenos los buses de salida???
return CAN_BUFFER_FULL;
}
CANTBSEL = CANTFLG; // Seleccione el buffer numerado más pequeño
txbuffer = CANTBSEL;
CANTIDR0 = (id >> 3) & 0xff; // Cargue el identificador en los registros IDR.
CANTIDR1 = (id & 0x07) << 5;
/************/
CANTIDR3_RTR=1;
/***********/
for(index = 0; index < length; index++) { //Cargue el dato en el buffer de datos.
*(&CANTDSR0 + index) = txdata[index];
}
CANTDLR = length; //ajuste la longitud del mensaje
CANTTBPR = priority; // ajuste la prioridad del mensaje
CANTFLG = txbuffer; //Baje la bandera de transmision del buffer. 1= baja bandera.
while((CANTFLG & txbuffer) != txbuffer); //espere hasta que se transmita el dato.
return CAN_NO_ERROR; //si el mensaje llegó, avise que no hubo error.
}
any help?
regards;
Mauricio
Messages sent out from a MSCAN node are not received by the same node. In a real application, it doesn't make sense to listen to your own messages. For debugging and self test purposes only, there is a "loop back" mode which causes the sent messages to appear in the rx buffers. Unless you have enabled loop back, you will never receive the sent messages.
If you can verify that the messages are sent correctly (with an external CAN listener), then there cannot be any problems with your clock or baudrate settings. I don't understand what you mean with "the transmit data registers does not contain the desired value".
Hello Daniel,
I am not testing CAN in loopback mode, I am sending data on bus & have connected can analyzer on the other side. I am also able to send data on to the bus.
The registers I mentioned above are the CANTDSR0-CANTDSR7. Whatever data I assign to these registers doesnt gets store there and ultimately I dont receive it.
i.e CANTDSR0=can_data[0], then the data in var can_data[0] is not assigned to CANTDSR0, and after the above line of code CANTDSR0 still contains 0x00.
Any help.
Perhaps you should show us your code, so it would be easier for us to understand what you are doing? There is no need for polling for an empty tx-buf, just check that CANTLG is non-zero and then assign CANTBSEL = CANTFLG. You can't write to any CAN buffer resigster before doing so.
Sten
Hello Sten,
Below is the code through which I select tx buf and then write data in data seg register,
/****************************************************************************
x=0;
while(!(CANTFLG & (0x01<<x))) // find free buf
{
x++;
if(x == 3)
x=0;
}
CANTBSEL = 0x01<<x;
Try this approach instead:
if (CANTFLG) { // any transmit buffer empty?
CANTBSEL = CANTFLG; // select first empty transmit buffer
// write IDR-, DLR- and DSR-registers
CANTFLG = CANTBSEL; // Transmit!
}
else // no vacant transmit buffer; do the appropiate action (wait or put message in software buffer)
Sten