Hallo. Ich will ein Programm in C für einen PIC schreiben. In dem
Programm will ich eine Funktion haben, der an einem Ausgang (z.b.
PORTB.0) was macht. Jedoch will ich die Information, welcher Ausgang es
ist, als Parameter in die Funktion übergeben.
Hier mein Versuch, der jedoch nicht funktioniert hat (Funktionen sind
ziemlich sinnlos, Einstellungen sind auch getroffen, es geht mir hier
aber ums Prinzip):
1
voidioschalt(bitausgang){
2
ausgang=1;
3
}
4
5
voidmain(void){
6
bittestio@PORTB.0;
7
while(1){
8
ioschalt(&testio);//Adresse von testio übergeben
9
}
10
}
Wenn ich das mit cc5x compiliere, kommt eine Fehlermeldung beim Aufruf
der Funktion. Wenn ich oben statt "bit ausgang" "char ausgang" schreibe,
ist der Fehler weg, er erzeugt auch eine asm und hex, funktionieren tuts
dann aber auch nicht.
Hat jemand eine Idee, wie man sowas machen kann? Also quasi die
Adress-Information in eine Variable übergeben. Muss ich das mit dem *
statt dem & übergeben?
Hmmm ich glaube hier ist jeder nur sprachlos was das "Programming"
betrifft. Das ist doch nicht dein Ernst oder ?
Ich empfehle dir dringend dich mit C zu beschäftigen. Nimm zuerst
"normales" ANSI-C. Wenn du das dann beherrschst dann kannst du darüber
nachdenken, das ganze auf den PIC zu bringen.
Womit du dich gerade rumschlägst sind sog. Pointer.
http://www.hs-augsburg.de/~sandman/c_von_a_bis_z/c_014_000.htm
Wenn du die Pointer nicht behrrschst dann versuch ohne Pointer
auszukommen.
Leider muss ich dir mitteilen, dass du die Pointer nicht beherrschst.
Ist nicht böse oder persönlich gemeint aber du hast sie einfach noch
nicht verstanden.
Michael Skropski schrieb:> bit testio @ PORTB.0;
Auch wenn ich mit dem CC5X nochnie gearbeitet habe:
Ich muss dir sagen, dass das Programm absolut keinen Sinn ergibt. Selbst
wenn das compiliert gibt das NULL Sinn.
Michael Skropski schrieb:> void ioschalt(bit ausgang){> ausgang = 1;> }>> void main(void){> bit testio @ PORTB.0;> while(1){> ioschalt(&testio); //Adresse von testio übergeben> }> }
Du deklarierst eine Variable testio als Bit (1/0) bei PORTB0. Was willst
du damit bezwecken?
In der Endlosschleife übergibst du dann den Wert von testio (also den
Wert den PORTB0 bei der Deklaration hat an die Funktion ioschalt.
In der aufgerufenen Funktion weisst du dann der Variable ausgang den
Wert 1 zu.
Was soll da deiner Meinung nach passieren?
Ich sitze jetzt seit knapp 5 Minuten vor deinem Code und versuche mir zu
überlegen was du bezwecken willst. Wenn es das ist was ich denke dann
hast du von PIC und Programmieren so viel Ahnung wie ne Kuh vom Fliegen:
Du hast dir gedacht durch "ausgang = 1;" geht es nun zurück zu "bit
testio @ PORTB.0;" und damit wird PORTB = 1 ?
Ich gebe dir wirklich den Rat und schau dir C nochmal genau an:
Die Variable ausgang ist eine lokale Variable. D.h. sie existiert nur in
der Funktion ioschalt().
Wenn du ausgang = 1 setzt dann hat sie halt den Wert aber das
interessiert niemanden.
bit testio @ PORTB.0; wird nur einmal ausgeführt - das heißt nicht, dass
wenn du testio veränderst, dass dann PORTB auch den neuen Wert von
testio annimmt !
Bits sind auf PICs nicht einzeln frei und insbesondere indirekt
adressierbar, auch wenn der Compiler mit der nicht standardkonformen
@-Mimik eine Bitadressierung vortäuscht. Folglich muss man die Ports als
Ganzes ansprechen und mit deren Adresse hantieren. Dem fügt man dann
noch die Bitposition innerhalb des Ports hinzu, vorzusweise als
Bitmaske. Um dann klassische Bitoperationen auf ganze Bytes anzuwenden.
Das geht dann auch indirekt.
Also könnte sowas in der Art funktionieren:
Michael Skropski schrieb:> bit testio @ PORTB.0;
gewöhn dich daran, von solchen Spezialitäten Abschied zu nehmen
PORTB |= ( 1 << Bit );
setzt das Bit mit der Nummer Bit am Port
PORTB &= ~( 1 << Bit );
löscht das Bit mit der Nummer in Bit am Port
Was mich wundert ist zum Beispiel: Warum übergibtst du Parameter? Die
brauchst du doch garnicht für deine Funktion.
eines muss dir klar sein:
Unsere Funktion:
1
int schaltio( int ausgang ){
2
return(ausgang/2);
3
}
Ein Funktionsaufruf wie
[avrasm]schaltio(22);[avrasm]
bewirkt, dass die 22 an schaltio übergeben wird (one-way)
in der Funktion schaltio() nimmt die lokale Variable ausgang (die gibt's
nur in der Funktion schaltio()) den Wert 22 an.
Der Rückgabewert der Funktion schaltio() ist logischerweise 11 (=22/2)
Beachte, dass die Funktion mit "int schaltio()" beginnt und nicht mit
"void schaltio()".
Int bedeutet, dass ein Integer zurückgegeben wird - void bedeutet, dass
nichts zurückgegeben wird / werden kann.
Bitte fang mit C ganz von Vorne an - klau dir keinen Code und hoffe dass
das hier kein andere liest.
Es tut mir leid aber das ist das schlimmst was ich je in C gesehen habe.
Ich hab dir weiter oben einen Link gepostet (1. Antwort). Bring dir
damit C bei. Arbeite alles durch und fang dann an das auf PICs zu
machen. BITTE =)
Glaub mir wir haben alle so angefangen und es geht einfach nicht
anderst. Du hast keine Ahnung von C und versuchst C auf einen
Microcontroller zu bringen. Das ist in gewissen Maßen hoffnungslos. Du
willst ja keine Mist entwickeln sondern was gescheites und dir nicht
immer Code zusammenkopieren. Und glaube bitte nicht, dass du das auch so
verstehst und die Grundlagen nicht brauchst - jeder denkt so =) Du hast
uns das schon eindrucksvoll bewiesen.
Nichtsdesto trotz helfe ich dir gerne bei deinen PIC spezifischen
Themen.
Viel Spaß
AAllsoo.. Ich hab schon erfolgreich Programme mit C für PICs
geschrieben, die genauso funktioniert haben wie sie sollten. Und mit:
Michael Skropski schrieb:> Hier mein Versuch, der jedoch nicht funktioniert hat (Funktionen sind> ziemlich sinnlos, Einstellungen sind auch getroffen, es geht mir hier> aber ums Prinzip):
wollte ich verdeutlichen, dass mir Bewusst ist, dass die Funktion
absolut sinnlos ist, jedoch vom Prinzip her das ist, was ich suche. Ich
will eine 1-Wire-ähnliche Funktion zum senden schreiben. 1-Wire -> 1 Bit
als Ausgang. Die Information, welches Bit das ist, will ich zusammen mit
einem Byte in die Funktion übergeben. Aus diesem Grund kann ich aber
z.B. PORTB.0 nicht in die Funktion schreiben, denn dann kann ich das nur
für den PORTB.0 benutzen.
Es stimmt zwar, dass ich mit C quasi erst angefangen habe, jedoch hab
ich weder dabei noch vorher in ca 3-4 Jahren PHP einen Pointer
gebraucht. Daher weiß ich nicht, wie das geht.
Lehrmann Michael schrieb:> Michael Skropski schrieb:>> bit testio @ PORTB.0;>> Auch wenn ich mit dem CC5X nochnie gearbeitet habe:>> Ich muss dir sagen, dass das Programm absolut keinen Sinn ergibt. Selbst> wenn das compiliert gibt das NULL Sinn.
Laut einer Anleitung zu cc5x ist das eine Bit-zuweisung, sodass testio
representiv für PORTB.0 steht. Wenn man das allgemein nciht macht,
wusste ich das nicht, jedoch hat es bisher einwandtfrei funktioniert.
Lehrmann Michael schrieb:> Du deklarierst eine Variable testio als Bit (1/0) bei PORTB0. Was willst> du damit bezwecken?>> In der Endlosschleife übergibst du dann den Wert von testio (also den> Wert den PORTB0 bei der Deklaration hat an die Funktion ioschalt.
Ich hab verscuht, dass die in der Funktion deklarierte Variable ausgang
in diesem Fall PORTB.0 representiert. Quasi will ich, dass, wenn ich
ausgang setze, ansich testio und somit PORTB.0 gesetzt wird. Das geht
dann also anscheinend mit einem Pointer.
Wie gesagt wollte ich eine allgemeine Funktion schreiben, wo etwas mit
einem Ausgangsbit passiert (ob eine Datenübertragung oder simples
einschalten ist wie gesagt um das Prinzip zu verstehen egal), ich aber
beim Aufruf der Funktion bestimmen will, mit welchem Bit.
Michael Skropski schrieb:> Laut einer Anleitung zu cc5x ist das eine Bit-zuweisung, sodass testio> representiv für PORTB.0 steht. Wenn man das allgemein nciht macht,> wusste ich das nicht, jedoch hat es bisher einwandtfrei funktioniert.
Du musst dir bewusst sein, das das eine Erweiterung ist, die der
Compiler-Hersteller extra für diesen Compiler erfunden hat.
Und jetzt hast du auch gesehen, wo die Grenzen dieser Erweiterung
liegen. Mit der üblichen C-Standardlösung gibt es diese Grenzen nicht.
Auch wenn das ein wenig Verlust von Bequemlichkeit in der Tipparbeit
bedeutet.
Würde das denn gehen, wenn ich als Übergabe-Parameter PORTB.0 schreibe
oder liegt es allgemein am cc5x-Compiler. Wenn es am Compiler liegt,
würde es dann mit MikroC for PIC gehen? Hat mir ein Freund empfohlen und
ist wohl bis 2 kB kostenfrei.
Michael Skropski schrieb:> Ich hab verscuht, dass die in der Funktion deklarierte Variable ausgang> in diesem Fall PORTB.0 representiert. Quasi will ich, dass, wenn ich> ausgang setze, ansich testio und somit PORTB.0 gesetzt wird. Das geht> dann also anscheinend mit einem Pointer.
Tja das mit dem Pointer den du falsch verwenden hast ändert noch nichts
daran, dass es so nicht geht. PortB wird trotzdem immernoch nur
verändert wenn du das anordnest. Das tust du nur in der Deklaration.
Dass du schon erfolgreicher Programme geschrieben hast möchte ich in
Frage stellen ... Aber nichts für ungut. Lerne C einfach von Grund auf -
wie jeder es tun muss .
Lehrmann Michael schrieb:> Dass du schon erfolgreicher Programme geschrieben hast möchte ich in> Frage stellen
Dann tu das, weil du ja weißt, was ich alles gemacht hab. Da ich nicht
von ausgehe, dass noch sinnvolle Antworten kommen, seht diesen Thread
als Closed.
Trotzdem ein Danke an die, die mir wirklich Helfen wollten.
PS: Nobody is perfect. Habe schon gesehen, das hier wer im Forum gefragt
hat, wie man einen Spannungsteiler berechnet. Der wurde allerdings nicht
so angefahren, wie ich. Also keine Ahnung, was bei mir das Problem ist.
Naja. Werde mal wen anderes Fragen.
Michael Skropski schrieb:> Der wurde allerdings nicht> so angefahren, wie ich.
Dem wurde allerdings auch nicht 3 mal erklärt, dass er eine
Spezialsyntax seines Compilers benutzt, die so erst mal toll aussieht
aber ihre Schwächen hat.
> Also keine Ahnung, was bei mir das Problem ist.
Das Problem ist, kurz gesagt, dass die kleinste Einheit mit der in C
operiert wird, das Byte ist. In C gibt es nicht kleineres. Wenn du doch
ein Stilmittel dafür hast, dann ist das Compilerspezifisch und
verallgemeinert nicht.
Du kannst dich drehen und wenden wie du willst. Mit einem Mini-Cooper
kann man nun mal nicht vernünftig einen 5 Personen Haushalt von München
nach Hamburg übersiedeln. Egal wieviel du vorher schon gesiedelt bist.
Pfeif auf diese Spezialsyntax, benutze Standard C, so wie alle anderen
auch, und die bist im Rennen.
> Naja. Werde mal wen anderes Fragen.
Ah ja. Nach der Methode: Wenn mir die Diagnose nicht zusagt, geh ich
halt zu einem anderen Arzt.
Karl heinz Buchegger schrieb:> Dem wurde allerdings auch nicht 3 mal erklärt, dass er eine> Spezialsyntax seines Compilers benutzt, die so erst mal toll aussieht> aber ihre Schwächen hat.
war allerdings schon beim ersten oder zweiten Post, aber sei es drumm.
Karl heinz Buchegger schrieb:> Das Problem ist, kurz gesagt, dass die kleinste Einheit mit der in C> operiert wird, das Byte ist. In C gibt es nicht kleineres.
Das z.B. hab ich nicht gewusst, weil ich wie gesagt das Tutorial von
cc5x durchgemacht habe und es da den Datentyp Bit gibt.
Karl heinz Buchegger schrieb:> Ah ja. Nach der Methode: Wenn mir die Diagnose nicht zusagt, geh ich> halt zu einem anderen Arzt.
Ne, nach der Methode: Wenn mir hier keiner genau sagt, warum es nicht
geht oder wie es gehen kann, frag ich wen, der mir mehr sagt, als dass
ich nicht C programmieren kann..
Aber naja, die Antwort von dir hat jedenfalls meine Frage beantwortet,
also hat sich das hier jetzt erledigt.
Michael Skropski schrieb:> Ne, nach der Methode: Wenn mir hier keiner genau sagt, warum es nicht> geht oder wie es gehen kann, frag ich wen, der mir mehr sagt, als dass> ich nicht C programmieren kann..
Dann solltest du dich mal fragen, warum er dir das wohl gesagt hat
Bitpointer werden von C nicht unterstützt, war den C-Erfindern wohl zu
lächerlich.
Ich wüßte jetzt auch keine CPU, die Bitpointer unterstützt.
Man kann sich aber die Funktionen selber schreiben. Anbei mal für nen
8051.
Natürlich geht das auf Kosten der Geschwindigkeit, wenn man immer erst
ne Funktion aufruft, anstatt nur einen Befehl. Dein 1-Wire Timing kannst
Du damit vergessen.
1-Wire braucht ja auch keine mehrere Pins, man kann alle Device parallel
schalten.
Nur wenn die Leitungen zu lang werden, kann ein Aufteilen helfen. In dem
Fall legt man aber alle 1-Wire Busse auf einen Port und merkt sich nur
in einer Masken-Variable, welchen Bus man auswählt. Damit kann man bis
zu 8 Busse ansprechen (AND/OR) und es ist nur etwas langsamer als der
Bitbefehl.
Peter