PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Funktion PULSEIN



Dirk
07.05.2006, 20:00
Hallo Bascom-Kenner,

wie genau ist eigentlich die Funktion PULSEIN?

Anders gefragt: In der mcs.lib ist bei der Funktion _pulse_in angegeben, dass man hier Anpassungen (@genus) je nach Prozessor machen muss, um das Messintervall möglichst genau hinzukriegen.
Da ist ein Wert von 9 Zyklen vorgegeben, der aber wohl für den internen Takt von 1MHz ausgelegt ist. Dann findet sich da auch eine Bemerkung, dass man für einen 4MHz-Takt 30 Zyklen zusätzlich braucht.

Mich würde der Wert für einen M32 mit 8MHz interessieren. Wie kann ich hier den Wert selbst anpassen?

Meine Messungen mit dem M32 haben bei längeren Intervallen von z.B. 36ms einen zu kleinen Messwert von 35,6ms gezeigt.

Gruß Dirk

hrei
08.05.2006, 09:41
Hallo,

@genus(n) wird bereits von Bascom nach $crystal berechnet und sorgt in diesem Fall für 9 µS Wartezeit, wir können das also unverändert übernehmen. Die restliche µS muss noch beackert werden. Bei den für 8 Mhz benötigten zusätzlichen 70 Takten kannst Du natürlich 70 NOPs einfügen, wäre aber nicht sonderlich elegant :-). Also nehmen wir eine Schleife.

Der entsprechende Teil der MCS.LIB sieht dann so aus:


; MCS.LIB ANPASSUNG ------------------------------------------------------------

; FÜR 8 MHZ

_pulse_in5:
@genus(9) ; Sorgt für 9 µS Wartezeit und wird
; von Bascom nach $Crystal berechnet

; Warteschleife für die restliche µS (insgesamt 80 Takte)
push r17 ; 2 Zyklen

ldi R17, $16 ; warte 66 Zyklen
warte0:
dec R17
brne warte0
pop r17 ; 2 Zyklen

Ld r0,z ; 2 cycl. get pin state
And r0, r24 ; 1 cycl. get only the input pin state
Eor r0,r16 ; 1 cycl. xor with begin state
Brne _pulse_in_exit ; 2 cycl. ready ,state changed
Adiw xl,1 ; 2 cycl. counter
brne _pulse_in5 ; 2 cycl. again
;-------------------------------------------------------------------------------


Nach der Änderung noch von Bascom die Lib in die .lbx kompilieren lassen... fertig.

Grüße
Henrik

Dirk
08.05.2006, 21:23
Hallo Henrik,

danke für die prompte Hilfe!
Ich probier's gleich aus!

Gruß Dirk

Dirk
09.05.2006, 19:34
Hallo Henrik,

vielleicht kannst du mir noch einmal helfen:

Ich habe mcs.lib jetzt so geändert:

......
_pulse_in5:
@genus(9) ; This For 10 Us Units But Approx. Depends On Xtal

; you can remove the above call and tailor this routine
; when remarked 10 cycles/ loop are needed and for 1 Mhz this is 10 uS
; for 4 MHz you need additional 30 cycles and the @genus can be used

; routine adapted for 8 MHz:
Push r17 ; 2 cycl.
Ldi r17,$16 ; waiting 66 cycl.
_pulse_in6:
Dec r17
brne _pulse_in6
Pop r17 ; 2 cycl.

Ld r0,z ; 2 cycl. get pin state
And r0, r24 ; 1 cycl. get only the input pin state
Eor r0,r16 ; 1 cycl. xor with begin state returns zero if the same
Brne _pulse_in_exit ; 2 cycl. ready ,state changed
Adiw xl,1 ; 2 cycl. counter
brne _pulse_in5 ; 2 cycl. again
_pulse_in_timeout:
.......

