Vai al contenuto
PLC Forum


Api Da Usare In Vb.. - Accesso diretto al BIT


roberto.zeni

Messaggi consigliati

Ho una variabile in formato Word (16 bit).

Vorrei una funzione che mi accede direttamente al singolo bit (senza modificare gli altri) per quanto riguarda:

- Lettura del singolo bit

- Scrittura a 1 del singolo bit (senza modificare gli altri)

- Scrittura a 0 del singolo bit (senza modificare gli altri)

Ho già trovato delle soluzioni tramite codice VB che mi sembrano però abbastanza complicate (soprattutto per quanto riguarda la scrittura a zero del singolo bit).

Esistono delle API (oppure delle soluzioni eleganti) da usare in VB che permettano questo?

Grazie

Link al commento
Condividi su altri siti


Ospite bingobongo

ho trovato qualcosa che avevo fatto, forse ti potrebbe andare bene ? <_<

prova a mettere questo codice in una form.

DefInt A-Z
Dim b(0 To 15) As Boolean


Private Sub Form_click()
Dim a

'
'prova ad elaborare il numero 33
'
a = 33
rw_nb a

Form1.Print a
For x = 0 To 15
Form1.Print x, 2 ^ x, b(x)
Next

'
'mostra il 33 col bit 2 alto
'
Form1.Print wr_nb(a, 2, True)

End Sub


Sub rw_nb(word As Integer)

Dim x           As Integer

'
'legge i bit
'
For x = 0 To 15

If (word And (2 ^ x)) = (2 ^ x) Then b(x) = True Else b(x) = False

Next


End Sub



Function wr_nb(word As Integer, bit As Integer, VeroFalso As Boolean) As Integer

Dim new_word    As Integer
Dim x           As Integer
'
'prima legge i bit
'
For x = 0 To 15
    If (word And (2 ^ x)) = (2 ^ x) Then b(x) = True Else b(x) = False
Next

b(bit) = VeroFalso

'
'poi riscrive la word col bit(0-15) cambiato
'
For x = 0 To 15
    If b(x) = True Then new_word = new_word + (2 ^ x)
Next

wr_nb = new_word

End Function

Modificato: da Gabriele Corrieri
Link al commento
Condividi su altri siti

Se cerchi nel forum , avevo tempo fa postato una DLL per gestire gli shift e le operazioni booleane , che puoi facilmente implementare in VB.

Ciao B)

Link al commento
Condividi su altri siti

Le routine seguenti non usano API però secondo me sono abbastanza eleganti.

'

' Function : Eleva 2 a potenza

' Input : Esponente

' Output : 2^Esponente

' Nota : L'esponente deve essere compreso nel range [0,31]

'

Public Function Eleva2(ByVal exponent As Long) As Long

Static res(0 To 31) As Long

Dim i As Long

'

' Generazione errore di Run-Time

'

If (exponent < 0 Or exponent > 31) Then Err.Raise 5

If res(0) = 0 Then

res(0) = 1

For i = 1 To 30

res(i) = res(i - 1) * 2

Next

'

' Caso speciale

'

res(31) = &H80000000

End If

Eleva2 = res(exponent)

End Function

'

' Function : Setta il Bit specificato in un long

' Input : - Valore di cui si vuole modificare il Bit

' - num° Bit

' - Stato ON-OFF (1-0)

' Output : Valore modificato

' Nota : Richiesta routine Eleva2()

'

Public Function SetBit(ByVal value As Long, ByVal bit As Long, ByVal stato As Byte) As Long

If stato = 0 Then SetBit = (value And Not Eleva2(bit))

If stato = 1 Then SetBit = (value Or Eleva2(bit))

End Function

'

' Function : Testa il valore del Bit specificato

' Input : - Valore di cui si vuole conoscere lo stato di un Bit

' - num° Bit

' Output : - 1 se il Bit esaminato è a 1

' - 0 se il Bit esaminato è a 0

' Nota : Richiesta routine Eleva2()

'

Public Function BitTest(ByVal value As Long, ByVal bit As Long) As Byte

Dim LocalVal As Boolean

LocalVal = (value And Eleva2(bit))

BitTest = IIf(LocalVal = True, 1, 0)

End Function

'

' Function : Conta il numero di Bit settati a 1

' Input : Valore di cui calcolare il numero di Bit a 1

' Output : Numero di Bit a 1

' Nota : Questa routine si basa su una propietà dei numeri binari :

' (number And (number - 1)) pulisce sempre il Bit meno significativo

' del numero number

'

Public Function BitCount(ByVal Number As Long) As Integer

Do While Number

Number = Number And (Number - 1)

BitCount = BitCount + 1

Loop

End Function

'

' Function : Modifica lo stato del Bit specificato

' Input : - Valore di cui si vuole modificare lo stato di un Bit

' - num° Bit

' Output : Valore con il Bit specificato settato a:

' - 0 se questo era a 1

' - 1 se questo era a 0

