ByteForth macrocompiler voor AVR en 8052 |
1. Wat is ByteForthByteForth is een 8-bits Forth compiler onder MS-DOS die code genereert voor een microcontroller zonder externe ROM en RAM. Het Forth systeem levert zelfstandig werkende machinecode af zonder de bekende Forth interpreter. ByteForth heeft een ingebouwde simulator, de gegenereerde code kan dus zo op de PC worden getest. Om de hardware te kunnen testen moet de code natuurlijk op de microcontroller draaien.Maar ByteForth is meer.
|
2. Macrocompiler voor ByteForth
|
\ Voorbeeld van een macro \ uit 8051 ByteForth: $11 MACRO SWAP ( x1 x2 -- x2 x1 ) A: @R0 MOV, R0: INC, A: @R0 XCH, R0: DEC, @R0 A: MOV, RET, END-CODE |
\ Voorbeeld van een macro \ uit AVR ByteForth: $02 MACRO SWAP ( x1 x2 -- x2 x1 ) R17 X+ LD, R16 X+ LD, -X R17 ST, -X R16 ST, RET, END-CODE |
4. Interactief testen (software simulator)Als je nieuwe code gaat compileren, moet je beginnen met EMPTY (verwijder alle eventuele code uit de programmabuffer) en bijvoorbeeld 89C2051 (de naam van de betreffende microcontroller).Met de ingebouwde simulator kun je de code testen, de hardware natuurlijk niet. Voorbeeld: |
1 DUP .S \ Test de bibliotheekroutine DUP \ met het getal 1 op de stack ( 1 1 ) \ De reactie van Forth |
De routine DUP blijkt te werken.
Alle zelf gemaakte woorden zijn op dezelfde manier te testen. |
\ We maken zelf het woord NIP : NIP ( x y -- y ) SWAP DROP ; 1 2 NIP .S \ We testen NIP ( 2 ) \ De reactie van Forth |
5. Flash programmerDe beide versies van ByteForth bevatten een flash-programmer om het ontwikkelde programma in de geselecteerde microcontroller te kunnen zetten. De nieuwe 8051-versie heeft nu een programmer via RS232 voor o.a. de AT89C2051 en een ISP-programmer (In System Programmer) voor bijv. de AT89S8252. Op dit moment ben ik bezig de C2-interface toe te voegen voor de C8051F3xx. Als die af is komt er een nieuwe 8051 ByteForth uit.De AVR-versie van ByteForth bevat een ISP-programmer die tientallen verschillende AVR microcontrollers kan programmeren, de ISP-hardware is gelijk aan die voor de 8051 versie. Ze zijn daarom uitwisselbaar. |
6. Optimising compilerEen prefix met datawoord assembleert zeer compacte code (TO-concept).Voorbeeld: |
\ voor 8051 VARIABLE COUNTER CLEAR COUNTER wordt adr 0 # MOV, [3 bytes] INCR COUNTER adr INC, [2 bytes] FROM COUNTER R0: DEC, @R0 adr MOV, [3 bytes] |
\ voor AVR VARIABLE COUNTER CLEAR COUNTER wordt R16 0 LDI, Y+adr R16 STD, [4 bytes] INCR COUNTER R16 Y+adr LDD, R16 INC, Y+adr R16 STD, [6 bytes] FROM COUNTER R16 Y+adr LDD, -X R16 ST, [4 bytes] |
\ voor 8051 FLAG END? CLEAR END? wordt bitadr CLR, [2 bytes] SET END? bitadr SETB, [2 bytes] END? C: bitadr MOV, A: ACC: SUBB, R0: DEC, @R0 A: MOV, [6 bytes] |
\ voor AVR FLAG END? CLEAR END? wordt CLT, bitadr BLD, [4 bytes] SET END? SET, bitadr BLD, [4 bytes] END? R16 CLR, bitadr SBRC, R16 $FF ORI, -X R16 ST, [8 bytes] |
EXIT maakt van de laatste call een jump indien mogelijk. Controlestructuren assembleren rechtstreeks machinecode.
Edge optimiser: alle woorden en macro's zijn gemerkt met een code waar hun stack-invoer en stack-uitvoer aan af te lezen is. De compiler kan hieruit afleiden hoe hij deze randen kan optimaliseren. Macro's kunnen hierdoor in elkaar geschoven worden. Enkele voorbeelden. Zonder optimiser: |
\ 8051 10 TO COUNTER R0: DEC, @R0 10 # MOV, adr @R0 MOV, R0: INC, [6 bytes] BEGIN END? UNTIL C: bitadr MOV, A: ACC: SUBB, R0: DEC, @R0 A: MOV, A: @R0 MOV, R0: INC, codeadr JZ, [10 bytes] |
\ AVR
10 TO COUNTER R16 10 LDI, -X R16 ST, R16 X+ LD, Y+adr STD, [8 bytes] BEGIN END? UNTIL R16 CLR, bitadr SBRC, -X R16 ST, R16 X+ LD, R16 TST, codeadr BREQ, [12 bytes] |
Met optimiser: |
10 TO COUNTER adr 10 # MOV, [3 bytes] BEGIN END? UNTIL bitadr codeadr JNB, [3 bytes] |
10 TO COUNTER R16 10 LDI, Y+adr R16 STD, [4 bytes] BEGIN END? UNTIL bitadr SBRS, adr RJMP, [4 bytes] |
7. Voorbeeld van een compleet programmaHet volgende programma krijgt analoge input binnen die gedigitaliseerd wordt. Het resultaat komt als een binair getal op 8 leds te staan. |
\ Analoog naar digitaal omzetting met de TLC549IP \ Codelengte voor de AT89C2051=201 bytes, voor de AT90S2313=292 bytes). 89C2051 TARGET \ Compileer voor AT89C2051 $90 SFR LEDS \ Poort 1 met 8 leds $B4 BIT-SFR ADC-KLOK \ Klokpuls invoer P3.4 $B5 BIT-SFR ADC-DATA \ Data uitvoer P3.5 $B7 BIT-SFR ADC-SELECTEER \ Activeer invoer P3.7 : ADC ( -- u ) \ Doe een AD-omzetting FALSE TO ADC-KLOK \ Stop lezen van analoge invoer TRUE TO ADC-SELECTEER \ Start AD-omzetting 4 0 DO LOOP \ Conversie duurt min. 17 us FALSE TO ADC-SELECTEER \ Start uitlezen ADC-DATA 1 AND \ Lees databit 7 7 0 DO \ Lees resterende 7 databits TRUE TO ADC-KLOK FALSE TO ADC-KLOK \ Schuif volgend bit naar buiten 2 * ADC-DATA 1 AND OR \ Schaal data in en lees volgend bit LOOP TRUE TO ADC-KLOK \ Blijf analoge invoer lezen ; : NAAR-LEDS ( u -- ) \ Print data binair INVERT TO LEDS ; : KNIPPER ( -- ) \ Visualiseer opstarten -1 NAAR-LEDS 250 MS \ Alle leds aan 0 NAAR-LEDS 250 MS \ Alle leds uit ; : TOON-ADC ( -- ) \ Toon omzetting op LEDS SETUP KNIPPER BEGIN ADC NAAR-LEDS AGAIN \ Lees ADC, en toon uitkomst ; ' TOON-ADC RESET-VEC SET-VECTOR \ Installeer ADC omzetter \ Einde |
8. ByteForth werkcyclus | |
Laptop met dongle en Ushi |
|
De ByteForth versies op een rij |
Overzicht van de wijzigingen (2.00 t.o.v. 1.70):
Door al deze verbeteringen kan ByteForth nu nog compactere code genereren, ook wanneer het 16-bits getallen en variabelen betreft. Het debuggen is eenvoudiger door het goed leesbare resultaat van de disassembler. Er zijn bibliotheek en voorbeeld-files bijgekomen die het maken van eigen toepassingen vergemakkelijken.
|
|
|