| Zeile 59: | Zeile 59: | ||
</pre> | </pre> | ||
| + | ===PULSEIN=== | ||
| + | DIM Result AS WORD | ||
| + | PULSEIN Result , Pind , 2 , 1 | ||
| + | *Aufruf | ||
| + | <pre> | ||
| + | LDI ZL,0x30 // Adresse von SFR PIND | ||
| + | LDI r24,0x02 // PinNr 2 | ||
| + | LDI r16,0xFF // State 1 | ||
| + | CALL PULSEIN | ||
| + | |||
| + | LDI XL,0x60 laden der Ergebnisadresse | ||
| + | LDI XH,0x00 | ||
| + | ST X+,r24 // store result | ||
| + | ST X,r25 | ||
| + | </pre> | ||
| + | |||
| + | Hier kommen mehrere Funktionen zum Einsatz, die auch ggf. für andere Zwecke aufgerufen werden. | ||
| + | |||
| + | *Idle Loop | ||
| + | <pre> | ||
| + | L_0x009C: | ||
| + | SBIW ZL,0x0001 | ||
| + | BRNE L_0x009C | ||
| + | RET | ||
| + | </pre> | ||
| + | *Set_ErrBit | ||
| + | <pre> | ||
| + | SET | ||
| + | BLD r6,2 | ||
| + | RET | ||
| + | </pre> | ||
| + | *Clear_ErrBit | ||
| + | <pre> | ||
| + | CLT | ||
| + | BLD r6,2 | ||
| + | RET | ||
| + | </pre> | ||
| + | *MakeMask | ||
| + | <pre> | ||
| + | LDI r25,0x01 | ||
| + | AND r24,r24 | ||
| + | BREQ L_0x00BC | ||
| + | CLC | ||
| + | L_0x00B6: | ||
| + | ROL r25 | ||
| + | DEC r24 | ||
| + | BRNE L_0x00B6 | ||
| + | L_0x00BC: | ||
| + | MOV r24,r25 | ||
| + | COM r25 | ||
| + | RET | ||
| + | </pre> | ||
| + | *Pulsein, die eigentliche Funktion | ||
| + | <pre> | ||
| + | PULSEIN: | ||
| + | CALL Clear_ErrBit | ||
| + | CLR ZH | ||
| + | CLR XL // clear Timout Lo | ||
| + | CLR XH // clear Timout Hi | ||
| + | CALL MakeMask // R24 Mask, R25 neg Mask | ||
| + | AND r16,r24 | ||
| + | LDD r0,Z + 1 // DDRD | ||
| + | AND r0,r25 // Make Input | ||
| + | STD Z + 1,r0 // DDRD | ||
| + | L_0x00D8: // ------------- Loop | ||
| + | LDD r0,Z + 0 // PIND | ||
| + | AND r0,r24 // PIND & Mask | ||
| + | EOR r0,r16 // (PIND & Mask) ^ State | ||
| + | BRNE L_0x00E6 // Ok PIN != State | ||
| + | ADIW XL,0x0001 // Timeout counter++ | ||
| + | BREQ L_0x0118 // elapsed->ERR-Exit | ||
| + | RJMP L_0x00D8 // cont'd Loop | ||
| + | L_0x00E6: | ||
| + | CLR XL // clear Timout Lo | ||
| + | CLR XH // clear Timout Hi | ||
| + | L_0x00EA: // ------------- Loop | ||
| + | LDD r0,Z + 0 // PIND | ||
| + | AND r0,r24 // PIND & Mask | ||
| + | EOR r0,r16 // (PIND & Mask) ^ State | ||
| + | BREQ L_0x00F8 // Ok PIN == State | ||
| + | ADIW XL,0x0001 // Timeout counter++ | ||
| + | BREQ L_0x0118 // elapsed->ERR-Exit | ||
| + | RJMP L_0x00EA // cont'd Loop | ||
| + | L_0x00F8: | ||
| + | CLR XL // clear Timout Lo | ||
| + | CLR XH // clear Timout Hi | ||
| + | |||
| + | L_0x00FC: | ||
| + | PUSH ZL // Save | ||
| + | PUSH ZH | ||
| + | LDI ZL,0x20 // calc from $XTAL | ||
| + | LDI ZH,0x00 | ||
| + | CALL L_0x009C // 10 µS Idle | ||
| + | POP ZH // Restore | ||
| + | POP ZL | ||
| + | LDD r0,Z + 0 // PIND | ||
| + | AND r0,r24 // PIND & Mask | ||
| + | EOR r0,r16 // (PIND & Mask) ^ State | ||
| + | BRNE L_0x011C // OK, Pulsein done ********* | ||
| + | ADIW XL,0x0001 // PulseCounter++ | ||
| + | BRNE L_0x00FC // cont'd Loop | ||
| + | L_0x0118: | ||
| + | CALL Set_ErrBit | ||
| + | L_0x011C: | ||
| + | MOV r24,XL // result --> R24:r25 | ||
| + | MOV r25,XH | ||
| + | RET // that's it | ||
| + | </pre> | ||
==Autor== | ==Autor== | ||
Version vom 8. Juni 2006, 09:11 Uhr
Inhaltsverzeichnis
Bascom Inside-Code
Für den allgemein Interessierten und für Power-User, die ihr Bascom-Programm mit etwas Assembler-Code aufpeppen möchten, stelle ich recht zwanglos einige Assembler-Codeschnipsel zusammen mit den zugehörigen Bascom-Statements zur Verfügung.
Die meisten Beispiele könnte man mit Inline-Assemler direkt ersetzen, wenn man mal probieren wollte, man muß natürlich auf Daten- und Labeladressen aufpassen
Die meisten Bascom-Funktionen ergeben im Code dann folgende Teile:
- Der Aufruf
- die Vorbereitung, also das Laden von Registern mit den konkreten Argumenten,
- einen Call auf den eigentliche Funktions-code
- das Abliefern des Ergebnisses
- Die Funktion selbst
Config ADC
CONFIG Adc = Single , Prescaler = Auto
LDI r24,0x06 OUT ADCSR,r24
Start ADC
START ADC
SBI ADCSR,ADEN
Getadc()
- Aufruf
DIM X AS WORD laut "prog.RPT" an der Adresse 0x0063 X = GETADC(0)
ergibt folgenden Code:
LDI r24,0x00 ADC-Kanal-Nummer nach Register 24 OUT ADMUX,r24 in den ADC-Multiplexer CALL L_0x00F6 Aufruf der getadc-funktion LDI XL,0x63 laden der Ergebnisadresse (DIM X AS WORD) LDI XH,0x00 ST X+,r24 Speichern ergebnis (R24:r25) in "X" ST X,r25
- Funktion
L_0x00F6: SBI ADCSR,ADSC Starten der 1. Konversion L_0x00F8: SBIC ADCSR,ADSC Fertig ? RJMP L_0x00F8 nein, Loop1 SBI ADCSR,ADSC Starten der 2. Konversion L_0x00FE: SBIC ADCSR,ADSC Fertig ? RJMP L_0x00FE nein, Loop2 IN r24,ADCL Ergebnis auslesen r24:r25 IN r25,ADCH RET fertig
PULSEIN
DIM Result AS WORD PULSEIN Result , Pind , 2 , 1
- Aufruf
LDI ZL,0x30 // Adresse von SFR PIND LDI r24,0x02 // PinNr 2 LDI r16,0xFF // State 1 CALL PULSEIN LDI XL,0x60 laden der Ergebnisadresse LDI XH,0x00 ST X+,r24 // store result ST X,r25
Hier kommen mehrere Funktionen zum Einsatz, die auch ggf. für andere Zwecke aufgerufen werden.
- Idle Loop
L_0x009C: SBIW ZL,0x0001 BRNE L_0x009C RET
- Set_ErrBit
SET BLD r6,2 RET
- Clear_ErrBit
CLT BLD r6,2 RET
- MakeMask
LDI r25,0x01 AND r24,r24 BREQ L_0x00BC CLC L_0x00B6: ROL r25 DEC r24 BRNE L_0x00B6 L_0x00BC: MOV r24,r25 COM r25 RET
- Pulsein, die eigentliche Funktion
PULSEIN: CALL Clear_ErrBit CLR ZH CLR XL // clear Timout Lo CLR XH // clear Timout Hi CALL MakeMask // R24 Mask, R25 neg Mask AND r16,r24 LDD r0,Z + 1 // DDRD AND r0,r25 // Make Input STD Z + 1,r0 // DDRD L_0x00D8: // ------------- Loop LDD r0,Z + 0 // PIND AND r0,r24 // PIND & Mask EOR r0,r16 // (PIND & Mask) ^ State BRNE L_0x00E6 // Ok PIN != State ADIW XL,0x0001 // Timeout counter++ BREQ L_0x0118 // elapsed->ERR-Exit RJMP L_0x00D8 // cont'd Loop L_0x00E6: CLR XL // clear Timout Lo CLR XH // clear Timout Hi L_0x00EA: // ------------- Loop LDD r0,Z + 0 // PIND AND r0,r24 // PIND & Mask EOR r0,r16 // (PIND & Mask) ^ State BREQ L_0x00F8 // Ok PIN == State ADIW XL,0x0001 // Timeout counter++ BREQ L_0x0118 // elapsed->ERR-Exit RJMP L_0x00EA // cont'd Loop L_0x00F8: CLR XL // clear Timout Lo CLR XH // clear Timout Hi L_0x00FC: PUSH ZL // Save PUSH ZH LDI ZL,0x20 // calc from $XTAL LDI ZH,0x00 CALL L_0x009C // 10 µS Idle POP ZH // Restore POP ZL LDD r0,Z + 0 // PIND AND r0,r24 // PIND & Mask EOR r0,r16 // (PIND & Mask) ^ State BRNE L_0x011C // OK, Pulsein done ********* ADIW XL,0x0001 // PulseCounter++ BRNE L_0x00FC // cont'd Loop L_0x0118: CALL Set_ErrBit L_0x011C: MOV r24,XL // result --> R24:r25 MOV r25,XH RET // that's it
Autor
Siehe auch