Kleine Aufgabe und AvR Rechnet falsch?

Gast #2170518
Lesenswert?

Hi ich hab nen kleines Programm geschrieben das einfach 4 bits also 
00001111
immer weiter nach links schieben soll und die bits die beim 8ten bit 
rausfallen sollen wieder im ersten bit reinfallen also
11110000
11100001
usw

Nun hab ich mir das ganze so aufgebaut das es logischer weise 
funktionieren müsste allerdings scheint avr irgenetwas komplett falsches 
zu tuhen D: 11100001= 240-15(=225) avr errechnet mir aber 223
Warum tut er dies?


1
//Schieber
2
#include <avr/io.h>
3
int f[3];
4
int main (void){
5

6

7

8
up:
9
f[1]=15;
10
f[2]=15;
11
f[3]=0;
12

13

14
while (f[3]<=4){
15

16
PORTB=f[1];
17
f[1]=f[1]*2;
18
f[3]++;
19
}
20

21

22
while (f[3]>=3){
23

24
f[1]=f[1]-f[2];
25
f[2]=f[2]*2;
26
PORTB=f[1];
27
f[3]--;
28
}
29
goto up;
30
return 0;
31
}
Gast #2170530
Lesenswert?

Patrick90 schrieb:
> up:
[...]
> goto up;
Pfui, nimm ne while(true){} , ist ganz schlechter stil

Ebenso rast dein Programm dadurch, ich denke mal, dass du es noch 
nichtmals flackern siehst, sondern die LEDs nur auf einer gewissen 
helligkeit sind?!

1. Tipp:
kein goto
2. Tipp: nach dem setzten von Portb _delay_ms(XX); verwenden
3. Tipp: bit schubserein verwenden, ich denke das ist eleganter als 
deine jetztige methode
4. anstatt int wüde ich byte verwenden
Gast #2170551
Lesenswert?

nimm bitoperationen

bsp. für 10x shiften:
1
unsigned char value = 0x0f;
2
unsigned char upperbit;
3
int i;
4
for (i=0; i<10; i++)
5
{
6
    upperbit = value & 0x80;        // oberstes bit merken
7
    value <<= 1;                    // nach links shiften
8
    if (upperbit) value |= 1;       // wenn oberstes bit gesetzt war, unterstes bit setzen
9

10
}
Gast #2170552
Lesenswert?

Schon mal was von einrücken gehöhrt?
Schon mal der erste Fehler:
1
int f[3];
2
f[3]=0;
Die Sache mit Arrays und Indizes solltest Du Dir nochmal anschauen.
An welcher Stelle im Program erhällst Du 223. Am Besten Du nimmst Dir 
Bleistift und Papier und spielst selber mal µC. Btw., Du weist aber 
schon, daß int 16 Bit hat?
Gast #2170556
Lesenswert?

// schiebt ein Byte bitweise nach links und fügt links herausfallende 
Bits
// rechts wieder ein.

uint8_t i;
i = irgendetwas;

while(1)
  {
  if (i & 0x80)    // das Bit.7 testen, wenn gesetzt
    {
    i << 1;    // nach links schieben und
    i++;    // das links rausgefallende Bit rechts wieder einfügen
    }
  else      // wenn Bit.7 nicht gesetzt,
    {
    i << 1;    // dann nur schieben
    }

  machwas_mit_dem_Byte;
  }
Persönliche Seite #2170587
Lesenswert?

Patrick90 schrieb:
> Nun danke für die Tipps aber die sind nun banal für mich btw bei der
> 2ten schleife soll <=1 stehen nicht 3
>
> es ist nur verwirrent das avr das nicht richtig berechnen kann =/

solche Aussagen sollte man sich schnell abgewöhnen - denn meistens sitzt 
der Fehler 50 cm vor dem Bildschirm. Es kommt zwar vor das uC's oder 
bestimmte Cores Fehler aufweisen, nur sind diese sehr sehr selten und 
meistens schon im DB dokumentiert. Steht dorts nichts sollte man den 
Fehler exakt identifizieren - und zwischen dem C-Sourcecode und dem 
Programmieren des uC's gibts noch einige Stationen wo etwas schief gehen 
kann ;).
Gast #2170603
Lesenswert?

Patrick90 schrieb:
> 11110000
> 11100001

da du den datentyp int geaehlt hast, ist f[] 2 byte gross. ausserdem 
wird eine multiplikation niemals durch das carry rotieren.
sonst wuerde ja aus einer gerade zahl (LSB = 0) irgendwann eine ungerade 
werden (LSB = 1)

deine erste schleife wird 5 mal durchlaufen, das ist dir klar?

debugge das programm schritt fuer schritt und beobachte die 
registerinhalte. an welcher stelle ist f[1] == 223? die info solltest du 
noch dazuschreiben.

das goto eine todsuende ist, wurde ja schon geschrieben.
Gast #2170662
Lesenswert?

Mein Gott, ihr könnt es aber auch kompliziert machen.

  MOVLW  B'00001111'
  MOVWF  MeineZelle        ; MeineZelle vorbelegen

zyklus:
  RLF    MeineZelle,W      ; MSB ins Carry
  RLF    MeineZelle,F      ; Carry ins LSB
  GOTO   zyklus

Sowas braucht beim PIC nur 800 ns, wovon der GOTO die Hälfte frißt.

Apropos GOTO, Ich halte das GOTO Statement sowohl bei C als auch bei 
Pascal durchaus nicht für schlechten Stil. Wo man eine Ewigschleife zu 
drehen beabsichtigt, da ist GOTO genau richtig!

Auf alle Fälle ist das besser und lesbarer als sowas wie while(true) 
{....}

oder gar while (1)....


W.S.
Gast #2170677
Lesenswert?

Patrick90 schrieb:
> fehler gefunden ^^ bei ersten while bedingung 3 anstatt 4

Ich liege am Boden.
Dein Code macht überhaupt nicht, was er soll. Er ist umständlich, 
langsam, fast unlesbar, und funktioniert nur mehr oder weniger zufällig 
für Zahlen <=15 als Startwert.
Arrays scheinen dir auch sehr zu gefallen, einfache Variablen sind ja 
schließlich langweilig.

Dann geben dir 2 Leute Tips, wie man Linksshifts mit Carry korrekt und 
auf einfache Weise implementiert, das interessiert dich aber nicht die 
Bohne.

Ich bin weg. Luft abgelassen.

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