Bitweiser Zugriff

Bitweiser indizierter Zugriff auf indiziertes Array

  • 1
  • 2
  • Page 1 of 2
grech
Benutzer
Avatar
Gender:
Location: Saarland
Age: 67
Posts: 15
Registered: 10 / 2015
Subject:

Bitweiser Zugriff

 · 
Posted: 30.04.2019 - 17:46  ·  #1
Hallo zusammen,
ich bin zwar neu bei AVRCO, programmiere aber schon einige Jahre in Pascal/Delphi...
Neuerdings mache ich was mit Microcontrollern (XMega u.s.),

Dabei habe ich eine Problem:
Ich möchte Taster einlesen( 8 * 128 ) und
möchte Leds (8 * 128) über Schieberegister ein- und ausschalten.
Die Ein- und Ausgabe funktionieren schön. Dabei verwende ich Port A in ganzer Breite zum einlesen
der Taster und Port B zum ansteuern der LED.
An jedem Ausgang der Ports hängen dann bis zu 16 Schieberegister (LS595 bzw LS165).
Das ergibt zusammen also etwa ziemlich genau 1024 bit.
Damit ich mit den Daten (Taster) geschickter hantieren kann,
muss ich zu Beginn meiner Manipulationen etwas umsortieren.
Da fangen mit AVRCO die Probleme an. (oder ich nicht weiß wie es geht)
Ich finde keine elegante Möglichkeit der bitweisen Bearbeitung der Tasten/LED-Daten

Bisher hatte ich das ganze in BASCOM-AVR gelöst.
Wenn man aber mal mit Pascal gearbeitet hat will man sich ja nicht mit Basic ärgern.
Aber da gibt's eine elegante Möglichkeit.

Da gibt's Formulierungen wie:
LEDDAT[Index].pinnr := 1 or 0;
oder
LEDDAT[Index].pinnr := LEDDAT[Index+1].pinnr+1;

Hat jemand eine Idee wie solche Zuweisungen in AVRCO geschickt formuliert werden können?
Bisher helfe ich mir mit einer Procedure die aber bestimmt einiges an Zeit und Speicher frisst.

procedure setb( var abyte: byte; aBit : byte; value : boolean);
var m : byte;
begin
if value then
m := %00000001;
if abit > 0 then
m := m rol abit;
endif;
abyte := abyte or m;
else
m := %11111110;
if abit > 0 then
m := m rol abit;
endif;
abyte := abyte and m;
endif;
end;


eine ähnliche Prozedur gibt es dann auch noch für Word.
Wenn jemand eine geschickten Ansatz für dieses Problem könnte er mir sehr helfen.

Gruß grech
Merlin
Administrator
Avatar
Gender:
Age: 24
Posts: 1409
Registered: 03 / 2005
Subject:

Re: Bitweiser Zugriff

 · 
Posted: 30.04.2019 - 18:07  ·  #2
for
Code
LEDDAT [Index] .pinnr: = 1 or 0; 


use

Code
SetBit(LEDDAT [Index], pinnr,  1{ or 0}); 


That is equivalent to your function.
grech
Benutzer
Avatar
Gender:
Location: Saarland
Age: 67
Posts: 15
Registered: 10 / 2015
Subject:

Re: Bitweiser Zugriff

 · 
Posted: 30.04.2019 - 18:23  ·  #3
OK,
Ich bin zwar sicher, dass ich das ausprobiert hatte und einen Compiler-Fehler bekam.
Aber es funzt.
Und auch die Variante
SetBit(LEDDAT [Index], pinnr, Bit(LEDDAT [Index+1], pinnr-1) );
wird ohne Fehler übersetzt.
Ich nehme an, dass das Programm dann auch das richtige tut.
Muss noch probieren wie es mit WORD aussieht.

Vielen Dank
Grech
Merlin
Administrator
Avatar
Gender:
Age: 24
Posts: 1409
Registered: 03 / 2005
Subject:

Re: Bitweiser Zugriff

 · 
Posted: 30.04.2019 - 18:32  ·  #4
It does indeed do the right thing. AVRCo is very strong on bit manipulation.
grech
Benutzer
Avatar
Gender:
Location: Saarland
Age: 67
Posts: 15
Registered: 10 / 2015
Subject:

