Forum: Mikrocontroller und Digitale Elektronik Hardwarefehler finden


von Heike (Gast)


Lesenswert?

Ich habe an meinen ATmega einen RTL8019AS und ein externes SRAM mit dem 
benötigten Latch angeschlossen.
In das SRAM kann ich schreiben und auslesen.
Meine Hardware ist zweifach vorhanden und einmal funktioniert die 
Hardware -> es ist kein grundsätzlicher Verdrahtungsfehler. Die Software 
funktioniert auch.

Ich habe mit einem Multimeter die Verbindungen vom ATmega zum RTL8019AS 
nachgemessen und erkenne keine Fehler.

Nun wollte ich mit folgendem Testprogramm an jedem zweiten Ausgang zum 
RTL8019AS "5V" rausschicken und diese mit einem Oszi nachmessen:

{...
  PORTA &= ~(_BV(PA1)) | ~(_BV(PA3)) | ~(_BV(PA5)) | ~(_BV(PA7));
  PORTA =  _BV(PA0) | _BV(PA2) | _BV(PA4) | _BV(PA6);
  DDRG = (1<<DDG1);
  PORTG =  _BV(PG1);
  for (;;);
}

Wenn ich die Signale an diesen Pins anschaue, so wechseln sie von 
ständig zwischen 5V und 0V.

Liegt das an meinem Programm, oder kann es an der Hardware liegen. Soll 
ich die externen Pullups ausschalten?

von johnny.m (Gast)


Lesenswert?

> PORTA &= ~(_BV(PA1)) | ~(_BV(PA3)) | ~(_BV(PA5)) | ~(_BV(PA7));
Also kein Hardware-Fehler, sondern ein Software-Fehler...

Überlege mal, was die obige Anweisung macht. _BV(PA1) entspricht (1 << 
PA1), also 0b00000010. Dementsprechend ist ~(_BV(PA1)) ~(1 << PA1), also 
0b11111101. Dann hast Du noch ~(_BV(PA3)) usw.. Wenn Du die ganzen 
Bitmasken veroderst, kommt folgendes raus:
~(_BV(PA1))  -> 11111101
~(_BV(PA3))  -> 11110111
~(_BV(PA5))  -> 11011111
~(_BV(PA7))  -> 01111111
                --------
                11111111
Mit anderen Worten: Da steht immer 0b11111111 im Portregister! Wenn Du 
die Bits tatsächlich löschen willst, dann muss es
1
PORTA &= ~(_BV(PA1) | _BV(PA3) | _BV(PA5) | _BV(PA7));
heißen.

von Rahul, der Trollige (Gast)


Lesenswert?

de Morgan lässt grüssen...

von Rahul, der Trollige (Gast)


Lesenswert?

Entweder so:
>PORTA &= ~(_BV(PA1) | _BV(PA3) | _BV(PA5) | _BV(PA7));

oder (vermutlich) so:
PORTA |= ~_BV(PA1) &  ~_BV(PA3) & ~_BV(PA5) & ~_BV(PA7));

von johnny.m (Gast)


Lesenswert?

@Rahul:
Einen wunderschönen guten Morgen! Also auf ein neues... Hast Du die 
Voodoo-Puppe schon griffbereit;-?

von Rahul, der Trollige (Gast)


Lesenswert?

>Hast Du die Voodoo-Puppe schon griffbereit;-?

Fühlst du noch keine Schmerzen? Dann ist das Püppchen kaputt... ;-)

von marc989 (Gast)


Lesenswert?

Leider kennen viele die De Morganschen Gesetze nicht, obwohl sie einem 
das Leben so vereinfach können :-))

Gruß Marc

von Heike (Gast)


Lesenswert?

OK, sorry!

Könnt ihr einer Anfängerin trotzdem noch helfen?

Ist das dann so richtig?
...
  DDRC &= ~( (1<<PC1) | (1<<PC3) | (1<<PC5) | (1<<PC7) );
  PORTC |= ~_BV(PC1) & ~_BV(PC3) & ~_BV(PC5) & ~_BV(PC7);

  DDRA &= ~( (1<<PA1) | (1<<PA3) | (1<<PA5) | (1<<PA7);
  PORTA |= ~_BV(PA1) & ~_BV(PA3) & ~_BV(PA5) & ~_BV(PA7);

  DDRG |= (1<<PG1);
  PORTG |= (1<<PG1);

Ich find das total unübersichtlich...

von johnny.m (Gast)


Lesenswert?

Das ist tatsächlich unübersichtlich. Warum machst Du es nicht immer auf 
dieselbe Weise? Meist werden die Bitmasken erst alle verODERt und dann 
invertiert, um Bits zu löschen, also:
1
REGISTER &= ~(_BV(BIT1) | _BV(BIT2) | _BV(BIT3)); //...usw
Beim Setzen der Bits dann einfach das UND durch ein ODER ersetzen und 
den Bitkomplement-Operator weglassen, also
1
REGISTER |= _BV(BIT1) | _BV(BIT2) | _BV(BIT3); //...usw
Alles klar? Ansonsten hilft das AVR-GCC-Tutorial weiter...

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
Noch kein Account? Hier anmelden.