CAN auslesen AT90CAN128

OP #4218738
Lesenswert?

Hallo Community,
Zwar habe ich folgendes Problem.
Ich wollte für ein Projekt mithilfe des AT90CAN128 CAN Ids auslesen und 
diese über ein Display ausgeben.
Leider bekomme ich es nicht genau hin. Habe auch schon die Forumssuche 
benutzt, aber hier findet man meist nur Beispiele zum senden und 
antworten.
Der Controller soll eigentlich "nur" Ids auslesen können.
Jetzt wollte ich hier Fragen ob jemand hierfür vielleicht einen Beispiel 
Code oder eine Lib oder sonstiges hätte.
Schonmal danke im Vorraus.

Mit freundlichen Grüßen
Julian
OP #4218763
Lesenswert?

Vielen Dank. Diesen Beitrag habe ich auch schon komplett durchgepaukt. 
Da fehlt mir aber leider ein Beispiel zum ID empfangen.
Nehmen wir an ich will den Inhalt von dem unsigned int mit der ID 
0x773[2]als Beispiel in eine Variable speichern, sodass ich die auf 
einem Display ausgeben kann.
Der Codeschnipsel welcher dann in der Main stehen würde, den bekomme ich 
einfach nicht hin.
Vielleicht weiß ja noch jemand was.
Schonmal danke im Vorraus.
Gast #4218775
Lesenswert?

So in etwa mache ich das:
1
ISR(CANIT_vect)
2
{
3
  CANPAGE = CANHPMOB;
4

5
  // Hier CANIDT auswerten
6

7
  ...
8
          
9
  CANSTMOB = 0;
10
  CANCDMOB = (2<<CONMOB0)|8;
11
}
12

13
void main()
14
{
15
  // 125 kHz @ 16MHz
16
  CANBT1 = 0x1e;
17
  CANBT2 = 0x04;
18
  CANBT3 = 0x13;
19
  
20
  // 8 mobs für Empfang
21
  for (uint8_t page=0; page<0x70; page+=0x10)
22
  {
23
    CANPAGE = page;
24
    CANSTMOB = 0;
25
    CANIDT = 0;
26
    CANIDM = 0;
27
    CANCDMOB = (2<<CONMOB0)|8;
28
  }
29
    
30
  CANGCON = (1<<ENASTB);
31
  CANGIE = (1<<ENIT)|(1<<ENRX);
32

33
  CANIE2 = 0xFF; // interrupts für mobs 0-7
34
  
35
  sei();
36
  while(1);
37
}
OP #4218810
Lesenswert?

Vielen Dank!
Wenn ich dass richtig sehe, kann ich dann dort meine IDs anpassen. Und 
wenn noch mehr hinzukommen, da in dem Beispiel ja nur zwei sind. Einfach 
eine weitere Canpage hinzufügen und dann kann ich auf die IDs zugreifen.
Jedoch verstehe ich nicht wie sie bei CANMSG auf 0x55 und 0xaa kommen, 
da ihre Empfangs ID ja 0x333 ist.
Entschuldigen Sie für die vielleicht unnötigen Fragen, aber bin sehr neu 
in diesem Gebiet.
Schonmal Danke im Vorraus.
#4218820
Lesenswert?

Julian M. schrieb:
> Wenn ich dass richtig sehe, kann ich dann dort meine IDs anpassen. Und
> wenn noch mehr hinzukommen, da in dem Beispiel ja nur zwei sind. Einfach
> eine weitere Canpage hinzufügen und dann kann ich auf die IDs zugreifen.

Im CANPAGE Register steht drin, auf welche Message-Box sich die aktuelle 
Aktion gerade bezieht.
Das wird im Interrupt gesichert damit man nicht die Hauptschleife 
durcheinander wirft.
Also im Grunde meinst Du wahrscheinlich das richtige, so formuliert 
hätte ich das aber nicht.
Wenn man das mit dem Filter so benutzt das pro Message eine ID verwendet 
wird, dann muss man für eine weitere ID eine neue Message-Box 
konfigurieren.

> Jedoch verstehe ich nicht wie sie bei CANMSG auf 0x55 und 0xaa kommen,
> da ihre Empfangs ID ja 0x333 ist.

0x55 0xaa ist der Botschafts-Inhalt, nur so als Beispiel.

Die bis acht Byte der Botschaft liegen ja nicht in acht Registern, der 
Zugriff erfolgt über das eine CANMSG Register.