Re: Bitweiser Zugriff

 · 
Posted: 30.04.2019 - 21:39  ·  #5
Das nächste Problem:
ich möchte auf bestimmte bits mit einem Namen zugreifen.
z.B. auf die Tasten eines num. Tastenfeldes. (Num-Pad)
Diese möchte ich als bit deklarieren.
Geht leider nicht!

//=====================================================
const
anz_reg_io : byte = 128;

var
Reg_tasten, //Einlesen über port B
Reg_tasten_old, //zum Vergleich mit aktuellen t:ten
Reg_filter : array[1..anz_Reg_IO] of Byte; //Filter über IO//S

Const
Num16 : byte = 7;

F16_start : Byte = 1;
Adr_s16_7 : Byte = F16_start + 2;
Adr_s16_8 : Byte = F16_start + 1;
Adr_s16_9 : Byte = F16_start + 0;
Adr_s16_s : Byte = F16_start + 15;
Adr_s16_4 : Byte = F16_start + 14;
Adr_s16_5 : Byte = F16_start + 13;
Adr_s16_6 : Byte = F16_start + 12;
Adr_s16_1 : Byte = F16_start + 10;
Adr_s16_2 : Byte = F16_start + 9;
Adr_s16_3 : Byte = F16_start + 8;

var
Num_0[@Reg_tasten[adr_s16_0],num16] : bit;
Num_1[@Reg_tasten[adr_s16_1],num16] : bit;
Num_2[@Reg_tasten[adr_s16_2],num16] : bit;
Num_3[@Reg_tasten[adr_s16_3],num16] : bit;
Num_4[@Reg_tasten[adr_s16_4],num16] : bit;
Num_5[@Reg_tasten[adr_s16_5],num16] : bit;
Num_6[@Reg_tasten[adr_s16_6],num16] : bit;
Num_7[@Reg_tasten[adr_s16_7],num16] : bit;
Num_8[@Reg_tasten[adr_s16_8],num16] : bit;
Num_9[@Reg_tasten[adr_s16_9],num16] : bit;
//===================================================

Könnte aber gehen weil,
Typ der Variable und Adresse schon zur Compilezeit bekannt sind;

Gruß grech
pvs-deck
PowerUser
Avatar
Gender:
Age: 53
Homepage: pvs-deck.de
Posts: 1341
Registered: 02 / 2009
Subject:

Re: Bitweiser Zugriff

 · 
Posted: 30.04.2019 - 22:57  ·  #6
Quote by grech

Das nächste Problem:
....
Könnte aber gehen weil,
Typ der Variable und Adresse schon zur Compilezeit bekannt sind;

Gruß grech


Hallo grech,

hmm...
ich bin mir da nicht ganz sicher ob es so mit einem ARRAY funktioniert.
Evtl. musst Du über eine Schleife "for" das zu prüfende Byte in das definierte Byte übertragen.
Bei Deinem Aufbau könnte der Compiler Probleme haben.

in etwa so (ungetestet)

...
Code
VAR
 bBuffer : Byte;
 Flag1[@bBuffer,num16]  : bit;

procedure CheckByte; var
var
 xi : byte;
 
begin
   for xi:= 1 to anz_Reg_IO do
     bBuffer:= Reg_filter[ xi ]; 
   
   // Hier kannst Du dann Flag1 prüfen und was tun....     

   endfor;
end CheckByte;


Ist einer der möglichen Lösungswege, da ich aber nicht genau weiß was Du mit diesem Construct vor hast, ist es schwer was passendes raus zu suchen.

Thorsten
Merlin
Administrator
Avatar
Gender:
Age: 24
Posts: 1409
Registered: 03 / 2005
Subject:

Re: Bitweiser Zugriff

 · 
Posted: 01.05.2019 - 10:31  ·  #7
You can't do it in a single go - the dereferencing is too complex for the compiler, but you can do it in 2 stages, like this (I omitted 0 because adr_s16_0 is missing in the original)

Code
//=====================================================
const
anz_reg_io : byte = 128;

var
Reg_tasten, //Einlesen über port B
Reg_tasten_old, //zum Vergleich mit aktuellen t:ten
Reg_filter : array[1..anz_Reg_IO] of Byte; //Filter über IO//S

Const
Num16 : byte = 7;

