Hallo,
ich wuede gerne im uC prufen ob ich mehrere einsen oder nullen anliegen
habe (8bit). kenn mir jemand einen tip geben.
Machs mir glaub irgendwie bisschen umstaendlich.
Ich wuerde alle zusammenzaehlen und entweder:
>4 mehr einsen
<4 mehr nullen
==4 anzahl gleich
gehts irgendwie einfacher mit maskieren oder spezielle befehle. ich
programmiere in.
gruss
Hallo,
Einem Byte kann man die Werte nach folgneder Tabelle zuordnen:
1
0000 0000 <
2
0000 0001 <
3
0000 0010 <
4
0000 0011 <
5
0000 0100 <
6
0000 0101 <
7
0000 0110 <
8
0000 0111 <
9
0000 1000 <
10
0000 1001 <
11
...
12
0000 1110 <
13
0000 1111 =
14
0001 0000 <
15
...
16
0001 1110 =
17
0001 1111 >
18
0010 0000 <
19
....
Also stell eine Tabelle (array, 256 Bytes) auf mit den korrekten
Einträgen <,=,>, lies das Portbyte ein und verwende es als Index für den
Zugriff auf die Tabelle. Geht maximal schnell, verbraucht dafür 256
Byte.
Georg
Kannst du mir verraten, warum du mit dem externen Interrupt die Dinge
schon wieder komplizierter machen musst, als unbedingt notwendig?
Warum nicht beim ersten Versuch alles so einfach wie möglich, so dass
man möglichst wenig Chancen auf Fehler hat? Hauptschleife { P0 einlesen
- Anzahl Bits bestimmen - auf P1 ausgeben }. Fertig. Mehr braucht es für
den ersten Versuch nicht. Alles darüber hinausgehende birgt nur wieder
neue Möglichkeiten für Fehler, die mit dem eigentlich zu Testenden
nichts zu tun haben.
Abgesehen davon solltest du dir mal über Datentypen Gedanken machen.
Einfach für alles "int" zu verwenden ist nicht nett dem µC gegenüber. Du
treibst ihn damit in 16 Bit Verarbeitung rein, die nicht sein müsste.
Dein Programm handelt im wesentlichen von Bytes. Dafür ist 'unsigned
char' der Datentyp der Wahl, oder wenn du hast 'uint8_t'.
marten schrieb:> Interrupt raus gemacht, volatile rein gemacht. Keine Veraenderung...
... die jetzige Version erneut zeigen.
Aus eigener Erfahrung: Es gibt kein Programm, das einfach genug wäre als
das man nicht blöde Fehler machen kann, die man dann auch selbst nicht
sieht.
Karl Heinz schrieb:> ich würde das zumindest soweit korrigieren, dass ich P1 auf Ausgang> setze, wenn ich was ausgeben will.
no passt schon, so macht man das bei 8051ern.
Beitrag "Re: Ports AT89S8253"
@Marten: was legst du denn an P0 an und was kommt an P1 raus? Hast du
die Pegel mal nachgemessen?
Wir arbeiten an einem Experimentierboard Easy8051B.
An P0 sind Pushbuttons angeschlossen. Wir wollen die einsen, die an
Port0 anliegen zaehlen und den wert dan an P1 ausgeben.
Wenn ich z.B. zwei buttons druecke, habe ich zwei nullen und 6 einsen
anliegen. dass heist ich will die binaere 2 an port1 ausgeben.
Das kann 1. der Compiler nicht und 2. der Controller nicht
1. weil der Compiler Kommentare ignoriert
2. weil der 8051 einen Pullup eingebaut hat und nur nach GND treiben
kann
Es könnte natürlich bei den vielen 8051 Derivaten durchaus auch eines
mit Richtingsregister geben. Das wäre aber ungeschickt...
BTW: Welche Pegel hast du tatsächlich am P0?
was du willst, ist klar. Was du konkret als Fehler beobachtest ist
unklar.
Also nochmal:
welches konkretes Bitmuster liegt an Port0 (mit Multimeter nachmessen)
welches konkrete Bitmuster wird an Port2 ausgegeben?
Dir ist auch klar, dass du B2 von Port 3 toggeln musst, damit was
passiert?
marten schrieb:> Wenn ich z.B. zwei buttons druecke, habe ich zwei nullen und 6 einsen> anliegen. dass heist ich will die binaere 2 an port1 ausgeben.
Wäre es dann nicht sinnvoll, die Nullen zu zählen?
Wozu das Rumgehampel mit dem P3?
Ich würde da einfach mal das hier vorschlagen:
marten schrieb:
Ich gebs auf
> while (1)> {>> if (P3.B2 == 0)> {> while (P3.B2 == 0)> val = P0;> result = count_ones(val);> P2 = result;> }> }> }
da hast du doch schon wieder Nebenbedingungen!
Was ist so schwer an
1
while(1)
2
{
3
val=P0;
4
result=count_ones(val);
5
P2=result;
6
}
und wenn DAS funktioniert, dann wird ausgebaut! Aber nicht vorher.
Ich meine das absolut und 100%-ig Ernst mit: so einfach wie nur
irgendwie möglich!
Im Grunde wäre ein
Hallo marten,
die Ports sind beim 89S8253 nach Reset automatisch auf 0xFF (Eingang),
sie nochmal damit zu überschreiben schadet aber nicht.
Ich weiß nicht welchen Compiler du verwendest, beim Keil werden die
Portbit nicht P3.B2, sondern P3_2 beeichnet (in AT89S8253.h festgelegt).
Habe dein Programm mal mit Keil ausprobiert. In der "if --- while"
Kombination frißt es sich fest. Ohne das "while" läuft es wie gewollt.
if (P3_2 == 0)
{// while (P3_2 == 0) ;ausklammern oder löschen
val = P0;
result = count_ones(val);
P2 = result;
oder:
P2 = count_ones(P0);
}
Ich hoffe es hilft dir weiter. Gruß. Tom
Nullen zeahlen aber wohl :).
Vielen viel dank fuer eure hilfe.
Ich habe glaube einen Denkfehler mit der umgekehrten logic...
unsigned char count_ones(unsigned char val)
{
unsigned char i;
for( i = 0; val; val <<= 1 )
if( val & 0x80 )
i++;
return i;
}
void main() { // Main program
P0 = 0xFF; // Set P0 as high impedance
input
P2 = 0xFF; // Set P2 as input
while (1)
{
P2 = (8 - count_ones( P0 ));
}
}
Das geht.
P0 high Pegel 3,1 V Taster nicht gedrueckt
P0 low Pegel 0,1 V Taster gedrueckt
P2 high Pegel 4,7 V Taster nicht gedrueckt
P2 low Pegel 0,1 V Taster gedrueckt
Hallo marten,
du hast weiter oben mal geschrieben "ich will die binaere 2 an port1
ausgeben". Dann mußt du P1 anstatt P2 schreiben:
P1 = count_ones( P0 );
Das 8 - ... brauchst du nicht, die Routine von Peter gibt direkt die
Anzahl der "1" zurück.
Gruß. Tom
TomA schrieb:> ausgeben". Dann mußt du P1 anstatt P2 schreiben:
Das P1 anstelle von P2 ist optional. Anscheinend hat er zwischendurch
seine Meinung geändert, an welchem Port ausgegeben werden soll.
> Das 8 - ... brauchst du nicht, die Routine von Peter gibt direkt die> Anzahl der "1" zurück.
Allerdings will er eigentlich die Anzahl an 0-en zählen. Denn er will
gedrückte Tasten feststellen und die liefern ihm eine 0 am Portpin.
Daher die Subtraktion von 8.