Ach ja, die Botschaft wird in dem Beispiel nicht mal gelesen, es wird ja 
nur dessen Empfang festgestellt und ein Flag gesetzt.

Übrigens, die CANEN Zeilen in der Init sind überflüssig - stören aber 
auch nicht.
OP #4218906
Lesenswert?

Vielen Dank, dass du dir dafür so Zeit nimmst.
Habe dann nun auch alles soweit verstanden.
In dem Beispiel Programm wird getestet ob er eine Nachricht erhält und 
wenn diese Erhalten wurde. Schickt er eine Neue Massage los mit dem 
Message Inhalt 0x55 und 0xaa.
Dann muss ich mich jetzt nur noch Informieren wie man die Message dann 
ausließt und in eine Variable speichern kann, welche ich dann auf dem 
Display ausgeben kann.
Ist alles komplizierter als Gedacht, da man im Internet zum reinen 
Auslesen nicht sonderlich viel findet. Sondern eher zum Senden.
#4218917
Lesenswert?

Julian M. schrieb:
> Dann muss ich mich jetzt nur noch Informieren wie man die Message dann
> ausließt und in eine Variable speichern kann, welche ich dann auf dem
> Display ausgeben kann.

Die Daten sind wie geschrieben im CANMSG Register.
Man muss die also nur noch auslesen:
1
if(CANSIT2 & 0x02) // MOB1
2
{
3
  CANPAGE = (1<<4); // select MOB1
4
  CANSTMOB &= ~(1<<RXOK); // clear interrupt flag
5
  CANCDMOB = (1<<CONMOB1) | (1<<DLC3);
6

7
  var1 = CANMSG;
8
  var2 = CANMSG;
9
  var3 = CANMSG;
10
  var4 = CANMSG;
11
  var5 = CANMSG;
12
  var6 = CANMSG;
13
  var7 = CANMSG;
14
  var8 = CANMSG;
15

16
  can_received = 42;
17
}

Oder mit ner Schleife in ein Array schieben, oder was auch immer. :-)

Im CANPAGE Register steht dazu noch ein Index und es gibt ein Auto-Index 
Bit, die werden durch den Zugriff auf CANPAGE auf Null gesetzt und 
fertig.

Und als einfaches Beispiel fängt das Null Fehler ab, zum Beispiel könnte 
eine Botschaft mit weniger Byte eingehen als erwartet werden.
OP #4219272
Lesenswert?

Vielen Dank für Alles habe nun mal mein Bestes gegeben und den C-Code 
angehängt. Vielleicht könnten sie ja, wenn sie Zeit haben mal drüber 
schauen.
Habe das Beispiel angepasst. Wollte fragen ob dies so stimmt und ich 
dann in der While Schleife auch immer den Aktuellen Wert habe. Habe auch 
noch eine zweite Id zum empfangen eingestellt.
Schonmal danke im Vorraus.
Angehängte Dateien:
#4219286
Lesenswert?

Da sind ein paar Schnitzer drin, das funktioniert so nicht.
1
  id = 0x773;   // Empfangs-ID
2
  CANPAGE = (1<<4); // select MOB1
3
  CANIDT1 = (id >> 3); // Put bits 3-11 of message ID into CANIDT1
4
  CANIDT2 = (id << 5); // Put bits 0-2 of message ID into CANIDT2
5
  CANIDM1 = 0xff;
6
  CANIDM2 = 0xe0;
7
  CANIDM4 = (1<<IDEMSK);
8
  CANCDMOB = (1<<CONMOB1) | (1<<DLC3); // set to receive, 8-bytes in message
9

10
  id = 0x775;   // Empfangs-ID
11
  CANPAGE = (2<<4); // select MOB2
12
  CANIDT1 = (id >> 3); // Put bits 3-11 of message ID into CANIDT1
13
  CANIDT2 = (id << 5); // Put bits 0-2 of message ID into CANIDT2
14
  CANIDM1 = 0xff;
15
  CANIDM2 = 0xe0;
16
  CANIDM4 = (1<<IDEMSK);
17
  CANCDMOB = (1<<CONMOB1) | (1<<DLC3); // set to receive, 8-bytes in message
18

19
  CANGIE = (1<<ENIT) | (1<<ENRX); // enable receive interrupt
20
  CANIE1 = 0x00;
21
  CANIE2 = (1<<IEMOB1); // enable MOB1 IRQ