Das wird auch fehlerfrei zu mcs.lbx kompiliert, aber das Basic Programm meldet dann beim Kompilieren diverse Fehler (z.B. "ASM mnemonic not found [#ENDIF]". Ich habe sicher nichts weiter in der mcs.lib (1.11.7.6) verändert.
Nehme ich wieder die alte mcs.lib, wird das Basic Programm fehlerfrei kompiliert.
Woran kann das liegen?

Gruß Dirk

hrei
09.05.2006, 20:52
Hallo Dirk,

nicht gut, daß das Fehler ergibt, gut, daß Du Dich nochmal meldest.

Mir sind bei meinem "aus dem Gedächtnisgeschreibsel" nach Überprüfung folgende Abweichungen zu meiner in Betrieb befindlichen LIB aufgefallen:

1) ich habe das Label warte0 mit einem führenden Unterstrich verziert.

2)@genus hatte ich auskommentiert, weil die 80 Takte bei 8 MHz ja schon 10 µS Wartezeit entsprechen. Das haut dann auch hin.

Mein Kurztestprogramm:


$regfile = "m8def.dat"
'$regfile = "m168def.dat"
'$regfile = "m32def.dat"
$crystal = 7372800
'$crystal = 14745600
'$crystal = 16000000

$baud = 9600

$hwstack = 64
$swstack = 64
$framesize = 64

Config Pind.3 = Input

Dim Value0 As Word

'-------------------------------------------------------------------------------

Do
Pulsein Value0 , Pind , 3 , 0 'detect time from 0 to 1
Loop

End


kompiliert mit dieser LIB Änderung:


_pulse_in5: ; FÜR 7.3xx MHZ ------------------
; @genus(9)

; Warteschleife für insgesamt 73 Takte)
push r17 ; 2 Zyklen -------------------

; warte 57 Zyklen:
ldi R17, $13
_warte0:
dec R17
brne _warte0
; ----------------------------- 63 Zyklen
; warte 2 Zyklen:
nop
nop
; =============================
pop r17 ; 2 Zyklen ------------------

Ld r0,z ; 2 cycl. get pin state
And r0, r24 ; 1 cycl. get only the input pin state
Eor r0,r16 ; 1 cycl. xor with begin state
Brne _pulse_in_exit ; 2 cycl. ready ,state changed
Adiw xl,1 ; 2 cycl. counter
brne _pulse_in5 ; 2 cycl. again

_pulse_in_timeout:
call _Set_Error ; set error because of time out
_pulse_in_exit:
; X holds timing
Mov r24,XL ; store data here
Mov R25,XH

Ret
[END]


völlig fehlerfrei. (Bascom V1.11.8.2)

Versuche es nochmal, wenn es dann noch nicht klappt, fällt mir schon noch was ein :-).

Grüße
Henrik

Dirk
09.05.2006, 21:59
Hallo Henrik,

habe das jetzt auch so geändert:
Mein neues Label _pulse_in6 probeweise in _warte0 umbenannt und @genus auskommentiert.

Leider die gleichen Fehlermeldungen. Bascom auch 1.11.8.2.

Noch eine Idee?

Gruß Dirk

hrei
10.05.2006, 15:19
Hallo Dirk,

hmm... seltsam. Die Fehlermeldung deutet darauf hin, daß Dir doch irgendwo ein Zeichen vor einem (Basic-)Befehl in der Lib abhanden gekommen ist. So etwas bekomme ich, wenn ich z.B. mal wieder das Sternchen vor einer Präprozessoranweisung vergessen habe.

Vorschlag: Ich sende Dir eine bei mir funktionierende, für 8MHz kompilierte MCS.Lib per Mail zu. Öffentlich darf ich das nicht, von registriertem Anwender zu registriertem Anwender sollte das aber nicht zu bemängeln sein.

Dürfte der einfachste und schnellste Weg sein. Nur Deine Mail Adresse bräuchte ich dafür natürlich (meine steht im Profil).

Grüße
Henrik