Hi,
ich habe mehrere Eingangsplatinen die ich mit jeweils zwei
Schieberegister bestückt habe. Ich schiebe mit folgender Schleife meine
1en und 0en in das "Eingang[i]" Array.
Für eine andere Auswertung benötige ich jedoch die Bits im Byte, hierfür
habe ich ein ByteArray angelegt "StatusEingangKarte[j]" -> uint16_t
StatusEingangKarte[EPL_Anzahl];
In diesem ByteArray sollen jetzt von der ersten Karte die 16 bit
reingeschoben werden, wie mache ich das am besten?
Ich habe es so versucht, nur wie bekomme ich den nächsten "j" oder "k"
hin der mir eine neue Karte signalisiert?!?! Alle 16 muss "j" und "k"
erhöht werden?!?!
Habt ihr da eine Idee?
1
2
3
4
inti=0;
5
//Abfragen welches Registerbit gesetzt -> mit clock weiter schiebenEPL_Anzahl
6
for(i=(EPL_Anzahl*16)-1;i>=0;i--)
7
{
8
9
if(PINA&(1<<PINA0))
10
{// Logisch 0 wenn Schalter nicht gedrückt da Pullup an
Ich möchte mir den Rat erlauben, die Frage noch einmal, wesentlich
detaillierter und durchdachter zu formulieren, einen Schaltplan
anzuhängen und den Code zu dokumentieren. Vor allem auch genau zu
beschreiben, was das Ergebnis sein soll.
Es mag sein, das ich die Ausnahme bin, aber ich verstehe nämlich nur,
das Du Bits einlesen willst und prüfen welches gesetzt ist. An sich ist
das trivial, auch wenn ich akzeptiere das Du vielleicht an dieser Stelle
Schwierigkeiten hast. Wo aber da j und k in's Spiel kommen und warum das
eigentlich genau in Deinem Fall schwierig ist kann ich nicht erkennen.
OK, unten habe ich den Code auch kommentiert. Hoffe das hilft und ihr
könnt mir helfen.
Ich denke , dass ich irgendwie mit Modul arbeiten muss, das "j" von:
1
for(j=EPL_Anzahl;j>=0;j--)
2
{
3
StatusEingangKarte[j]&=~(1<<i);
4
}
muss meiner Meinung nach alle 16 mal "i"erhöht werden, also
i= 16
i= 32
i= 48
1
voidEingaenge_abfragen()
2
{
3
4
PORTC|=(1<<PC4);
5
6
// Mit PL alle Eingänge in das Register schieben.
7
8
// PL auf High
9
PORTC|=(1<<PC5);
10
// PL auf Low
11
PORTC&=~(1<<PC5);
12
// PL auf High
13
PORTC|=(1<<PC5);
14
15
inti=0;
16
//Abfragen welches Registerbit gesetzt -> mit clock weiter schiebenEPL_Anzahl
17
for(i=(EPL_Anzahl*16)-1;i>=0;i--)
18
{
19
20
if(PINA&(1<<PINA0))
21
{// Logisch 0 wenn Schalter nicht gedrückt da Pullup an
22
// Eingang[0-144] ist das Array, da stehen pro "i" nur 1 oder 0 drin.
23
// 144 da 9 Eingangskarten
24
Eingang[i]=0;
25
26
// jetzt brauche ein Byte z.B: StatusEingangKarte[0] das z.B so aussieht "0101010101010011" insgesamt 16 Bits
Na gut. War ja nur ein Rat. Musst Du ja nicht befolgen.Vielleicht kann
ja ein anderer was mit Deiner Frage anfangen. Viel Glück.
Und bevor Du jetzt antwortest: "Aber ich habe doch..."
nochmal dies:
>die Frage noch einmal, wesentlich
detaillierter und durchdachter zu formulieren, einen Schaltplan
anzuhängen [...]. Vor allem auch genau zu
beschreiben, was das Ergebnis sein soll.
Vom Grundkonzept wär's besser, wenn für 144 Bits nicht 144 Bytes in
Eingang[] verwendet werden, sondern eben nur tatsächlich 144 Bits in 18
Bytes. Dann liegt die Daten doch bereits in der gewünschten Form vor.
Ich versuche mal zu verstehen, was du willst:
- Daten von Schieberegister einlesen und in uint16_t-Variable speichern.
- nächstes Schieberegister auswählen
- das ganze von vorn
Da würde ich erstmal, wegen der Übersichtlichkeit, den Empfang in eine
eigene Funktion auslagern:
1
// 'Pseudocode'
2
uint16_tEmpfang()
3
// Es scheint mir so, als ob die Bits von allen Schieberegistern
4
// nacheinander über den selben Pin eingelesen werden (?)
5
// Ansonsten der Routine noch den Port und die Pinnummer der Daten
6
// (+evtl Clock) übergeben
7
{
8
uint16_tb=0;
9
10
for(uint8_ti=0;i<16;i++)
11
{
12
-hierTaktausgeben
13
14
b=b<<1;
15
if(PORT_DATA&(1<<PIN_DATA))
16
{
17
b|=1;
18
}
19
}
20
returnb;
21
};
Das Ergebnis kommt in das entsprechende 16-Bit-Element des Arrays mit (n
* Platinen) Einträgen.
Ja in etwa war das schon richtig was du meintest, die eigene Routine
habe ich ja schon.(void Eingaenge_abfragen ())
So sieht die Routine aus die die Eingänge abfragt und den Status des
Bits ein "Eingang[xx]" einträgt (s.unten)
Drück ich am 20ten Eingang den Taster wird Eingang[20] TRUE.
Das soll auch so bleiben, jetzt will ich es nur noch haben, dass in 16
Bits großen Bytes "StatusEingangKarte[xx]" in diesem Fall das
StatusEingangKarte[1] so aussieht: "0000 0000 0000 1000"
1
voidEingaenge_abfragen()
2
{
3
4
PORTC|=(1<<PC4);
5
6
// Mit PL alle Eingänge in das Register schieben.
7
8
// PL auf High
9
PORTC|=(1<<PC5);
10
// PL auf Low
11
PORTC&=~(1<<PC5);
12
// PL auf High
13
PORTC|=(1<<PC5);
14
15
inti=0;
16
//Abfragen welches Registerbit gesetzt -> mit clock weiter schiebenEPL_Anzahl
Kannst Du die Schieberegister mit SPI auslesen? Mit dem 74HC165 geht das
z.B. prima. Dann kannst Du direkt mit ganzen Bytes hantieren und es
wird viel einfacher und übersichtlicher?
@ Alex (Gast)
>So sieht die Routine aus die die Eingänge abfragt und den Status des>Bits ein "Eingang[xx]" einträgt (s.unten)
Hmmm.
>Drück ich am 20ten Eingang den Taster wird Eingang[20] TRUE.
Specherverschwendung.
>Das soll auch so bleiben, jetzt will ich es nur noch haben, dass in 16>Bits großen Bytes
Ein Byte hat immer 8 Bit, nicht mehr nicht weniger. Ein Wort ist nicht
streng definiert, oft sind es aber 2 Bytes.
> "StatusEingangKarte[xx]" in diesem Fall das>StatusEingangKarte[1] so aussieht: "0000 0000 0000 1000"
Mach, was schon mehrere Leute vorgeschlagen haben. Lies die Bits
systematisch ein und pack sie in ein Byte. Das kann man mehrfach
wiederholden und hat ein Array. Siehe Bitmanipulation und
AVR-Tutorial: Schieberegister.
Die Ratestunde ist eröffnet:
Welche Schieberegister? 165, 597, ?
Welcher Controller? SPI, USI
Was wird eingelesen? Wie schnell?
Was soll das Ganze?
Schaltplan?
mfg.