F16_start : Byte = 1;
Adr_s16_7 : Byte = F16_start + 2;
Adr_s16_8 : Byte = F16_start + 1;
Adr_s16_9 : Byte = F16_start + 0;
Adr_s16_s : Byte = F16_start + 15;
Adr_s16_4 : Byte = F16_start + 14;
Adr_s16_5 : Byte = F16_start + 13;
Adr_s16_6 : Byte = F16_start + 12;
Adr_s16_1 : Byte = F16_start + 10;
Adr_s16_2 : Byte = F16_start + 9;
Adr_s16_3 : Byte = F16_start + 8;

var
Reg_tasten1[@Reg_tasten[adr_s16_1]] : byte;
Reg_tasten2[@Reg_tasten[adr_s16_2]] : byte;
Reg_tasten3[@Reg_tasten[adr_s16_3]] : byte;
Reg_tasten4[@Reg_tasten[adr_s16_4]] : byte;
Reg_tasten5[@Reg_tasten[adr_s16_5]] : byte;
Reg_tasten6[@Reg_tasten[adr_s16_6]] : byte;
Reg_tasten7[@Reg_tasten[adr_s16_7]] : byte;
Reg_tasten8[@Reg_tasten[adr_s16_8]] : byte;
Reg_tasten9[@Reg_tasten[adr_s16_9]] : byte;

//Num_0[@Reg_tasten[adr_s16_0],num16] : bit;
Num_1[@Reg_tasten1,num16] : bit;
Num_2[@Reg_tasten2,num16] : bit;
Num_3[@Reg_tasten3,num16] : bit;
Num_4[@Reg_tasten4,num16] : bit;
Num_5[@Reg_tasten5,num16] : bit;
Num_6[@Reg_tasten6,num16] : bit;
Num_7[@Reg_tasten7,num16] : bit;
Num_8[@Reg_tasten8,num16] : bit;
Num_9[@Reg_tasten8,num16] : bit;
//===================================================
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2134
Registered: 03 / 2003
Subject:

Re: Bitweiser Zugriff

 · 
Posted: 01.05.2019 - 12:40  ·  #8
Hallo Grech,

erst mal 2 Fragen:
Welchen Compiler benutzt du (Standard, Profi, Mega8/88, XMegaE5)?
Die LEDs sind einfarbig (kein RGB)?

Du könntest ein Array verwenden:
LED : Array[0..7,0..15] of Byte;

Der erste Wert entspricht dem Pin deines Ports B. Auf einem anderen, nicht verendeten Port definierst du eine SPI-Schnittstelle und schliesst diese an alle Eingänge deiner Schieberegister an. Die Pins des Ports B sind die /CS der 8 Ketten. Du mußt also nur für z.B. Schieberegister-Kette 4, den PortB,3 (es geht ja bei 0 los) auf Low ziehen und via SPI LED[3,0-15] raus schreiben. Der Zugriff auf die 16 Bytes jeder LED-Kette dürfte ja kein Problem sein.

Ich habe sowas ähnliches, nur kleiner mit 32 LEDs eindimensional, mal gemacht. Ich konnte mit einem Mega32 @ 16MHz meine LEDs via SoftSPI ca. 25000x/sek. updaten. topic.php?t=2828

Genau so könntest du auch die Schieberegister deiner Tasten einlesen.

Wenn du die Profi-Version hast, könntest du deine LED-Matrix als Grafik-Array definieren und mit dem GraphIOS immer alle LEDs updaten. Kommt drauf an, was du damit vor hast .... lohnt sich das?

Gruss
Harry

[Edit] Du bräuchtest sowas wie eine Word128-Variable (gibt nur 64):
Quote

4.1.20 WORD64
64bit, 8 Bytes, 0..18446744073709551615 Word64 sind ganze Zahlen. Sie sind auf einen Bereich von 0 bis 18446744073709551615 beschränkt. Word64 benötigen acht Byte Speicher.
var w64 : word64;
Achtung: 64bit Typen wie Word64, Int64 und Fix64 stehen nicht standardmässig zur Verfügung. Der entsprechende Typ muss explizit importiert werden.
from System Import Word64;
  • 1
  • 2
  • Page 1 of 2
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   136   150 · Page-Gen-Time: 0.023304s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI