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
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);
}