Ben sinds twee weken nu bezig met PIC's. Zelf ben ik VB6 en C# (.NET) programmeur. Ik ben dus niet echt meer gewend om stil te staan bij de bits en bytes van een BASIC taal als PICBASIC.
Evenals de array's die hier gebruikt worden.
Ik zou graag in een dubbele FOR-loop (genest) een tweedimensionale array uitvragen. Ik gebruik hiervoor een WORD-array welke 16 bits bevat en zo tweedimensionaal gebruikt kan worden. Het volgende heb ik gedefinieerd:
DIM LEDseq[4] AS WORD ;array voor het LEDpatroon
;vullen van het array
; 1234567890123456 De 16 bits van een woord
LEDseq[0] = 1010000000000000
LEDseq[1] = 0101000000000000 ;Bitwaarden per woord
LEDseq[2] = 0000001000000000
LEDseq[3] = 0000001000000000
Op deze wijze kan ik later heel makkelijk dit als parameter instellen en middels input vanaf een VB applicatie vullen naar wens van een gebruiker. Uiteraard zal dan een werkende interface klaar zijn. Maar dit terzijde.
Ik heb uiteraard al heel wat afgegoogled, maar heb geen oplossing kunnen vinden. Wel wordt er op http://www.picbasic.co.uk/forum/archive/index.php/t-544.html heel wat nuttige informatie gegeven, maar de syntax blijkt niet overeen te komen met mijn PROTON IDE vs1.0.0.1 en de BASIC Compiler vs2.2.0.20. Ik krijg dan "Not PROTON+ syntax.".
Enig idee hoe ik nu met twee variabelen een bit uit een word-element kan uitvragen?
In VB is uitvragen van een tweediminsionale array geen probleem:
Dim MyArray(3,15) As Integer
Dim intIndex1, intIndex2 As Integer
If MyArray(intIndex1, intIndex2) = 0 Then
<actie>
End If
Een beetje hetzelfde probleem heb ik met de I/O verwijzing. Graag zou ik zoiets als PORTA.[Index1] willen gebruiken. Is dat mogelijk?
In VB6:
Dim PORTA(7) As Integer
Dim LEDseq(,) As Integer = New Integer(3,15)
{{1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},}
Dim intIndex1, intIndex2 As Integer
Do While 1 = 1
For intIndex2 = 0 To 15
For intIndex1 = 0 To 3
PORTA(intIndex2) = LEDseq(intIndex1, intIndex2)
Next intIndex1
Next intIndex2
intIndex1 = 0
intIndex2 = 0
Loop
LaStei
carpe cerevisi
Eigenlijk moet je het hele probleem omdenken. De meeste uC werken het beste in bytes, en alle andere definities (int/word/array etc) zijn daar een afgeleide van en geeft problemen. Het array lijkt me statisch, i.e. wordt alleen maar uitgelezen. Je hebt 16 bits nodig voor je LED sequence, dus eigenlijk twee bytes. Voor moet je dus alles omrekenen, de word je de kolom met I en de rij met J doet dan is de inhoud van een cel [I,J] de plaats in het geheugen voor de low byte I(2J+1) en voor de high byte I(2J+1)+1. Het beste kun je mischien een kleine functie schrijven die deze macros voor je uitvoert. Hou trouwens wel rekening mee met de pagina grote van je array!
Als je trouwens elk bit als variabele op wilt slaan, dan vreet je geheugen, en dat heb je in je PIC niet. Omdat het bitwaarden zijn gewoon 8 als byte opslaan en afvragen welk bit je nodig hebt.
[Bericht gewijzigd door LaStei op ]
Op 14 maart 2007 15:30:59 schreef LaStei:
Als je trouwens elk bit als variabele op wilt slaan, dan vreet je geheugen, en dat heb je in je PIC niet.
Ja, dat heb je met die VB en .NET jongens. Een int gebruiken om een bitje op te slaan 
Dat begrijp ik nog wel JoWi . .
Vandaar ook een declaratie van een simpel word array in PICBASIC.
4x16 bits, wat is daar mis mee?
VB code dient alleen als voorbeeld.
Op 14 maart 2007 15:43:08 schreef JoWi:
[...]Ja, dat heb je met die VB en .NET jongens. Een int gebruiken om een bitje op te slaan
Dat valt nog mee. Echte .net jongens slaan alles op in unicode ascii :')
De laatste drie opmerkingen zijn lekker Off-topic, dus daar schiet ik weinig mee op.
LaStei:
Om even op jouw reply door te gaan. Kun je mij een syntactisch correct voorbeeld geven hoe je dat definieerd en vervolgens een dergelijke bit uit kan vragen?
Dat zal het een stuk duidelijker voor mij maken.
Jeroen Boere
IF you can't convince them, then confuse them!
een bit uit een byte opvragen doe je zo
if bytenaam.2 = 1 then HighBit = true "Kijk of bit twee hoog is, zoja; set HighBit = true (bijvoorbeeld)
Dank je, maar dat had ik al begrepen Jeroen.
En een bit uit een wordarray is ook geen probleem:
Variabele = Wordarray#1.2
Maar het gaat er om variabelen te gebruiken en geen integers.
Dus b.v.:
Variabele = Wordarray#[x].[y] ;Dit gaat niet werken!!
Al gedacht aan 'a=array[x][y][z]=array[x+x_lengte*y+x_lengte*y_lengte*z] ?
(desnoods met wat bitshifts en andere meuk)
[Bericht gewijzigd door alex278 op ]
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl
x = BYTE
PORT.x = ...
De oplossing wordt beschreven in de cursus: www.picbasic.nl/beginners10a_nl.htm
LaStei
carpe cerevisi
Helaas... Ik ben niet zo goed in PICBASIC, ik schrijf alles in assembler.... Maar het zal zoiet worden:
a = leesmatrix(x,y)
.
.
function matrix(x,y)
BCF STATUS,C ;clear carry bit
RRF X,W ;2x in W
ADDLW 1 ;2x+1 in W
MOVWF resultlo
MOVF Y
CALL MUL8x8 ;matrix max 256 elements,
resulthi ignore
MOVF resultlo,W ;Store value in W
CALL MATRIX_TBL ;Value now in W
.
.
.
.
;***************************************************************************
;** time efficient multiplication 8 bit x 8 bit = 16 bit (unsigned)
;**
;** company: elektronik 21 GmbH
;** programmer: Martin Schaefer (idea from Andrew Warren)
;**
;** execution time: fixed 38 cycles (with jump in and jump out) !!!
;** code length: 35 words
;** multiplier: w
;** multiplicand: resultlo
;** result: resulthi:resultlo
;***************************************************************************
MUL8X8 CODE
Mul8x8 ;* 2 cycles for call - instruction
GLOBAL Mul8x8, resulthi, resultlo
mult MACRO
btfsc STATUS,C
addwf resulthi,F
rrf resulthi,F
rrf resultlo,F
ENDM
clrf resulthi ;* 1 cycle
rrf resultlo,F ;* 1 cycle
mult ;* 4 cycles
mult ;* 4 cycles
mult ;* 4 cycles
mult ;* 4 cycles
mult ;* 4 cycles
mult ;* 4 cycles
mult ;* 4 cycles
mult ;* 4 cycles
retlw 0 ;* 2 cycles
;***************************************************************************
.
.
.
MATRIX_TBL ; matrix table
ADDWF PCL,F
DT 0x00,0x01,0x02,0x03....etc
DT 0x10,0x11,0x12........etc
MATRIX_TBL_END
; Check to ensure table doesn't cross a page boundary
IF ( (CMD_TBL & 0xFF00) != (CMD_TBL_END & 0xFF00) )
MESSG "Warning - User Defined: TABLE2 crosses page boundary in computed jump"
ENDIF
Maar er zijn misschien meer mensen die je met PIC basic kunnen helpen
Dank voor de moeite LaStei, maar hier kan ik idd geen soep van koken
. Wellicht dat iemand dit kan vertalen naar PICBASIC.
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl
Zoals eerder geschreven, de oplossing wordt beschreven in de cursus: www.picbasic.nl/beginners10a_nl.htm
(Zie ook je e-mail)
Ah Frits, zie nu ook jouw reactie. Sorry. Ik zal de link even doornemen. Alvast bedankt.
[EDIT]
Heb net je mail gezien. Dank je! Moest hem even uit de junkmail vissen (dat is geen blijk van ondankbaarheid
), dus geen melding gekregen.
Ok, dat PICBASIC niet met tweedimensionale arrays overweg kan dat vermoedde ik al. Maar je kunt natuurlijk de workarround handhaven die Melanie omschrijft op het PICBASIC forum bij punt 4. Of niet? Ik begrijp het syntax verschil alleen niet. Hebben we het hier over twee wezelijk verschillende PICBASIC versies?
[Bericht gewijzigd door Jevis op ]
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl
Ja, de link van jouw gaat naar Melabs PIC Basic, mijn website (en dus ook de cursus) is geschreven voor de Proton PIC Basic van Crownhill.
Melabs heeft meer weg van Basic Stamp.
Op 15 maart 2007 20:20:28 schreef Frits Kieftenbelt:
Ja, de link van jouw gaat naar Melabs PIC Basic, mijn website (en dus ook de cursus) is geschreven voor de Proton PIC Basic van Crownhill.Melabs heeft meer weg van Basic Stamp.
Aha, vandaar. Bedankt!
Wel, ben even aan het stoeien geweest . . . en zie hier het resultaat:
DEVICE 16F628A
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF
ALL_DIGITAL TRUE
SYMBOL PRESS = 0 ;Button pressed
SYMBOL RELEASE = 1 ;Button released
SYMBOL OFF = 0 ;LEDstatusindication OFF
SYMBOL ON = 1 ;LEDstatusindication ON
SYMBOL LED1 = PORTA.0 ;Output
SYMBOL LED2 = PORTA.1
SYMBOL LED3 = PORTA.2
SYMBOL LED4 = PORTA.3
SYMBOL LED5 = PORTA.4
SYMBOL LED6 = PORTA.5
SYMBOL LED7 = PORTA.6
SYMBOL LED8 = PORTA.7
SYMBOL S1 = PORTB.0 ;Input
SYMBOL S2 = PORTB.1
SYMBOL S3 = PORTB.2
SYMBOL S4 = PORTB.3
DIM LEDseq[4] AS WORD ;array which holds LEDpattern
DIM Pattern AS WORD ;var to temp hold element from LEDseq
; in order for GETBIT to work
DIM Index1 AS BYTE ;counter representing no of bits per element
DIM Index2 AS BYTE ;counter representing no of elements in array
PORTB_PULLUPS ON ;On-chip pull-up active
CLEAR ;Clear RAM
; 76543210
PORTA = %00000000 ;All PORTA low
TRISA = %00000000 ;PORT A.0-7 as output
TRISB = %11111111 ;PORT B.0-7 as input
;initialize array
; 0123456789012345
LEDseq[0] = %1010000000000000
LEDseq[1] = %0101000000000000
LEDseq[2] = %0000001000000000
LEDseq[3] = %0000001000000000
;Main
WHILE 1 = 1 ;create endless loop
FOR Index1 = 0 TO 15 ;Run down patternsequence per bit...
FOR Index2 = 0 TO 3 ;...for each LED
Pattern = LEDseq[Index2] ;allow GETBIT through temp var
IF GETBIT Pattern, Index1 = ON THEN ;if bit indicating LED ON...
SETBIT PORTA, Index2 ;...turn LED ON thru corresponding port
ELSE ;else: indicating LED should be OFF...
CLEARBIT PORTA, Index2 ;...turn LED OFF thru corresponding port
ENDIF ;close if
NEXT ;next LED
NEXT ;next step in sequence
WEND
END
Nog geen tijd voor test gehad. Volgt nog ...
Wie er tussentijds feedback heeft is welkom.
