Archiv verlassen und diese Seite im Standarddesign anzeigen : 4 Eingänge als BCD auswerten?
Hallo,
ich habe in meiner Schaltung die vier Eingänge PD5,PD6,PD7,PB0 mit einem BCD-Codierschalter belegt.
Dabei entspricht PD5 -> 1, PD6 -> 2, PD7 -> 4, PB0 -> 8
Nun habe ich mir folgende Funktion ausgedacht um dies auszuwerten und dann einfach im Hauptprogramm mit
if (BCD() == 1)...
abzufragen.
Wo liegt denn bei meiner Funktion mein Denkfehler? Denn wenn ich versuche die Rückgabewerte abzufragen dann passiert nichts, also muss irgendein Fehler in meinem Ansatz liegen.
Danke schon einmal für die Hilfe
int BCD(void)
/*
Diese Funktion werdtet die Stellung des BCD Schalters aus um im Programm eine
Umschaltung verschiedener Beleuchtungsmuster realisieren zu können
*/
{
if ( (!(PIND & (1<<PIND5))) & (!(PIND & (1<<PIND6))) & (!(PIND & (1<<PIND7))) & (!(PINB & (1<<PINB0))) )
{
return 0;
}
if ( (PIND & (1<<PIND5)) & (!(PIND & (1<<PIND6))) & (!(PIND & (1<<PIND7))) & (!(PINB & (1<<PINB0))) )
{
return 1;
}
if ( (!(PIND & (1<<PIND5))) & (PIND & (1<<PIND6)) & (!(PIND & (1<<PIND7))) & (!(PINB & (1<<PINB0))) )
{
return 2;
}
if ( (PIND & (1<<PIND5)) & (PIND & (1<<PIND6)) & (!(PIND & (1<<PIND7))) & (!(PINB & (1<<PINB0))) )
{
return 3;
}
if ( (!(PIND & (1<<PIND5))) & (!(PIND & (1<<PIND6))) & (PIND & (1<<PIND7)) & (!(PINB & (1<<PINB0))) )
{
return 4;
}
if ( (PIND & (1<<PIND5)) & (!(PIND & (1<<PIND6))) & (PIND & (1<<PIND7)) & (!(PINB & (1<<PINB0))) )
{
return 5;
}
if ( (!(PIND & (1<<PIND5))) & (PIND & (1<<PIND6)) & (PIND & (1<<PIND7)) & (!(PINB & (1<<PINB0))) )
{
return 6;
}
if ( (PIND & (1<<PIND5)) & (PIND & (1<<PIND6)) & (PIND & (1<<PIND7)) & (!(PINB & (1<<PINB0))) )
{
return 7;
}
if ( (!(PIND & (1<<PIND5))) & (!(PIND & (1<<PIND6))) & (!(PIND & (1<<PIND7))) & (PINB & (1<<PINB0)) )
{
return 8;
}
if ( (PIND & (1<<PIND5)) & (!(PIND & (1<<PIND6))) & (!(PIND & (1<<PIND7))) & (PINB & (1<<PINB0)) )
{
return 9;
}
return 0;
}
darwin.nuernberg
29.04.2007, 22:48
Erst mal Hardware:
Deine Pins am AVR sollten z.B. Pull-Up Widerstände haben, somit sind die schon mal HI.
Die Schalter legen dann den Pin jewiels auf Masse (Low).
Die beien Ports sind auf INPUT gesetzt?
So wie es jetzt mit C Programmierung aussieht (Sorry) amer allgemein:
Erst mal den Wert in Variablen übertragen (nicht die Port-Variablen verwenden)
Ich gehe mal davon aus dass die Schalter offen sind (Eingaänge also HI)
z.B. X und Y
Dann musst Du die beiden unterscheidlichen Ports in einer Variable vereinen
um ungewünschtes zu filtern erst mal mit AND
erst mal X = port_D and 11100000 REM (D7, D6, D5)
dann Y = port_B and 00000001 REM (B0)
jetzt schiebst Du X um 4- Bit nach rechts REM = 00001110
nun noch Y zu X verodern
X = X OR Y REM = 00001111
Nun hast Du den Wert in X stehen.
Wie das ganze in C zu scheiben ist kannst Du dann bestimmt umsetzen.
Hallo Darwin,
danke erst einmal für die Antwort.
Zur Hardware, meine Pins haben Pull-down Widerstände und sind selbstverständlich als Eingänge gesetzt.
Was ich jetzt nicht verstehe ist REM und wie ich die Bits schiebe. Wenn Du mir da noch einen Tip geben könntest würde mir das helfen.
darwin.nuernberg
29.04.2007, 23:18
OK dann sind deine Schalter Mit VCC (HI) verbunden und schalten dieses Durch (oder eben nicht).
REM heist REMARK uns ist ein Kommentar (und alles bis ans Zeilenende)
Und In C kenn ich mich nicht aus.
Such mal nach dem Befehl SHIFT oder wié das gemacht wird.
PD5 -> 1, PD6 -> 2, PD7 -> 4, PB0 -> 8
Ich habs mal in BASCOM realisiert (evtl. hilft es Dir):
$crystal = 8000000 ' Oszillator mit 8MHz
$baud = 19200 ' Seriell mit 19200, 8, N, 1, ohne Handshake
$regfile = "m32def.dat" ' Der benutzte Processor
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space
Dim X As Byte
Dim Y As Byte
Dim Result As Byte
Config Portd = Input
Config Portb = Input
Hauptprogramm: ' void Main(void)
Do
X = Portd And &B11100000 ' Port in Variable und Filtern
Y = Portb And &B00000001 ' Port in Variable und Filtern
Shift X , Right , 4 ' Bits 4x nach rechts schieben
Result = X Or Y ' Die beiden Veriablen vereinen
Loop
End
Klar könntest Du Dir auch eine Variable sparen, anstelle von Result könntest Du das Egebnis auch in X ablegen, das sieht dann so aus:
X = X Or Y ' Die beiden Veriablen vereinen
PS Die Demo von Bascom kostet nichts und gibt unter http://www.mcselec.com
Hallo,
Hoffentlich steigst Du noch durch in Deinem Programm :-#
PD5 -> 1, PD6 -> 2, PD7 -> 4, PB0 -> 8
zuerst Beide Ports in zwei Variablen einlesen
var1 = PIND;
var2 = PINB;
Jetzt die interessanten Pins holen
var1 &=((1<<PD5)|(1<<PD6)|(1<<PD7));
var 2 &=(1<<PB0);
Jetzt hast Du zwar Deine 4 Pins in den Variablen var1 und var 2 stehen, aber total durcheinander,
Die 3 unteren Bits kannst schon mal um 5 Stellen nach rechts Shiften, dann stehen sie schon mal richtig:
var1 >>=5;
Und da PB 0 für die Wertigkeit 8 steht,kann man die zwei Variablen nicht einfach verodern, sondern man muß schon eine if Abfrage starten:
if (var2)
var1 |=(1<<3);
Ungetestet, aber so müßte es klappen.
Gruß Sebastian
P.S.
REM ist/war eine Musikgruppe
darwin.nuernberg
30.04.2007, 07:19
Hallo,
Hoffentlich steigst Du noch durch in Deinem Programm :-#
P.S.
REM ist/war eine Musikgruppe
1. Wen/was meinst Du jetzt?
2. REM ist ein Schlafzustand! (Rapid Eye Movement)
Naja, ich meine eigentlich das Programm des Fragestellers,
sorry, hätte zitieren müssen.
Wenn ich solche Konstrukte sehe,
verstehe ich auch Leute, die meinen C wären Hieroglyphen
und allen Basic aufs Auge drücken möchten :wink:
@Henry,
nicht böse sein :-)
Gruß Sebastian
P.S. ich habe mir die Pinbelegung oben nochmal angeguckt, und habe kleine Änderung im Programm gemacht...
Hoffentlich steigst Du noch durch in Deinem Programm
@Henry,
nicht böse sein :-)
Hallo Sebastian,
ich find es auch etwas umständlich wie ich es gemacht habe und Übersichtlich ist es nicht ;)
Da ich C noch nicht so richtig kann und mich auch nur als (eines von vielen) Hobbys damit beschäftige, greife ich halt auf die Befehle die ich kenne zurück und bastel mir daraus meine gewünschte Funktion. Wie man sieht klappt das nicht immer :(
Aber hier habe ich ja ein Forum gefunden wo mir geholfen wird und so klappt das dann meistens und ich lern auch was dazu.
Eine Frage noch dazu. Das Ergebnis steht dann komplett in var1?
Werd schon mal etwas damit expirimentieren.
Danke
PS
Böse bin ich nicht, denn dein Ton war ja freundlich und Du hast ja auch einen Lösungsweg vorgeschlagen. (und deine Frage ist auch noch berechtigt :D )
Ich mag es nur nicht wenn jemand schreibt "Blöde Frage..." und selber aber nicht darauf antworden will. Wem was nicht passt an der Fragestellung, der braucht ja nicht drauf zu antworten. Man liest ja öfter so antworten wo blöde Sprüche kommen aber nicht auf die Frage eingegangen wird und das hilft natürlich niemandem.
Hallo Sebastian,
ich habe gerade mal deinen Lösungsweg in meine Schaltung geladen und es funktioniert auf jeden fall erst einmal in den ersten beiden Schalterstellungen. Ich denke es wird auch mit den anderen dann klappen.
Und als schöner nebenefekt ist das Programm auch noch um 2-3% kleiner geworden.
Danke euch beiden noch einmal für die Hilfe
Hallo Henry,
schön, daß es klappt, wie gesagt hab ich es nicht getestet und nochmals ändern müssen, ich dachte zuerst, daß PB0 für Bit 0 steht :-b
Und ja, das Ergebnis steht in var1.
Man könnte ganz ohne var 2 auskommen, und zwar anstatt
if (var2)
var1 |=(1<<3);
if (PINB & (1<<PB0))
var1 |=(1<<3);
schreiben.
damit hätte man noch ein paar Zeilen eingespart.
zum Testen und Probieren, versuche ich zuerst manche Sachen am PC, beim Linux ist gcc ja schon Onboard und für Windows gibt es auch gute Lösungen, wie Cygwin oder wenn man eine GUI haben muß devc++ oder Code::Blocks, das ist auf jedem Fall besser, als das Programm immer Flashen zu müssen, um zu schauen, ob es auch richtig klappt.
Gruß Sebastian
Hallo Sebastian,
Du schreibst bei Linux ist GCC dabei. Wie kann man den denn zum testen verwenden? Das ist doch der Compiler oder?
Ich werwende WinAVR und GCC unter Windows auch und wenn man damit auch testen kann wäre das super.
Hallo Henry,
Ob winavr auch den gcc (ohne avr) enthält kann ich Dir leider nicht sagen, meine Frau lässt mich nicht an ihren Win PC dran, aber falls das nicht gehen sollte gibt es noch andere Lösungen (sehe oben)
Ich teste meine Routinen in ganz normalen PC Programmen, das geht ganz gut, man muß aber ein paar Tricks benutzen, gerade habe ich Deine bcd Routine ausprobiert, und einen Fehler entdeckt ](*,)
und hier das PC- Programm:
#include <stdio.h>
#include <string.h>
int bcd (int portd,int portb){
int var1 = portd & ((1<<5)|(1<<6)|(1<<7));
var1 >>=5;
if (portb & (1<<0))
var1 |= (1<<3);
return var1;
}
int bit2char (char *string) {
int i,result=0;
for (i=strlen(string)-1;i>=0;i--) {
if (*string++ == '1')
result |=(1<<i);
}
return result;
}
int main (int argc,char *argv[]) {
int a,b;
if (argc < 3) {
printf("Du musst zwei Parameter übergeben\n");
return 1;
}
printf ("Ergebnis %d\n",bcd(bit2char(argv[1]),bit2char(argv[2])));
return 0;
}
Das Programm erwartet 2 Argumente in einer binären Form, die den Zustand Deiner Ports darstellen z.B. wenn alle Pins am Schalter auf high stehen <programname> 11100000 00000001
die bit2char Funktion wandelt nur die zwei Argumente aus char Arrays in int werte um, damit wird dann die bcd Funktion gefüttert und liefert den BCD Wert zurück, der ausgegeben wird...
Naja der Fehler lag bei
if (PINB & (1<<PB0))
var1 |=(1<<4);
es muß heißen
if (PINB & (1<<PB0))
var1 |=(1<<3);
Wohl ein Bit zu weit geschoben...
Und kompliziert ?
So lernt man C am einfachsten
Gruß Sebastian
P.S Ich habe das Programm oben nochmal geändert
Hallo Sebastian,
hast Recht, der Compiler heißt avr-gcc. Du testest Deine Programme also indem Du sie als PC-Programm compilierst und dann laufen lässt.
Danke für die Fehlerkorrektur, hätte ich erst gemerkt ween ich ab der achten Schalterstellung Probleme gehabt hätte.
Und kompliziert ?
Nö, wenn ich es so sehe dann macht das alles Sinn für mich. Ich werde zwar so schnell kein Programm aus dem Kopf zusammencoden können, aber mit meinen Aufzeichnungen als Hilfe wird der Wissensstand immer besser.
Ist nur immer etwas ungewohnt, da ich am PC (als weiteres Hobby) Programme in Delphi (also Pascall) schreibe.
Ist nur immer etwas ungewohnt, da ich am PC (als weiteres Hobby) Programme in Delphi (also Pascall) schreibe.
Naja, ich habe die Erfahrung gemacht, wenn man eine Sprache kann, kann man sich ziemlich schnell in eine andere reindenken.
Mit Pascal hatte ich bis jetzt nichts gemacht, ich fing auf C64 mit Basic an, dann auf Amiga mit C später PC C++, Java, PHP die sind fast alle gleich, bis auf die Objekt Orientierung, da bin ich etwas zu blöd dafür :mrgreen:
Mit der Bitschubserei muß Dir für die Zukunft nur merken
a = 1<<4 ergibt 00010000
das heißt man fängt bei 0 an
a = 1<<0 ergibt 0000001
wenn man aber die ganze Zahl schiebt fängt man bei 1 an
a = 1 ; //00000001
a <<=1; ergibt 00000010
usw.
deswegen
if (PINB & (1<<PB0))
var1 |=(1<<4);
hätte 000x0000 hier ben Bit gesetzt
naja, viel Spaß noch
Sebastian
Das war ein guter Hinweis. Ich denke das mit der schieberei habe ich jetzt denke ich begriffen. Kommt gleich in meine Sammlung nützlicher infos zur µC programmiererei ;)
Gute Nacht dann erst einmal und danke für die ausdauernde Hilfe. (Wir werden sicherlich noch einmal das Vergnügen haben hier im Forum ;) )
darwin.nuernberg
01.05.2007, 10:46
*** Fast (nicht ganz) OFFTOPIC ***
Naja, ich meine eigentlich das Programm des Fragestellers,
sorry, hätte zitieren müssen.
Wenn ich solche Konstrukte sehe,
verstehe ich auch Leute, die meinen C wären Hieroglyphen
und allen Basic aufs Auge drücken möchten :wink:
@Henry,
nicht böse sein :-)
SELBST ZENSIERT
Naja das Basic, als Programmiersprache ist nicht der alleinige Grund warukm ich mit BASCOM arbeite,
mit C wäre ich damals auch zufrieden gewesen,
wenn ich eine Anleitung gefunden hätte wie man das "Zeuch" richtig compiliert (damals zu viele unvollständige und z.T. widersprüchliche Anleitungen).
Jetzt ist es eben so, und ich bin zufrieden damit.
Ich will keinesfalls jemanden von Bascom überzeugen ***Jeohva, Jehova schrei***.
Hoffentlich entseht jetzt nich so ein Krieg wie mit Windows/Linux.*** Fast (nicht ganz) OFFTOPIC ENDE***
SELBST ZENSIERT
Hoffentlich entseht jetzt nich so ein Krieg wie mit Windows/Linux.
Das hoffe ich auch, aber ich verstehe nicht so ganz, warum Du hier in gcc Forum hausieren gehen muß, lass die Leute antun, jedem das seine :-)
Gegen Deine 6 Argumente hab ich nur das zu bieten (https://www.roboternetz.de/wissen/index.php/Codevergleich_AVR-Compiler)
Vielleicht kannst Du den Artikel ergänzen ?
Und bitte versuche das Ergebnis nicht schönzureden, Zitat
Remark: Das reine Register-rechnen (GCC) macht Bascom nicht. Er arbeitet immer im SRAM , brav mit Load & Store. (PicNick)
vor allem dieses brav hört sich so an, als ob es ein Vorteil wäre ;-)
Ach so, Deine Lösung hat immernoch einen Fehler :wink:
Gruß Sebastian
darwin.nuernberg
01.05.2007, 18:06
OOOPS,
Sorry...
habe garnich realsiert, dass das heir ein C-Forum ist,
Jetzt erst da Du es ansprichst.
Ich habe einfach auf die Frage hin gepostet und nicht auf das Forum geachet.
Ich war wo so voller Tatendrang...
Nochmal Entschuldigung
Ich wollte hier nicht Wildern.
ENTSCHULDIGUNG ENTSCHULDIGUNG ENTSCHULDIGUNG
Soll ich meine Beiträge wieder löschen?
Eigentlich OT, aber weil ich grad' vorbeikomme
vor allem dieses brav hört sich so an, als ob es ein Vorteil wäre
"Brav" sollte da nicht implizieren, daß C "schlimm" sei.
Ich wollte das Gespräch aber nicht unterbrechen
Hallo PicNick,
sorry, es war auch nicht gegen Dich gerichtet, ich find es gut, daß Du bei diesem Vergleich mitgemacht hast, mir ist es auch im Endeffekt egal, womit man seine Programme schreibt, nur objektiv soll man dabei bleiben und keinen Kreuzzug führen.
Für mich ist dieses Thema abgeschlossen.
Gruß Sebastian
Trotz alledem hat es mir bei meinem Problem geholfen und ich denke darauf kommt es an ;)
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.