logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.
REKLAMA
  • #1 6094744
    grimble
    Poziom 11  
    Cześć,

    Próbuje uruchomić moduł CAN w MC9S08DZ60. Inicjalizacja modułu w tryb LOOPBACK wydaje się przebiegać poprawnie. Zapis wiadomości do bufora nadawczego również wydaje się być ok.

    Wygląda na to że niestety moduł CAN nie wysyła wiadomości bo rejestr CANTFLG_TXEx jest niezmieniony. Jak można się spodziewać, po stronie odbiornika nie ma wiadomości.

    Rejestr odpowiedzialny za zliczanie błędów wskazuje nagle ze jest ich ponad 254 w nadajniku i odbiorniku co skutkuje przejściem do stanu bus-off czyli odcięcia.

    Nie mam pojęcia dlaczego tak się dzieje i przyznam że nie bardzo też wiem jak szukać rozwiązania. przypomnę że moduł działa po loopbacku czyli RX jest spięty wewnętrznie z Tx.

    Próbowałem modyfikować prędkość transmisji, długości TSEG1 i TSEG2. Bez rezultatu.

    poniżej dołączam kody źródłowe funkcji inicjującej i nadającej. uC pracuje z kwarcem 4MHz.

    Będę wdzięczny za wszelkie wskazówki.

    pozdrawiam,

    Bartek

    
    // funkcja inicjująca interfejs CAN
    void canInit(void){
    
      CANCTL1_CANE = 1;
    // zarządanie inicjalizacji modułu CAN
      CANCTL0_INITRQ = 1; 
    
    // Czekaj na wejście w tryb inicjalizacji
      while(!CANCTL1_INITAK);
    
    // włącz tryb looback
      CANCTL1_LOOPB  = 1;
      CANCTL1_LISTEN = 0;
    
      CANBTR0_SJW = 3;
      CANBTR0_BRP = 0x3F;
      CANBTR1_TSEG = 0x7f;
      CANBTR1_SAMP = 0;
      
      // konfiguracja filtrów 
      // MC9S08DZ60 datasheet p.237
      // dwa filtry 32bit
      CANIDAC_IDAM0 = 0;
      CANIDAC_IDAM1 = 0;
    
      // ID Mask Register - które bity mająbyc porównywane
      // Wszystkie bity jako 'do not care' -> 1
      CANIDMR0 = 0xFF; // first bank
      CANIDMR1 = 0xFF;
      CANIDMR2 = 0xFF;
      CANIDMR3 = 0xFF;
      
      CANIDMR4 = 0xFF; // second bank
      CANIDMR5 = 0xFF;
      CANIDMR6 = 0xFF;
      CANIDMR7 = 0xFF;
      
      // określają jakie to mają być bity
      CANIDAR0 = 0x00; // first bank
      CANIDAR1 = 0x00;
      CANIDAR2 = 0x00;
      CANIDAR3 = 0x00;
      
      CANIDAR4 = 0x00; // second bank
      CANIDAR5 = 0x00;
      CANIDAR6 = 0x00;
      CANIDAR7 = 0x00;
      
      // oscylator jako źródło zegara
      CANCTL1_CLKSRC = 0;
      
      // aktywuj przerwanie po ptrzymaniu wiadomości
      CANRIER_RXFIE = 1;
      
      // uruchom przerwania związane z błedami p.232 
      CANRIER_CSCIE = 1;
      // poziom raportowania: wszystkie
      CANRIER_RSTATE = 3;
      // poziom raportowania: wszystkie
      CANRIER_TSTATE = 3;
    
      // opuść tryb 'init'
      CANCTL0 = 0x00;
      CANCTL0_INITRQ = 0;
    
      // poczekaj az moduł CAN się uruchomi(wyjdzie z trybu init)
      while(CANCTL1_INITAK);
      
      // czekaj aż moduł CAN zsynchronizuje się z magistralą
      while(!CANCTL0_SYNCH);
    }
    
    Bool MSCANSendMsg(struct canMsg msg){
    
      unsigned char n_tx_buf, i;
      
      // sprawdza czy dane nie są za długie
      if(msg.len > CAN_MAX_DATA_LEN)
        return(FALSE);
    
      // sprawdza czy jesteśmy zsynchronizowani z magistralą
      if(!CANCTL0_SYNCH)
        return(FALSE);
    
      n_tx_buf = 0;
        CANTBSEL=CANTFLG;
        n_tx_buf=CANTBSEL;
      
      if(!n_tx_buf) // nie ma wolnego bufora
        return FALSE; 
      
      // Write Identifier
    //  CANTIDR0 = (unsigned char)(msg.id>>3);
    //  CANTIDR1 = (unsigned char)(msg.id<<5);
    // ID wpisane na stałe - do testów
      CANTIDR0 = 0xFF;
      CANTIDR1 = 0xE0;
      if(msg.RTR)
        // RTR=Recessive
        CANTIDR1 |= 0x10;
        
      // jeden bajt wiadomości - do testów
      CANTDSR0 = 0xFF;  
      // Write Data Length
    
      CANTDLR = 1;
      // Write Priority
      CANTTBPR = msg.prty;
      
      // Clear TXx Flag (buffer ready to transmission)
      CANTFLG = n_tx_buf;
      
      return(TRUE);  
    }
    
  • REKLAMA
REKLAMA