Hallo! Ich bin gerade dabei das ECAN Modul mit einem PIC18F4680 zum laufen zu bringen um eine Kommunikation zwischen zwei PICs herzustellen. ich habe eine Routine geschrieben um eine Nachricht zu senden. Der Empfang wird Interruptgesteuert abgewickelt. Im Loopback mode funktioniert alles einwandfrei. Die gesendete Nachricht wird richtig empfangen und eine RTR (Request to Send) anfrage wird auch mit einem Antwortframe beantwortet. jedoch sobald ich 2 PICS zusammenhänge und in den Normal Mode gehe, wird beim Empfänge immer die gleiche Nachricht empfangen, obwohl die Nachricht nur einmal beim Sender gesendet wurde. Muss der Empfang vom Empfänger irgendwie durch ein Frame bestätigt werden? Außerdem wird eine gesehdete RTR nicht beantortet. - ich kenn mich, was die frames und die genaue BOSCH norm anbelangt leider nicht 100%ig aus. Vielleicht könnt ihr mir weiter helfen? Vielen dank schon mal für Antworten! gruß, MAX
achja, was ich noch vergessen habe: zwischen den 2 PICs habe ich jeweils 2 MCP2551 CAN Tranceiver und auf beiden seiten einen 120Ohm abschlusswiderstand. - kann ich die 2 PICs auf direkt zusammenhängen TXCAN1->RXCAN2 und RXCAN1<-TXCAN2? gruß, MAX
>kann ich die 2 PICs auf direkt zusammenhängen >TXCAN1->RXCAN2 und RXCAN1<-TXCAN2? das dürfte nicht funktionieren >jedoch sobald ich 2 PICS zusammenhänge und in den Normal Mode gehe, >wird beim Empfänge immer die gleiche Nachricht empfangen, obwohl die >Nachricht nur einmal beim Sender gesendet wurde. Muss der Empfang vom >Empfänger irgendwie durch ein Frame bestätigt werden? Genau das ist die Ursache für das ständige neu Senden. Der Empfänger sendet dir selbe Message mit geseztem ACK Bit zurück. Dann weiß der Sender, dass die Message korrekt empfangen wurde. Falls dies nicht der Fall ist, wird die Message eben immer wieder gesendet.
Hallo PICer, diese überprüfung mit dem ACK bit macht das die CAN engine oder muss ich das softwaremäßig machen? kannst du mir vielleicht kurz den gesamten ablauf einer erfolgreichen übertragung einer Nachricht erklären. d.h. wer sendet wem was? Wäre nett, danke MAX
>Genau das ist die Ursache für das ständige neu Senden. Der Empfänger >sendet dir selbe Message mit geseztem ACK Bit zurück. Dann weiß der Das ist etwas undeutlich. Der Empfänger setzt am Schluss einer msg ds ACK-Bit. Er erzeugt also nicht nochmal die komplette msg (was ja die Datenrate halbieren würde). An EINER msg sind sowohl der Sender als auch der Empfänger beteiligt: der Sender sendet den "Body" und der Empfänger das ACK. Das ACK wird vom Empfänger selbstständig erzeugt. Ausnahme könnte höchstens ein Listen-Mode sein, in dem der Empfänger zwar hören, aber nicht aktiv am Busgeschehen teilnehmen darf. Wenn Dein Empfänger korrekt empfängt, es aber trotzdem zu mehrfachem Senden kommt, dann kann ich mir das höchstens durch o.g.Listen-Mode oder durch einen Hardware-Defekt (TX-Leitung des Empfängers defekt?) erklären. Gruß, Stefan
hallo stefan, danke für die antwort! jetzt ist mir auch klar, warum das bei mir auch so war, als ich den listen mode ausprobiert habe. ich werd mal die 2 pics ersetzten, um auszuschließen, dass eine TX-Leitung defekt ist. MAX
also hier, wen's interessiert die main und interrupt routine; ... can_msg *nachricht, *tx_temp, *rx_temp; void Interrupt_CAN_RXB0(void) { if(can_get_rx_buffer(rx_temp, RXB0)){ if(rx_temp->DLC&0x40){ //if RTR bit set, transmit RTR answer tx_temp->SID=rx_temp->SID; tx_temp->EID=rx_temp->EID; tx_temp->DLC=0x08; tx_temp->DATA[0]='R'; tx_temp->DATA[1]='T'; tx_temp->DATA[2]='R'; tx_temp->DATA[3]=' '; tx_temp->DATA[4]='A'; tx_temp->DATA[5]='N'; tx_temp->DATA[6]='S'; tx_temp->DATA[7]='W'; can_load_tx_buffer(nachricht,TXB1); can_tx_buffer(TXB1,2); //TXn senden } else { show_msg(rx_temp); //message ausgeben } } } void main(void) { unsigned char buffer[5]; unsigned int i, temp; i2c_init((CPU_FREQ/I2C_CLK-4)/4); lcd_init(LCD_DISP_ON); usart_init((CPU_FREQ/USART_BAUDRATE-16)/16); can_init((CPU_FREQ/CAN_BAUDRATE)/2/8-1, MODE_NORMAL); /*Global Interrupt*/ RCONbits.IPEN=1; //enable priority INTCONbits.GIEH=1; //enable all high priority interrupts INTCONbits.GIEL=1; //enable all low priority interrupts /*CAN Interrupts*/ INTCONbits.PEIE=1; //Peripheral Interrupt Enable PIE3bits.RXB0IE=1; //enable RXB0 Interrupt enable IPR3bits.RXB0IP=1; //enable high priority for RXB0 PIE3bits.RXB1IE=0; //enable RXB1 Interrupt enable IPR3bits.RXB1IP=0; //enable high priority for RXB1 PIE3bits.TXB0IE=0; //enable TXB0 Interrupt enable IPR3bits.TXB0IP=0; //enable high priority for TXB0 RXB0CON=0b00100000; //Config RXB0; RXB1CON=0b00100000; //Config RXB1; for(;;){ nachricht->SID=5; nachricht->EID=0; nachricht->DLC=0x05; nachricht->DATA[0]='M'; nachricht->DATA[1]='S'; nachricht->DATA[2]='G'; nachricht->DATA[3]=' '; nachricht->DATA[4]='1'; can_load_tx_buffer(nachricht,TXB0); can_tx_buffer(TXB0,2); //TXn senden delay_ms(1000); nachricht->SID=99; nachricht->EID=0; nachricht->DLC=0x07|0x40; nachricht->DATA[0]='R'; nachricht->DATA[1]='T'; nachricht->DATA[2]='R'; nachricht->DATA[3]=' '; nachricht->DATA[4]='R'; nachricht->DATA[5]='E'; nachricht->DATA[6]='Q'; can_load_tx_buffer(nachricht,TXB0); can_tx_buffer(TXB0,1); //TXn senden delay_ms(2000); } } ...
hab grad gesehen, hab vorher noch einer variable einen sinnvollen namen gegeben deshalb muss es in der ISR statt " can_load_tx_buffer(nachricht,TXB1);" "can_load_tx_buffer(tx_temp,TXB1);" heißen!
>kann ich die 2 PICs auf direkt zusammenhängen >TXCAN1->RXCAN2 und RXCAN1<-TXCAN2? So nicht, aber anders: mit wired or, denn alle Rx müssen alle Tx hören, und dominant (low) soll recessiv (high) übertönen: +5V PullUp | Rx1 ------*------ Rx2 | Tx1 --|<|-*-|>|-- Tx2 (sollen 2 schnelle Dioden sein) geht auch mit mehr als 2 Teilnehmern, wenn die Leitungen relativ kurz sind.
Hallo, ich hab jetzt mal beide PICs ausgetauscht und jetzt funktionierts einwadfrei, es muss also einer der beiden beim probeaufbau was abgekriegt haben :) - Danke für den hinweis! hab jetzt nur mehr ein paar kleine fragen und zwar: 1) im TXB0CON (Transmit buffer 0 control) gibts ein bit TXLARB (Transmission lost arbitration), was bedeutet lost arbitration. ich fermute es heißt, dass er das adressierungsfeld (Identifier) "verpasst" hat? 2) im TXB0CON, das bit TXERR wird das gesetzt, sobald der Sender keine Ack vom empfänger erhalten hat und probiert es somit noch einmal und die anzahl der versuche wird im TXERRCNT mitgezählt, seh ich das richtig so? wie sollte man so ein Transmition error am besten in der software behandeln, d.h. wie eird das in der praxis gemacht? so das wärs eigentlich. danke denen die mir hier immer antworten! gruß, MAX
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.