Hallo Leute, nachfolgend ein beispiel zur erklärung: Eine Funktion wird aufgerufen und eine Nummer übergeben (die Nummer gibt an welcher Port bzw. Bit abgefragt werden soll) in MAIN: value = receiver(1) ; in FUNKTION: unsigned int receiver (unsigned char Target) { unsigned int Objective[17]; . . . while(1) { Objective[1] = PORTCbits.RC1; Objective[2] = PORTCbits.RC2; . . . usw. if (Objective[Target] == 1) { ... } . . . return ... } } Heist also ich möchte abhängig vom Übergabeparameter an Receiver einen anderen Pin abfragen (Objective[Target]), jedoch direkt auf den Wert zugreifen über einen Pointer auf den Port. Ich nutze den PIC18F65K80, leider sind die Ports nicht Bit-addressierbar und es funktioniert evtl. nur über ein Makro, doch ich finde nicht wirklich hilfreiche Schnipsel. Also wenn sich da jemand auskennt wäre eine kleine Hilfe wirklich super :-)! PS: So wie es oben steht funktioniert es eigentlich, wenn es jedoch wie bei mir bis zu 16 Pins sind und ich nur einmal in der while Schleife die Abfrage mache, dann stimmen die Werte nicht mehr. MFG Flo
Poste vllt. mal den ganzen Code*, ich verstehe nicht ganz was du vorhast. * Mit Formatierung:
1 | [c]C-Code[/c] |
Flo schrieb: > jedoch direkt auf den Wert > zugreifen über einen Pointer auf den Port. Könntest du deinen Code bitte kommentieren? Objective ist doch eine lokale Variable der Funktion receiver. Darauf kannst du doch garnicht in main zugreifen.
:
Bearbeitet durch User
Flo schrieb: > PS: So wie es oben steht funktioniert es eigentlich, wenn es jedoch wie > bei mir bis zu 16 Pins sind und ich nur einmal in der while Schleife die > Abfrage mache, dann stimmen die Werte nicht mehr. Dann mach die Abfrage doch in der Funktion...
Hallo danke für die Antwort, sorry aber der ganze Code ist viel zu kompliziert und aufgeblasen, im grunde geht es darum: 1. Wert zb. 2 wird in Main an die Funktion Receiver übergeben. 2. Der übergebene wert ist in der Receiver Funktion das hier z.B. zweite Element eines Arrays. Dieses Array beinhaltet Portzuweisungen also z.B.: Objective[2] = PORTCbits.RC2; 3. Jetzt ist es so das über diesen Port ein Code eingelesen wird also mehrere High und Low Flanken, diese Werte werden dann in einem Array gebuffert und umcodiert etc. 4. Die Abfrage sieht dann so aus: if (Objective[Target] == 1 && flag = 0) {...} if (Objective[Target] == 0 && flag = 1) {...} wobei Target der übergebene Wert (2) ist und hierbei der RC2 pin abgefragt werden soll. Nun will ich aber bis zu 16 verschiedene Pins abfragen und würde ich es nach diesem Stil machen also in der while schleife zu schreiben: // Objective[1] = PORTCbits.RC1; // Objective[2] = PORTCbits.RC2; // Objective[3] = PORTCbits.RC3; // Objective[4] = PORTFbits.RF6; // Objective[5] = PORTFbits.RF7; // Objective[6] = PORTDbits.RD0; // Objective[7] = PORTDbits.RD1; // Objective[8] = PORTDbits.RD2; // Objective[9] = PORTDbits.RD3; // Objective[10] = PORTEbits.RE6; // Objective[11] = PORTEbits.RE7; // Objective[12] = PORTCbits.RC4; // Objective[13] = PORTCbits.RC5; // Objective[14] = PORTCbits.RC6; // Objective[15] = PORTCbits.RC7; // Objective[16] = PORTDbits.RD5; ... würde er bei jedem durchlauf erst mal alle Ports abfragen obwohl ich eigentlich aktuell nur den einen Wert also (2) möchte. Das führt zu Zeitverzögerungen und verursacht Fehler. Deshalb möchte ich: vorher einen pointer deklarieren der immer auf den Wert bzw. Adresse des aktuell gesuchten Elements zeigt und diesen dann in der if abfrage und in der while schleife verwenden. also: int receiver (unsigned char Target) { unsigned char Objective[17]; Objective[1] = PORTCbits.RC1; // Zuweisung der Elemente Objective[2] = PORTCbits.RC2; Objective[3] = PORTCbits.RC3; Objective[4] = PORTFbits.RF6; ... unsigned char *pTR; // Erstellen eines Pointers pTR = &Objective[Target]; // Auf adresse von gew. Wert while(1) { if(*ptr == 1 && flag == 0) // Aktuellen Wert holen und prüfen { ... } if(*ptr == 0 && flag == 1) { ... } return irgendwas; } Dies ist aber mit dem PIC nicht möglich da dieser nicht Bit Adressierbar ist, daher suche ich nach einer ähnlichen Alternative die mir diese Funktionalität ermöglicht! MFG FLO PS: Ich hoffe da blickt noch wer durch :D
Müsste man dann nicht eher die Adresse des Ports in die Variable schreiben? Also ungefähr so: Objective[1] = &PORTCbits.RC1; // Zuweisung der Elemente Objective[2] = &PORTCbits.RC2; Objective[3] = &PORTCbits.RC3; Objective[4] = &PORTFbits.RF6; ... Und dann halt ganz normal dereferenzieren: if ( *Objective[1] == 1 && flag == 0) ... und du müsstest theoretisch den aktuellen Wert des Portbits erhalten. Theoretisch.
Also ich weiss nicht ob ich Dein Problem richtig verstanden habe und ich kenne auch den PIC C Compiler nicht. Aber diese ganzen PortDbits.yxz scheinen Mitglieder einer struct zu sein. Muss ja in einer Headerdatei deklariert sein. Vlt hilfts die struct zurückzugeben und daraus den gewünschten Pin zu lesen. Aber gut möglich das ich das Problem nicht sehe, dann vergiss einfach meine Antwort.
Flo schrieb: > PS: Ich hoffe da blickt noch wer durch :D Nö ;-) Warum willst du denn alle zuweisen, wenn dich nur eins interessiert ? Was soll eigentlich die while(1) Schleife in einer Funktion ?
Volker SchK schrieb: > Was soll eigentlich die while(1) Schleife in einer Funktion ? Hehehe, das ist mir noch garnicht aufgefallen.
Ich denke, das einfachste wird sein wenn du dir eine Funktion getInput oder ähnliches schreibst:
1 | uint8_t getInput(uint8_t pin_number) |
2 | {
|
3 | switch(pin_number) |
4 | {
|
5 | case 1: return PORTCbits.RC1; |
6 | case 2: return PORTCbits.RC2; |
7 | case 3: return PORTCbits.RC3; |
8 | case 4: return PORTFbits.RF6; |
9 | case 5: return PORTFbits.RF7; |
10 | case 6: return PORTDbits.RD0; |
11 | case 7: return PORTDbits.RD1; |
12 | case 8: return PORTDbits.RD2; |
13 | case 9: return PORTDbits.RD3; |
14 | case 10: return PORTEbits.RE6; |
15 | case 11: return PORTEbits.RE7; |
16 | case 12: return PORTCbits.RC4; |
17 | case 13: return PORTCbits.RC5; |
18 | case 14: return PORTCbits.RC6; |
19 | case 15: return PORTCbits.RC7; |
20 | case 16: return PORTDbits.RD5; |
21 | default: return 0; |
22 | }
|
23 | }
|
:
Bearbeitet durch User
Gute Idee!
Wenn man sich den Funktionsaufruf bei jeder Abfrage sparen will, falls es so viele sind dass sie bei der Laufzeit ins Gewicht fallen, könnte man die getInput() auch inlinen lassen oder man versucht es so:
1 | // Untested
|
2 | #define INPUT_PIN (*port_ptr & bitmask)
|
3 | |
4 | volatile uint8_t *port_ptr = NULL |
5 | uint8_t bitmask = 0; |
6 | switch(Target) |
7 | {
|
8 | case 1: port_ptr = &PORTC; bitmask = 1 << 1; |
9 | case 2: port_ptr = &PORTC; bitmask = 1 << 2; |
10 | case 3: port_ptr = &PORTC; bitmask = 1 << 3; |
11 | case 4: port_ptr = &PORTF; bitmask = 1 << 6; |
12 | case 5: port_ptr = &PORTF; bitmask = 1 << 7; |
13 | case 6: port_ptr = &PORTD; bitmask = 1 << 0; |
14 | case 7: port_ptr = &PORTD; bitmask = 1 << 1; |
15 | case 8: port_ptr = &PORTD; bitmask = 1 << 2; |
16 | case 9: port_ptr = &PORTD; bitmask = 1 << 3; |
17 | case 10: port_ptr = &PORTE; bitmask = 1 << 6; |
18 | case 11: port_ptr = &PORTE; bitmask = 1 << 7; |
19 | case 12: port_ptr = &PORTC; bitmask = 1 << 4; |
20 | case 13: port_ptr = &PORTC; bitmask = 1 << 5; |
21 | case 14: port_ptr = &PORTC; bitmask = 1 << 6; |
22 | case 15: port_ptr = &PORTC; bitmask = 1 << 7; |
23 | case 16: port_ptr = &PORTD; bitmask = 1 << 5; |
24 | }
|
25 | if(port_ptr == NULL) |
26 | return; |
27 | |
28 | //...
|
29 | |
30 | // Abfrage dann mit
|
31 | if(INPUT_PIN) |
32 | //...
|
:
Bearbeitet durch User
Hey Leute, vielen Dank für die Antworten! Ich werde einige eurer Vorschläge ausprobieren! Die while schleife in der Funktion kommt daher, das die Funktion selbst auch cases enthält (switch(state)...) und auch auf andere Funktionen noch zurückgreift. Ums mal zu verdeutlichen: Mein µC bekommt von 16 anderen µC Werte via Manchester Code auf GPIO rein. Nun frage ich jeden Pin nacheinander ab und beginne die Decodierung, an meine Mainfunktion gebe ich den Wert als Integer zurück. In meiner Main wird die Funktion in einer For-Schleife aufgerufen also so: for (int i = 1; i < 17; i++) { ReceiveBuffer[i] = Receiver(i); } Demnach werden die decodierten Werte als Integer im ReceiveBuffer mit dem jeweiligen Index gespeichert. Daher kommt das ganze mit den vielen Eingängen usw. Natürlich könnte ich auch einen Multiplexer 16:1 davorschalten und das ganze über einen Pin machen, so werde ich es wenn es wirklich nicht anders funktioniert auch machen, jedoch war das Ziel hierbei so kostengünstig wie möglich ohne weitere benötigten Bauteile zu realisieren. Aber mal sehen was wird. Auf jeden: Vielen Dank schon mal ich mach aber demnächst Feierabend und werde eure Vorschläge morgen ausprobieren! LG Flo
Ich fand deinen ersten Vorschlag eh besser aber hier fehlen breaks ;-)
Volker SchK schrieb: > Ich fand deinen ersten Vorschlag eh besser aber hier fehlen breaks > ;-) Stimmt, hab ich ganz übersehen. Dann halt so:
1 | // Untested
|
2 | #define INPUT_PIN (*port_ptr & bitmask)
|
3 | |
4 | volatile uint8_t *port_ptr = NULL |
5 | uint8_t bitmask = 0; |
6 | switch(Target) |
7 | {
|
8 | case 1: port_ptr = &PORTC; bitmask = 1 << 1; break; |
9 | case 2: port_ptr = &PORTC; bitmask = 1 << 2; break; |
10 | case 3: port_ptr = &PORTC; bitmask = 1 << 3; break; |
11 | case 4: port_ptr = &PORTF; bitmask = 1 << 6; break; |
12 | case 5: port_ptr = &PORTF; bitmask = 1 << 7; break; |
13 | case 6: port_ptr = &PORTD; bitmask = 1 << 0; break; |
14 | case 7: port_ptr = &PORTD; bitmask = 1 << 1; break; |
15 | case 8: port_ptr = &PORTD; bitmask = 1 << 2; break; |
16 | case 9: port_ptr = &PORTD; bitmask = 1 << 3; break; |
17 | case 10: port_ptr = &PORTE; bitmask = 1 << 6; break; |
18 | case 11: port_ptr = &PORTE; bitmask = 1 << 7; break; |
19 | case 12: port_ptr = &PORTC; bitmask = 1 << 4; break; |
20 | case 13: port_ptr = &PORTC; bitmask = 1 << 5; break; |
21 | case 14: port_ptr = &PORTC; bitmask = 1 << 6; break; |
22 | case 15: port_ptr = &PORTC; bitmask = 1 << 7; break; |
23 | case 16: port_ptr = &PORTD; bitmask = 1 << 5; |
24 | }
|
:
Bearbeitet durch User
Flo schrieb: > Ums mal zu verdeutlichen: > > Mein µC bekommt von 16 anderen µC Werte via Manchester Code auf GPIO > rein. Nun frage ich jeden Pin nacheinander ab und beginne die > Decodierung, an meine Mainfunktion gebe ich den Wert als Integer zurück. > In meiner Main wird die Funktion in einer For-Schleife aufgerufen also > so: > > for (int i = 1; i < 17; i++) > { > ReceiveBuffer[i] = Receiver(i); > } Warum speicherst du nicht einfach die PortsC..F in ReceiveC..F ? Die Dekodierung kannst du dann doch genauso machen ...
Hallo Volker, ich kann deinem Vorschlag nicht ganz folgen, meinst du den Kompletten Port in jeweilige Buffer einlesen und diesen Buffer dann ausmisten? Ich machs halt momentan so und es funktioniert auch wenn ich einzelne mache nur eben bei den vielen verzögert es sich: 1. Warte auf eine Reihe Nullen -> Statewechsel 2. Warte auf steigende Flanke -> Timer ein Statewechsel 3. Warte auf fallende Flanke -> Timer aus -> Wert = Synchronisationszeit -> Statewechsel 4. Warte auf eine Reihe Nullen -> Statewechsel 5. Warte auf steigende Flanke -> Timer ein 6. Warte auf fallende Flanke -> Timer aus wenn Zeit um einiges größer als erste Zeit dann dementsprechend eine 0 u. 1 ins Array oder eben 1 u. 0. andernfalls wenn Zeit ungefähr gleich dann eben 1 oder 0 ins Array. 7. Wenn Message dann Fertig ist 8Bit ID + 10Bit daten wird das Array an eine Funktion übergeben die ID wegschneidet die Bits richtig hindreht und mir daraus den Binärwert in ein Integer schreibt --> return VALUE
Flo schrieb: > Hallo Volker, > > ich kann deinem Vorschlag nicht ganz folgen, meinst du den Kompletten > Port in jeweilige Buffer einlesen und diesen Buffer dann ausmisten? Warum ausmisten, lass es einfach stehen bis zum nächsten mal. Bei der Dekodierung greifst du einfach auf die jeweiligen Bits zu. Von mir aus wieder über ein #define uCNr1_in ReceiveC & 0x02 oder du definierst dir deine eigenen Bitfelder genau wie im PIC Header ...
1 | union whatever |
2 | {
|
3 | struct
|
4 | {
|
5 | unsigned char PC; |
6 | unsigned char PD; |
7 | unsigned char PE; |
8 | unsigned char PF; |
9 | };
|
10 | struct
|
11 | {
|
12 | unsigned C0 :1; |
13 | unsigned O_01 :1; //C1 |
14 | unsigned O_02 :1; //C2 |
15 | unsigned O_03 :1; //C3 |
16 | unsigned O_12 :1; //C4 |
17 | ...
|
18 | unsigned O_04 :1; //F6 |
19 | unsigned O_05 :1; //F7 |
20 | };
|
21 | };
|
22 | |
23 | ...
|
24 | |
25 | union whatever newIn, flags; |
26 | |
27 | ...
|
28 | |
29 | newIn.PC = PORTC; |
30 | newIn.PD = PORTD; |
31 | newIn.PE = PORTE; |
32 | newIn.PF = PORTF; |
33 | |
34 | ...
|
35 | |
36 | if(newIn.O_01 == flags.O_01){ |
37 | ...
|
Am einfachsten ist es, wenn Du die 16 Eingänge auf 2 Ports legst und die dann als 16Bit einliest. Dann brauchst Du nur noch eine Maske drüberlegen, um den gewünschten Pin auszuwerten:
1 | uint16_t read_pin( uint16_t mask ) // mask: 0x0001, 0x0002, 0x0004, ... 0x8000 |
2 | {
|
3 | uint16_t val = (PORTE<<8) | PORTF; |
4 | return val & mask; |
5 | }
|
Flo schrieb: > Mein µC bekommt von 16 anderen µC Werte via Manchester Code auf GPIO > rein. Das ist natürlich die denkbar ungeeignetste Methode, mehrere MCs zu vernetzen. Für sowas ist I2C oder CAN gedacht.
Hallo Leute, weiterhin dickes Dankeschön für eure Bemühungen. Leider hatte ich heute Vormittag einige Meetings und Telefonate und konnte deshalb noch nicht wirklich weiter machen. Ich hoffe ich finde Nachmittag noch Zeit an diesem MEETwoch! Dann versuche ich mal einige Methoden! Mfg Flo
Peter Dannegger schrieb: > Das ist natürlich die denkbar ungeeignetste Methode, mehrere MCs zu > vernetzen. > Für sowas ist I2C oder CAN gedacht. Ich weiß, jedoch kommt das nicht von mir und die 16microcontroller sind kleine 8-Füßler die nichts können ausser adc wert messen und über gpio als manchester ausgeben. Soll natürlich nahezu nichts kosten und deshalb der ganze aufwand, ein schöner Bus waere da natürlich was feines! Mfg Flo PS: Habs heute nicht mehr geschafft, wies halt so oft ist man nimmt sich was vor und kommt zu gar nichts, aber morgen ;-)
Aber selbst so ein kleiner 8-Füßer müsste doch eine serielle Datenübertragung gebacken bekommen. Im "schlimmsten" Fall halt bitbanged.
:
Bearbeitet durch User
Hallo Leute, nach einem Kaffee und einem Whiteboard voll mit Code habe ich die Lösung gefunden. Und zwar wie folgt: Im DEFINITIONS.H Header: typedef struct { unsigned char *port; unsigned char mask; }pin_pointer; const pin_pointer pins[4] = { &PORTC, 1 << 0, // PORTC pin 0 RC0 &PORTC, 1 << 1, // PORTC pin 1 RC1 &PORTC, 1 << 2, // PORTC pin 2 RC2 &PORTC, 1 << 3, // PORTC pin 3 RC3 ... etc... }; Anschließend die Port/Pin Abfrage in der FUNKTION: if(!((*pins[Target].port)&(pins[Target].mask))) { jetzt liegt eine 0 am gewünschten über Target definierten Pin an } ... if(((*pins[Target].port)&(pins[Target].mask))) { jetzt liegt eine 1 am gewünschten über Target definierten Pin an } So funktioniert es und er frägt immer nur den jeweilig gewünschten Port ab :-) ohne große Zeitverzögerung! Vielen Dank für die Denkanstöße und bereigtestellten Codeschnipsel!!! MFG Flo PS: Ja ich weiß aber dieser Weg wurde von Person "X" bestimt und von Person "Y" ausgeführt und "ich" also Person "Z" muss die Suppe auslöffeln :-D !
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.