22
  CANIE2 |= (1<<IEMOB2); // enable MOB2 IRQ
23
  CANSIT1 = 0x00;
24
  CANSIT2 = 0x00;
25
}

Den Block unter der Konfiguration für die jeweiligen Message-Boxen 
braucht man nur einmal und wenn man ein Register wie CANIE2 ein zweites 
Mal beschreibt dann besser mit einer Read-Modify-Write Operation. :-)
1
ISR (CAN_INT_vect)
2
{
3
  uint8_t canpage;
4

5
  canpage = CANPAGE; // save canpage
6

7
  if((CANSIT2 & (1<<SIT1)) != 0) // MOB1
8
  {
9
    CANPAGE = (1<<4); // select MOB1
10
    CANSTMOB &= ~(1<<RXOK); // clear interrupt flag
11
    CANCDMOB = (1<<CONMOB1) | (1<<DLC3);
12

13
    int i;
14
    unsigned int messwerte[8];
15

16
    for(i=0; i<8; i++) {
17
      
18
    messwerte[i] = CANMSG;
19
    
20
    }
21

22
    can_received = 42;
23
  }
24
  
25
  if((CANSIT2 & (1<<SIT2)) != 0) // MOB2
26
  {
27
    CANPAGE = (2<<4); // select MOB1
28
    CANSTMOB &= ~(1<<RXOK); // clear interrupt flag
29
    CANCDMOB = (1<<CONMOB1) | (1<<DLC3);
30

31
    int i;
32
    unsigned int temperatur[8];
33

34
    for(i=0; i<8; i++) {
35
      
36
      temperatur[i] = CANMSG;
37
      
38
    }
39

40
    can_received = 42;
41
  }
42

43
  CANPAGE = canpage; // restore canpage
44
}

Ähem, erstmal sind die Variablen lokal für die Funktion, das verlässt 
den Interrupt doch nie.
Und dann ist es "(1<<SIT2)" für MOB2.

Und die 1980er klingeln gerade durch und wollen Ihre Variablen vom Typ 
"int" und "unsigned int" wieder haben. ;-)

1
  DDRB = 0x00;  // alle Pins auf Eingang
2
  PORTB = 0xff; // Pullups an
3

4
  DDRC = (1<<PC2) |(1<<PC7) | (1<<PC6);
5
  PORTC = 0xff; // Pullups an / Ausgang auf High
6

7
  DDRD = 0x00; // alle Pins auf Eingang
8
  PORTD = 0xff; // Pullup-Widerstände an
9

10
  DDRE = 0x00;  // alle Pins auf Eingang
11
  PORTE = 0xff; // Pullups an

Da fehlt noch einiges, der 90CANxx hat noch ein paar Ports mehr
und TXCAN auf PD5.
Das ist einfach nur Copy-Paste von meinem Mega16M1 Beispiel.
1
  while(1)
2
  {
3
    // Hier kann ich dann einfach den Wert der Id ausgeben lassen?
4
    // also in dem ich einfach in den Displaybefehl als ausgabewert messwerte[3] eingebe?
5
    // und auch zum Beispiel temperatur[4]?
6
  }
7
}

Ja, sobald die auch verfügbar sind. :-)

Also am einfachsten Global deklariert mit volatile wie die 
"can_received" Variable und mit Default-Wert.
#4219555
Lesenswert?

1
  CANGCON = (1<<SWRES); // off and reset
2

3
  for (i=0; i<6; i++)
4
  {
5
    CANPAGE = (i<<4); // select MOb

Mach aus der "6" mal noch eine 15, der 90CAN hat ein paar Message-Boxen 
mehr. :-)
1
volatile uint16_t messwerte[8]={0};
2
volatile uint16_t temperatur[8]= {0};

Warum eigentlich 16 Bit wenn die Werte doch nur 8 Bit breit sind?
1
  DDRD = (1<<PD5) |(1<<PD6);
2
  DDRA = 0xFF;  // Hier sind LEDs angeschlossen
3
  DDRC = 0xFF;  // Hier sind LEDs angeschlossen

Also kann ja jeder machen wie er will, aber normalerweise initalisiere 
ich erstmal alle Ports komplett durch und schalte bei den unbenutzen 
Pins die Pullup-Widerstände ein.

Und ja, in dem Context würde ein "PORTA = 0x00" nichts bewirken weil das 
Register nach dem Reset sowieso auf Null steht, ich finde es aber 
übersichtlicher explizit hinzuschreiben was man vorhat.
OP #4219626
Lesenswert?

