Forum: Mikrocontroller und Digitale Elektronik AT90CAN128 Bit und Form Errors


von Mike (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.