Forum: Mikrocontroller und Digitale Elektronik Lauflicht im ATmega8


von WeißNichtWeiter (Gast)


Lesenswert?

Hi,
ich habe da einen Konflikt mit meinem ATmega8.
Also ich habe folgenden Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
int main()
5
{
6
  DDRB = 0xFF;
7
  PORTB = 0xFF;
8
  while (1)
9
  {
10
  if(PORTB==0xFF)
11
    PORTB=0xFE;
12
  else
13
    PORTB=PORTB*2+1;
14
  _delay_ms(100);
15
  }
16
  return 0;
17
}
Alle LEDs aus mit 0xFF = 0b11111111 = 255
Wenn PORTB jetzt 0xFF ist, was er ja anfangs ist wird er 0xFE gesetzt = 
254 = 0b11111110
Es leuchtet LED0.
Dann wird PORTB x 2 also 254 x 2 = 508 + 1 = 509 = 1FD
Wenn jetzt nur 2 Hexadezimale stellen verarbeitet werden können wird die 
1 nicht beachtet und es ergibt sich 0xFD = 253 = 0b11111101
LED1 leuchtet. Es ergibt sich ein lauflicht...

Ändere ich den Code so das das Licht andersrum laufen soll:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
int main()
5
{
6
  int a;
7
  DDRB = 0xFF;
8
  PORTB = 0xFF;
9
  while (1)
10
  {
11
  if(PORTB==0x01)
12
    PORTB=0xFF;
13
  else
14
    PORTB=(PORTB-1)/2;
15
  _delay_ms(100);
16
  }
17
  return 0;
18
}
PORTB ist 0xFF wird also -1 und dann /2 gerechnet: 255 - 1 = 254 / 2 = 
127 = 0x7F = 0x01111111
Es sollte LED7 leuchten.
127 - 1 = 126 / 2 = 63 = 3F = 0x00111111
Es sollten LED7 und LED6 leuchten.

Allerdings leuft kein Licht. Hab ich irgendwo einen denkfehler? Helft 
mir bitte auf die Sprünge.

von Karl H. (kbuchegg)


Lesenswert?

WeißNichtWeiter schrieb:

> Allerdings leuft kein Licht. Hab ich irgendwo einen denkfehler? Helft
> mir bitte auf die Sprünge.

Der Simulator sagt auch, dass das laufen müsste.

Ob es wohl damit zusammen hängt, dass PB6 und PB7 als Spezialfunktion 
die XTAL Pins sind, über die ein Quarz an den Mega8 angeflanscht wird.

Wechsle mal auf den PORT D
Dort hast du auch noch einen vollständigen 8 Bit Port


Übrigens:
In deiner Applikation willst du Bits schieben.
An dieser Stelle solltest du dann auch die C eigenen Schiebeoperationen 
benutzen und nicht mit * und / rumhampeln.

  b =  a << 1;
b erhält den Wert, den man bekommt wenn a bitmässig um 1 Stelle nach 
links geschoben wird.

  b =  a >> 1;
b erhält den Wert, den man bekommt wenn a bitmässig um 1 Stelle nach 
rechts geschoben wird.

von WeißNichtWeiter (Gast)


Lesenswert?

Ok mit Schiebeoperatoren klappts. Auch auf PORTB.
Danke

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

WeißNichtWeiter schrieb:
> Ok mit Schiebeoperatoren klappts. Auch auf PORTB.

Weisst Du auch warum?

Deswegen:
1
PORTB=(PORTB-1)/2;

(PORTB-1) könnte negativ werden, also wird eine vorzeichenbehaftete 
Division durchgeführt. Da eine vorzeichenbehaftete Division durch 2 
nicht identisch ist mit dem Schieben nach rechts (denn das 
Vorzeichen-Bit muss dabei erhalten bleiben), geht das voll in die Hose.

Gruß,

Frank

von WeißNichtWeiter (Gast)


Lesenswert?

Achso so hab ich das noch garnicht gesehen, klingt aber logisch...
Danke für die nachträgliche Aufklärung ;)

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.