Vielen Dank, dank ihnen verstehe ich nun einigermaßen was ich mache :)
Habe nun noch meine letzte ID hinzugefügt.
Ist eine Multiplex ID, hoffe ich habe sie richtig realisiert.
Nun habe ich jedoch noch eine Frage, wird der Interrupt dann immer von 
selbst ausgelößt oder muss ich den in der Main() auch irgendwo auslösen?
Dass ich immer die Aktuelle Zahlen habe und nicht nur die, die er beim 
ersten Durchgang rausließt.
Schonmal danke im Vorraus
Angehängte Dateien:
#4219662
Lesenswert?

Julian M. schrieb:
> Ist eine Multiplex ID, hoffe ich habe sie richtig realisiert.

Sieht gut aus, ist nur nicht ganz optimal.
1
  for(i=0; i<8; i++) { // Ist ein Multiplex mit 3 Row
2
         // Welche Row dran ist wird im Bit 0 übertragen
3
    if (i==0){
4
      row=CANMSG;
5
    }else{
6
    temperatur[i][row] = CANMSG;
7
    }
8
  }


Das "if(i==0)" wird bei jedem Durchlauf mit überprüft.
1
        row = CANMSG;
2

3
  for(i=0; i<7; i++) {
4
    temperatur[i][row] = CANMSG;
5
  }

Als Optimierung etwas witzlos, zugegeben, man sollte Interrupts aber 
auch immer so kurz wie möglich halten.

> Nun habe ich jedoch noch eine Frage, wird der Interrupt dann immer von
> selbst ausgelößt

Ja, es gibt automatisch einen IRQ wenn eine Botschaft mit der passenden 
ID empfangen wurde.

> Dass ich immer die Aktuelle Zahlen habe und nicht nur die, die er beim
> ersten Durchgang rausließt.

Das Flag "can_received" ist in meinem Beispiel dafür da der 
Hauptschleife zu melden, dass was empfangen wurde.
Das könnte man dafür nutzen um ein Display nur bei Änderungen zu 
aktualisieren.
1
if(can_received != 0)
2
{
3
 can_received = 0;
4
 mach_was_mit_den_daten();
5
}

Wobei das auch drei Flags sein könnten, für jede Botschaft einzeln.

can_received_temperatur
can_received_gang
can_received_messwerte

Oder so ähnlich. :-)
Oder ganz weglassen geht auch. :-)
OP #4219764
Lesenswert?

Vielen Dank.
Habe nun meinen Code soweit fertig, es kommen auch keine Error 
Meldungen.
Kann ihn leider warscheinlcih erst Dienstag testen.
Jedoch kommen zwei Warnings einmal:
Warning  1  #warning "F_CPU not defined for <util/delay.h>" [-Wcpp]
Obwohl ich
#define F_CPU 16000000ULL
#include <util/delay.h>
geschrieben habe.

Die zweite Warning verstehe ich leider gar nicht und weis auch nicht, 
nach was ich im Internet suchen sollte.

Warning  2  'CAN_INT_vect' appears to be a misspelled signal handler 
[enabled by default]

Schonmal danke im Vorraus. :)
Angehängte Dateien:
#4219835
Lesenswert?

Julian M. schrieb:
> Warning  1  #warning "F_CPU not defined for <util/delay.h>" [-Wcpp]
> Obwohl ich
> #define F_CPU 16000000ULL
> #include <util/delay.h>
> geschrieben habe.

Hmm, das bekomme ich garnicht.
Ich habe gerade ein neues Projekt aufgemacht mit dem 90CAN128, Deinen 
Text rein kopiert, das GLCD Zeug auskommentiert und durchlaufen lassen.

Auch ein zusätzliches "_delay_ms(12);" führt zu keiner Warnung.

> Die zweite Warning verstehe ich leider gar nicht und weis auch nicht,
> nach was ich im Internet suchen sollte.
>
> Warning  2  'CAN_INT_vect' appears to be a misspelled signal handler
> [enabled by default]

Das kommt davon, wenn man das "trocken" macht. :-)
Das muss "ISR (CANIT_vect)" sein.

Aber ich bekomme noch zwei Warnung für das hier:
1
  sprintf(wassertempstring, "%i", temperatur[2][6]);
2
  sprintf(oiltempstring, "%i", temperatur[2][7]);

