Hallo ,
Ich habe ein großes Problem mit meinem Can Controller und hoffe, dass
ihr mir helfen könnt. Das Problem is wie folgt:
Ich programmiere einen AT90can128 mit dem Evaluation Kit von Atmel
(DVK90) und habe das Testprogrammm von Atmel nur leicht modifiziert um
die CAN Kommunkation erstmal zu testen. Ich empfange und sende CAN
Nachrichten abwechselnd in einer while(1) Schleife. Das Problem ist nun,
dass fast jede vierte Nachricht nicht richtig abgeschickt wird. Ich
kriege dabei Bit und Form Errors , und der CANTEC steigt ebenfalls
stetig, geht aber nicht buss off. Der Controller ist wg. CAN mit dem
8MHZ Quartz am Eval Board angeschlossen, das entsprechende Fuse ist auch
gesetzt.
In einem weiteren Experiment werden keine Error Flags im CANSTMOB
gesetzt, dafür steigt aber der Transmission Error Count (CANTEC)
ebenfalls stetig.
Nun meine Fragen dazu: Sind diese Fehlerraten normal für diesen
Controller oder stimmt bei mir irgendwas nicht (was ich eher vermute)?
Und wenn es an meinem Code bzw. meine Einstellungen liegt, was kann die
Ursache für diese Art von Fehler sein, bzw. wie kann ich die beheben?
Und letzte Frage: Ist es möglich, dass CANTEC steigt und trotzdem keine
Error Flags gesetzt werden? Wann erhöht sich der CANTEC überhaupt ? Das
ist in der Doku leider nirgendswo erwähnt.
Im Anhang ist der gesamte Code für das erste gescheiterte "Experiment".
Bin euch für jeden Hilfe dankbar!
#include "config.h"
#include "uart_lib.h"
#include "uart_drv.h"
#include "can_lib.h"
#include "can_drv.h"
#include "rtc_drv.h"
#include "led_drv.h"
#include "Key_drv.h"
#include <avr/interrupt.h>
//_____ M A C R O S
__________________________________________________________
//_____ D E F I N I T I O N S
________________________________________________
#define RXCAN 'R'
#define TXCAN 'T'
//_____ D E C L A R A T I O N S
______________________________________________
void spy_printing(U8 rxtx, st_cmd_t* msg);
Bool trap();
#define PRINT(msg) uart_mini_printf msg
U8 counter ;
Bool terminate = FALSE;
Bool doTrap = FALSE;
ISR(TIMER1_COMPA_vect)
{
doTrap=TRUE;
}
void recieve()
{
U8 i, u8_temp;
st_cmd_t message;
U8 buffer [8];
message.pt_data = &buffer[0];
//- CAN ECHO: WAIT FOR RECEIVED
// --- Init Rx data
message.pt_data = &buffer[0];
for(i=0; i<8; i++) buffer[i]=0;
// --- Rx Command
message.cmd = CMD_RX;
// --- Enable Rx
while(can_cmd(&message) != CAN_CMD_ACCEPTED);
// --- Wait for Rx completed
while(1)
{
u8_temp = can_get_status(&message);
if (u8_temp != CAN_STATUS_NOT_COMPLETED) break; // Out of
while
}
if (u8_temp == CAN_STATUS_ERROR)
{
PRINT(("Recieve Error %02x \n\r",message.status));
}
else
;// spy_printing(RXCAN, &message);
}
Bool trap()
{
U8 u8_temp;
st_cmd_t message;
U8 buffer [8];
message.pt_data = &buffer[0];
U8 cantecBefore = CANTEC;
message.id.tab[0]= 0x04;
message.id.tab[1]= 0x82;
message.id.tab[2]= 0x10;
message.id.tab[3]= 0x18;
message.dlc=6;
message.pt_data[0]=0x0;
message.pt_data[1]= 0x02;
message.pt_data[2]= 0x05;
message.pt_data[3]= 0x2; // length of data
message.pt_data[4]= 0x0; // data
message.pt_data[5]= counter; // data
message.cmd = CMD_TX_DATA;
message.ctrl.ide=1;
// --- Enable Tx
while(can_cmd(&message) != CAN_CMD_ACCEPTED);
// --- Wait for Tx completed
while(1)
{
u8_temp = can_get_status(&message);
if (u8_temp != CAN_STATUS_NOT_COMPLETED) break; // Out of while
}
if (u8_temp == CAN_STATUS_ERROR)
{
PRINT(("TRANSMISSION ERROR %02x, counter = %02x,CANTEC
=%02x\n\r",message.status,counter,CANTEC));
return FALSE;
}
spy_printing(TXCAN, &message);
counter++;
return TRUE;
}
void
initTimer()
{
DDRB |= (1<<5);
//clear on compare match
TCCR1A |=(1<<COM1A1);
TCCR1A &=~(1<<COM1A0);
TCCR1A &=~(1<<WGM10);
TCCR1A &=~(1<<WGM11);
TCCR1B |=(1<<WGM12);
TCCR1B &=~(1<<WGM13);
TCCR1B |=(1<<CS10);
TCCR1B &=~(1<<CS11);
TCCR1B |=(1<<CS12);
TCCR1C &=~(1<<FOC1A);
OCR1AH = 0x05;
OCR1AL = 0x00;
TIMSK1= (1<<OCIE1A)/* | (1<<TOIE1A)*/;
}
int main (void)
{
// Clock prescaler Reset
CLKPR = 0x80; CLKPR = 0x00;
DDRA =0xFF;
//- Pull-up on TxCAN & RxCAN one by one to use bit-addressing
CAN_PORT_DIR &= ~(1<<CAN_INPUT_PIN );
CAN_PORT_DIR &= ~(1<<CAN_OUTPUT_PIN);
CAN_PORT_OUT |= (1<<CAN_INPUT_PIN );
CAN_PORT_OUT |= (1<<CAN_OUTPUT_PIN);
// Init UARTs
// Init UART-0 at 38400 bauds
Uart_select(UART_0);
uart_init(CONF_8BIT_NOPAR_1STOP,38400);
// --- Init CAN (special AUTOBAUD)
//- Wait until activity on RxCAN
while ((CAN_PORT_IN & (1<<CAN_INPUT_PIN)) != 0);
//- Reset CAN peripheral
Can_reset();
//- Set CAN Bit-timming
can_init((U16)1000); // c.f. macro in "can_drv.h"
//- Set CAN Timer Prescaler
CANTCON = CANBT1; // Why not !
initTimer();
asm("sei");
while(1)
{
recieve();
if(doTrap)
{
trap();
doTrap = FALSE;
}
}
uart_mini_printf("terminating\n\r");
return 0;
}
void spy_printing(U8 rxtx, st_cmd_t* msg)
{
U8 indx;
PRINT(("-0- %cxCAN @ %02X%02X: 0x%08lX(Ext.), L=%d, CANTEC=%02x,",
rxtx, CANSTMH, CANSTML, msg->id.ext, msg->dlc,CANTEC));
for(indx=0; indx< (msg->dlc-1); indx++)
{
PRINT (("%02X-", *(msg->pt_data + indx)));
}
PRINT(("%02X\r\n", *(msg->pt_data + indx)));
}
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.