Gast
#5763285
Hallo Leute,
Bin gerade dabei ein kleines Programm mit Can-Bus zu schreiben.
Funktioniert auch soweit mit der 11 Bit-ID. Nub benötige ich die
extended ID. Leider funktioniert das nicht so wie ich mir das vorstelle.
Ich bekomme immer eine andere ID als die, die ich deklariert habe.
Vieleicht fällt ja jemanden der Fehler auf.
Danke im vorraus!
hier der Code:
*/
#include <avr/io.h> // Einbinden der Bibliothek
#include <avr/interrupt.h> // Einbinden der Bibliothek
volatile uint8_t ms_tick = 0;
// wird alle 10ms aufgerufen
ISR (TIMER3_COMPA_vect) // Interrupt aufrufen
{
ms_tick = 42;
}
void timer3_init(void)
{
// EMPFANGEN VON DATEN
// Timer3 - 10ms bei 2 Mhz
TCCR3B = 0x00; // Stop ---> timer/counter control
register
//TCCR3A = 0x00;
//TCCR3C = 0x00;
OCR3A = 19999; // TOP - Timer zählt bis zum maximalen
wert von 19999 und gibt einen Interrupt aus (Seite 140 im
Datenblatt)
TIMSK3 |= (1<<OCIE3A); // Timer/Counter Interrupt Mask
Register (Seite 142 im Datenblatt)
TCCR3B |= (1<<WGM32) | (1<<CS31); // Modus = CTC, Vorteiler
(prescaler) = 8 dies entspricht dann 2 MHz (Seite 138 im
Datenblatt)
}
void can_init(void) // CAN initialisieren
{
uint8_t i,j; // deklarienen von Variabeln
//uint16_t id; // Kurze ID aktiviren durch entfernen
von
uint32_t id; // Lange ID aktiv
CANGCON = (1<<SWRES); // Reset ---> can general control
register (Seite 252 im Datenblatt)
// reset all message objekts
for (i=0; i<15; i++) // Schleife
{
CANPAGE = (i<<4); // select message objekt
CANCDMOB = 0x00; // disable message objekt
CANSTMOB = 0x00; // Statusregister zurücksetzen
// clear CAN identifier tag registers
(Seite 263 im Datenblatt)
CANIDT1 = 0x00; // Register 1 zurücksetzen
CANIDT2 = 0x00; // Register 2 zurücksetzen
CANIDT3 = 0x00; // Register 3 zurücksetzen
CANIDT4 = 0x00; // Register 4 zurücksetzen
// clear CAN identifier mask registers
(Seite 265 im Datenblatt)
CANIDM1 = 0x00; // Register 1 zurücksetzen
CANIDM2 = 0x00; // Register 2 zurücksetzen
CANIDM3 = 0x00; // Register 3 zurücksetzen
CANIDM4 = 0x00; // Register 4 zurücksetzen
// clear CAN data message register
(Seite 266 im Datenblatt)
for (j=0; j<8; j++)
{
CANMSG = 0x00; // Register 1 zurücksetzen
}
}
// Einstellung für eine 250 kBit/s Baudrate mit 16 MHz Quarzoszillator
(Seite 267 im Datenblatt)
//CÁN bit timing register
CANBT1 = 0x06; // Register 1
CANBT2 = 0x0C; // Register 2
CANBT3 = 0x37; // Register 3
CANGCON = (1<<ENASTB); // Aktivieren des CAN-Busses
// CAN-Einstellung für den Mikrocontroller
id = 0x18FF50E5; // ID vom Mikrocontroller
CANPAGE = (0<<4); // Auswählen des MOB0
CANIDT1 = (id >> 3); // Setzen der Bits 3-10 der
Nachrichten-ID in das CANIDT1 Register
CANIDT2 = (id << 5); // Setzen der Bits 0-2 der
Nachrichten-ID in das CANIDT2 Register
CANIDM1 = 0xFF; // alles auf High-Pegel
setzten
CANIDM2 = 0xE0;
CANIDM4 = (1<<IDEMSK); // setzten des identifier
extension mask (Seite 265 im Datenblatt)
CANCDMOB = (1<<CONMOB1) | (1<<IDE) | 8; //
Empfangsmodus eingeschaltet für 8 Byte Nachrichtenlänge
// CAN-Einstellung für den emfänger
id = 0x1806E5F4; // ID vom Ladegerät
CANPAGE = (1<<4); // Auswählen des MOB1
CANIDT1 = (id >> 3); // Setzen der Bits 3-10 der
Nachrichten-ID in das CANIDT1 Register
CANIDT2 = (id << 5); // Setzen der Bits 0-2 der
Nachrichten-ID in das CANIDT2 Register
CANIDM1 = 0xff; // alles auf High-Pegel
setzten
CANIDM2 = 0xe0;
CANIDM4 = (1<<IDEMSK); // setzten des identifier
extension mask (Seite 265 im Datenblatt)
CANCDMOB = (1<<IDE) | 8; // Sendemodus
eingeschaltet für 8 Byte Nachrichtenlänge
CANSTMOB |= (1<<TXOK); // Interruptaufruf bei
Versandbestätigung einleiten
// CAN general interrupt enable register
CANGIE = 0x00; // gesamtes CAN general interrupt
enable register deaktivieren (Seite 255 im Datenblatt)
CANIE1 = 0x00; // message objekt interrupts 8-14
deaktiviert (Seite 257 im Datenblatt)
CANIE2 = 0x00; // message objekt interrupts 0-7
deaktiviert
CANSIT1 = 0x00; // CAN status interrupt message objekt
register 1 deaktivieren (Seite 257 im Datenblatt)
CANSIT2 = 0x00; // CAN status interrupt message objekt
register 2 deaktivieren
}
int main(void)
{
uint8_t data[8]; // deklaration von Variabeln
uint8_t can_delay = 0; // deklaration von Variabeln
int i; // deklaration von Variabeln
float current; // deklaration von Variabeln
current=32; // deklaration von Variabeln
// deklaration der emfangenen Datenbytes
int Byte1; // Ausgangsspannung HighByte
int Byte2; // Ausgangsspannung LowByte
int Byte3; // Ausgangsstrom HighByte
int Byte4; // Ausgangsstrom LowByte
int Byte5; // Fehlermeldungen
int Byte6; // nicht belegt
int Byte7; // nicht belegt
int Byte8; // nicht belegt
Byte1 = 0; // alle DatenBytes auf 0 setzten
Byte2 = 0;
Byte3 = 0;
Byte4 = 0;
Byte5 = 0;
Byte6 = 0;
Byte7 = 0;
Byte8 = 0;
//
cli();
timer3_init(); //TIMER3 initalisieren
can_init(); // CAN initalisieren
sei(); // alle Interrupts aktivieren
DDRB=0b00010101;
PORTB=(0<<PB0) | (0<<PB2) | (0<<PB4);
while (1)
{
if(ms_tick)
{
ms_tick = 0;
CANPAGE = (0<<4); // Auswählen des MOB0
if(CANSTMOB & (1<<RXOK)) // Wurden Daten Empfangen?
{
Byte1= CANMSG; //Empfangene Nachricht in Byte1-8
abspeichern
Byte2= CANMSG;
Byte3= CANMSG;
Byte4= CANMSG;
Byte5= CANMSG;
Byte6= CANMSG;
Byte7= CANMSG;
Byte8= CANMSG;
if (Byte5==0b00000001) //Wenn im Byte5=1 steht
{
PORTB=(1<<PB0); // Fehler: Hardwarefehler PB0 aktiv
}
else if (Byte5==0b00000010) //Wenn im Byte5=2 steht
{
PORTB=(1<<PB2); //Fehler: Übertemperatur PB2 aktiv
}
else if (Byte5==0b00000100) // Wenn in Byte 5=4 steht
{
PORTB=(1<<PB0) | (1<<PB2);
// Fehler: Eingangsspannung unzulässig
}
else if (Byte5==0b00001000) // Wenn in Byte 5=8 steht
{
PORTB=(1<<PB4); // Fehler Batterie nicht verbunden
}
else if (Byte5==0b00010000) //wenn in Byte 5=16 steht (in
Hex=10)
{
PORTB=(1<<PB0) | (1<<PB4);
//Fehler Can-Bus Fehler
}
else if (Byte5==0b00001100) // Wenn in Byte 5= 12 steht (in
Hex=C)
{
PORTB=(1<<PB2) | (1<<PB4);
//Fehler Keine Eingangsspannung
}
else
{
PORTB = (0<<PB0) | (0<<PB2) | (0<<PB4) ;
}
CANSTMOB &= ~(1<<RXOK); // Reset Flag
CANCDMOB = (1<<CONMOB1) | 8; // Empfangsmodus eingeschaltet für
8 Byte Nachrichtenlänge
}
can_delay++;
if(can_delay > 99)
{
can_delay = 0;
CANPAGE = (1<<4); // Auswählen des MOB1
if(CANSTMOB & (1<<TXOK)) // Senden beendet?
{
CANSTMOB &= ~(1<<TXOK); // Reset flag
CANMSG = 1;
CANMSG = 2;
CANMSG = 3;
CANMSG = 4;
CANMSG = 0;
CANMSG = 0;
CANMSG = 0;
CANMSG = 0;
CANCDMOB |= (1<<CONMOB0); // CAN übertragung einleiten
}
}
}
}
} //Fehler Can-Bus Fehler
}
else if (Byte5==0b00001100) // Wenn in Byte 5= 12 steht (in
Hex=C)
{
PORTB=(1<<PB2) | (1<<PB4);
}
else
{
PORTB = (0<<PB0) | (0<<PB2) | (0<<PB4) ;
}
CANSTMOB &= ~(1<<RXOK); // Reset Flag
CANCDMOB = (1<<CONMOB1) | 8; // Empfangsmodus eingeschaltet für
8 Byte Nachrichtenlänge
}
can_delay++;
if(can_delay > 9)
{
can_delay = 0;
CANPAGE = (1<<4); // Auswählen des MOB1
if(CANSTMOB & (1<<TXOK)) // Senden beendet?
{
CANSTMOB &= ~(1<<TXOK); // Reset flag
CANMSG = current;
CANMSG = current;
CANMSG = current;
CANMSG = current;
CANMSG = current;
CANMSG = current;
CANMSG = current;
CANMSG = current;
CANCDMOB |= (1<<CONMOB0); // CAN übertragung einleiten
}
}
}
}
}




