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

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.

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 ]

x = BYTE
PORT.x = ...

De oplossing wordt beschreven in de cursus: www.picbasic.nl/beginners10a_nl.htm

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.

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 ]

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.

Inmiddels getest: werkt prima!! :-)