Die Variable ist so definiert:
1
volatile uint8_t temperatur[8][3]={{0},{0}};
OP #4221291
Lesenswert?

Also habe es heute geflasht, leider hatte ich heute keine möglichkeit 
die Can übertragung zu testen, werde ich morgen machen.
Jetzt aber eine Frage muss ich dass ISR wieder umbennen wenn ein CAN 
angeschlossen ist?
Und ist es normal, dass wenn kein CAN angeschlossen ist, auf dem Display 
an den Postionen der Prints eine Art Verpixeltes Zeichen erscheint? Da 
die Zahlen ja eigentlich mit 0 deklariert sind.
Schonmal danke im Vorraus.
Angehängte Dateien:
#4226476
Lesenswert?

Spontan fällt mir auf, dass da erheblich zu wenig Kondensatoren an den 
Versorgungs-Anschlüssen der ICs sind.

Und wieder mal die "typischen" 22pF Kondensatoren am Quarz - welcher 
Quarz ist das genau?

Sind die Fuse-Bits im Controller richtig gesetzt so das der auch 
wirklich auf den 16 MHz läuft?

Edit: Was zum Henker soll da drauf ein 3A Schaltregler?
#4226500
Lesenswert?

Julian M. schrieb:
> Es ist ein 16 MHz Quartz.

Ja, schon, aber welcher genau?

> Die Fuse-Bits müssten richtig gesetzt sein.

Müssten oder sind? :-)

> Sie haben mir ja damals ein Testprogramm geschickt und dort war
> ja auch auf 16 Mhz eingestellt

Das Programm ändert aber nichts an den Einstellungen, das Programm geht 
von dieser Konfiguration aus.

> und sie meinten ja dass im CAN bereicht,
> sich der Chip nicht unterscheidet zum AT90CAN128.

Das ist richtig, bis auf die Anzahl der Message-Objekte unterscheiden 
sich die CAN-Einheiten nicht.
#4226512
Lesenswert?

Julian M. schrieb:
> Oh wo sehe ich welcher Quartz dies genau ist. Wie schon gesagt ist mein
> erstes Projekt und habe die Platine so bekommen.

Dann kann man nur hoffen, dass derjenige der das gebaut hat wusste, was 
er tut, am Schaltplan lässt sich das aber leider erstmal nicht wirklich 
fest machen.
Hast Du auch das Layout? Wie sieht der Quarz denn aus?
Bei 500 kBit wird es aber so oder so hoffentlich nicht daran liegen.

> Achso wenn das Programm nichts an den Einstellungen ändert wird dies
> wohl der Fehler sein. Habe dann gar keine Einstellungen.

Kommt darauf an ob der Controller auf dem Board noch ganz frisch war 
oder ob damit schon jemand rumgespielt hat.
Mach im Programmier-Fenster mal die "Fuse" Einstellungen auf und mach 
Screenshots davon.
#4226626
Lesenswert?

Julian M. schrieb:
> Daran wirds dann wohl liegen oder?

Yup, genau daran liegt es, der Controller läuft dann  nur aus dem 
internen RC-Oszillator mit 1 MHz.

Leider kann ich im Emulator den 90CAN128 nicht auswählen, ich habe aber 
auch keinen Programmer hier.

Auf jeden Fall muss die CKDIV8 Fuse aus sein.
Und mach mal nen Screenshot von den Einstellung für den Takt, aus dem 
Kopf heraus müsste das eine der Optionen ganz unten sein, stelle aber 
besser nichts ein wenn Du nicht sicher bist.

Edit, habe mal nen Bild angehängt.
Das kommt von http://www.engbedded.com/fusecalc/
Angehängte Dateien:
#4226732
Lesenswert?

Das Layout ist auch an mehreren Stellen falsch, viel Erfahrung hatte der 
Benedict damit nicht.
Aber ich gehe mal davon aus, dass das mal irgendwie funktioniert hat 
wenn das in einem Formula-Student Racer verbaut war.

Die 22pF sind übrigens wirklich falsch für den Quarz, in der Bauform 
haben die typisch ein CL von 30pF und bräuchten so je 56pF.
Nur sollte der dennoch anlaufen und der CAN müsste bei 500kBit gerade 
noch so laufen.

Der CAN-Transceiver ist jedenfalls richtig verdrahtet, dem fehlt nur ein 
Kondensator an der Versorgung.