' Nota : Richiesta routine Eleva2()

'

Public Function BitToggle(ByVal value As Long, ByVal bit As Long) As Long

BitToggle = (value Xor Eleva2(bit))

End Function

Link al commento
Condividi su altri siti

- Lettura del singolo bit

- Scrittura a 1 del singolo bit (senza modificare gli altri)

- Scrittura a 0 del singolo bit (senza modificare gli altri)

Ho già trovato delle soluzioni tramite codice VB che mi sembrano però abbastanza complicate (soprattutto per quanto riguarda la scrittura a zero del singolo bit).

lettura singolo bit:

c = a AND x dove in x c'è la maschera del bit da estare es. x=8 testi il 4 bit

Scrivere 1 nel bit

c= a OR x dove x contiene il bit da forzare a 1 es. x=8 forzi il 4 bit

Scrivere 0 nel bit

c = a AND x dove x contiene il complemento del bit da azzerare es. x=247 azzeri il bit 4

Link al commento
Condividi su altri siti

Visual Basic fa a pugni con le operazioni sui bit.

Comunque, per finire l'esposizione di Livio, aggiungo...

Shift a sinistra di n bit:

c = a * 2^n

Shift a destra di n bit:

c = a / 2^n

Ciao!

Link al commento
Condividi su altri siti

Salve,

E' impensabile usare una funzione per ricavare lo stato di una variabile,

quando l'unico che bisogna fare e' costruire la struttura della data in base

a la forma desiderata e poi accedere a questa tramite l'indirizzamento.

Non so se in Vbasic e' possibile , ma quello che devi fare e' una "union"

tra una variabile del tipo "signed short int" (–32,768 to 32,767),

una var. del tipo "signed char" (–128 to 127) ed una struttura di 16

elementi del tipo "unsigned" come sotto indicato.

// Dichiarazione della struttura

union reg_16bits

{signed short int mw_16;

signed char mb_8[2];

struct merker_flags {

unsigned bit0:1;

unsigned bit1:1;

unsigned bit2:1;

unsigned bit3:1;

unsigned bit4:1;

unsigned bit5:1;

unsigned bit6:1;

unsigned bit7:1;

unsigned bit8:1;

unsigned bit9:1;

unsigned bit10:1;

unsigned bit11:1;

unsigned bit12:1;

unsigned bit13:1;

unsigned bit14:1;

unsigned bit15:1;

}wd;

};

// Dechiarazione della data costruita sulla base struttura

union reg_16bits DB10[256]; // costruzione del DB10 con 255 words

// indirizzamento e accesso a i dati.

DB10[0].mw_16=0x0b0a; // carico il num dec. 2826 su la word zero del DB10

DB10[0].mb_8[0]=0x0a; // accesso al byte basso

DB10[0].mb_8[1]=0x0b; // accesso al byte alto

DB10[0].wd.bit15; // 0 - bit del segno

DB10[0].wd.bit14; // 0

DB10[0].wd.bit13; // 0

DB10[0].wd.bit12; // 0

DB10[0].wd.bit11; // 1

DB10[0].wd.bit10; // 0

DB10[0].wd.bit9; // 1

DB10[0].wd.bit8; // 1

DB10[0].wd.bit7; // 0

DB10[0].wd.bit6; // 0

DB10[0].wd.bit5; // 0

DB10[0].wd.bit4; // 0

DB10[0].wd.bit3; // 1

DB10[0].wd.bit2; // 0

DB10[0].wd.bit1; // 1

DB10[0].wd.bit0; // 0 bit piu' significativo

Saluto.

Link al commento
Condividi su altri siti

Salve Livio,

il VB è una cosa un po' diversa

Lo so,

Sinceramente non sono al corrente dei nuovi sviluppi del VB,non l'uso da un bel po'

DB10[0].wd.bit0; // 0 bit piu' significativo

oops, // 0 bit meno significativo

Saluto.

Link al commento
Condividi su altri siti

Personalmente ritengo che sia molto piu' oneroso fare delle elevazioni a potenza che usare uno shift anche se richiamato tramite dll.

Al limite se non si voglio usare delle dll esterne , si puo' sempre pre-caricare in un array i valori per i mascheramenti.

Es:

dim aPesi[16] as long

aPesi[0] = 1

aPesi[1] = 2

aPesi[2] = 4

aPesi[3] = 8

aPesi[4] = 16

aPesi[5] = 32

aPesi[6] = 64

aPesi[7] = 128

aPesi[8] = 256

aPesi[9] = 512

aPesi[10] = 1024

aPesi[11] = 2048

aPesi[12] = 4096

aPesi[13] = 8192

aPesi[14] = 16384

aPesi[15] = 32768

Per testare il bit 5 della word Pippo

dim Pippo as long

Pippo = 5342

if pippo and aPesi[5] then

msgbox "Pippo = 1"

else

msgbox "Pippo = 0"

endif

Ciao B)

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...