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
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.
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 ?
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:
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
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
...
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:
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 ;-)
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 !