Die Fuses passen jetzt?
Ist der Jumper am CAN gesteckt, oder ein externe 120 Ohm am Bus oder in 
der "BOSCH MS4 Box" 120 Ohm verbaut/aktiviert?
OP #4226740
Lesenswert?

Vielen Dank, habe gerade erfahren, dass es noch nie funktioniert hat. 
Ein Jumper ist nicht gesteckt. Ich glaube in der box sind die 120ohm 
aktiviert, denn wenn man Daten direkt ausließt von der ms4 also mit 
einem converter anschließt und dann empfängt man zum Beispiel mit 
busmaster die Botschaften.
Die Fuses müssten nun passen.
Vielen Dank für alles, ich halte euch auf dem laufenden ob es 
funktioniert.
#4226753
Lesenswert?

Julian M. schrieb:
> Vielen Dank, habe gerade erfahren, dass es noch nie funktioniert hat.

Na, die Vögel sind ja lustig, Dir so ein Board anzudrehen. :-)

Was passiert denn wenn Du an das lauffähige System aus Bosch-Box und 
USB-CAN-Adapter mit Busmaster die Platine auch noch als dritten 
Teilnehmer anschliesst?

Ach ja, noch einen, hast Du jetzt eigentlich die Port Konfiguration noch 
ergänzt? In Deinem letzten Test-Programm stand da ja quasi noch nichts 
drin.
OP #4226758
Lesenswert?

Habs die Ports für den can auf high gesetzt. Dann die Ports für die LEDs 
als Ausgang gesetzt und dann halt noch das Display initialisiert.
Wenn ich die Platine als dritten Teilnehmer anschließe ist es so, dass 
die eigentlich gar nicht reagiert. Also es verändern sich keine Werte 
auf dem display oder so.
OP #4226774
Lesenswert?

Nein keine error frames, also die ms4 sendet aufjedenfall die 
Botschaften richtig. Das Problem ist, dass er nicht in das ISR reingeht 
irgendwie.
Ob die Ports alle richtig sind kann ich leider nicht sagen. Dafür kenne 
ich mich zuwenig aus, ist mein erstes Projekt. Habe halt im Internet 
nach geschaut, welche Ports der at90can128 für die can Übertragung 
braucht und die habe ich auf high gesetzt. Wahrscheinlich habe ich mich 
mit diesem Projekt einfach übernommen. Und die Ports für das display 
usw. Sind richtig gesetzt. Den ich habe das Programm mal so 
umgeschrieben dass anstatt die can Daten. Festgelegte Werte genommen 
werden die sich verändern. Dann funktioniert auch alles wunderbar.
#4226808
Lesenswert?

Hier:
1
void init_ports(void)
2
{
3
  DDRA = 0xFF;  // Hier sind LEDs angeschlossen
4
  PORTA = 0x00;
5

6
  DDRB = (1<<PB1) | (1<<PB2) | (1<<PB4) | (1<<PB5) | (1<<PB6); // LCD-Ports auf Ausgang setzen
7
  PORTB = (1<<PB0) | (1<<PB7); // Pullups an ungenutzen Pins einschalten
8

9
  DDRC = 0xFF;  // Hier sind LEDs angeschlossen
10
  PORTC = 0x00;
11

12
  DDRD = (1<<PD5);
13
  PORTD = (1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD7);  // Pullups an ungenutzen Pins einschalten
14

15
  DDRE = (1<<PE1);
16
  PORTE = (1<<PE2) | (1<<PE3) | (1<<PE4) | (1<<PE5) | (1<<PE6) | (1<<PE7);  // Pullups an ungenutzen Pins einschalten
17

18
  DDRF = 0x00; // alle Pins auf Eingang
19
  PORTF = 0xff; // Pullup-Widerstände an
20

21
  DDRG = 0x00; // alle Pins auf Eingang
22
  PORTG = 0xff;  // Pullup-Widerstände an
23
}

Beim PORTB für das LCD bin ich mir nicht sicher, die müssten irgendwo 
anders noch initialisiert werden, dazu fehlt aber jeglicher Aufruf in 
Deinem Programm.

Eine LED kann man wackeln lassen mit dem PIN-Register:

PINC = (1<<PC0); // Zustand von LED1 wechseln

Das geht nicht mit allen AVR, aber beim 90CAN funktioniert das so.
1
ISR (CANIT_vect)
2
{
3
    uint8_t canpage;
4

5
    PINC = (1<<PC0); // Zustand von LED1 wechseln

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren