PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Interrupt und PCF8574



RHS
01.11.2005, 21:03
Hallo,

ich habe den Interrupt-Ausgang eines PCF 8574 mit INT5 (PE.5)
eines Mega128 verbunden. Am PCF 8574 sind Taster gegen
Masse angeschlossen.

Ich möchte nun in Bascom eine Interrupt-Routine anspringen und
dort abfragen, welche Taster gedrückt sind.


Config Int5 = FALLING
On Int5 PCF_Key

Enable Interrupts
Enable Int5

Do
'irgendwas
Loop

PCF_Key:
Print "Taster gedrückt"
Return


Mein Problem ist, dass das Interrupt-Label immer/ständig
angesprungen wird. Wie macht man das richtig?

Danke: - Reinhard -

linux_80
01.11.2005, 21:07
Hallo,
hast Du überall Pullup Widerstände drin (bei INT und Tastern), damit keine Signale ins flattern kommen?

RHS
01.11.2005, 23:26
@linux_80

PullUp's sind bei den Tastern dran. Wie soll ich das beim INT
machen?

Ich habe gerade noch mal gemessen: wenn ich einen Taster
drücke, wird der INT-Ausgang vom PCF auf low (0) gezogen.
Ich kann das Signal aber beim M128 nicht auswerten ...

Gruß: - Reinhard -

linux_80
02.11.2005, 00:39
im DB unter 7.2 ist es auch dargestellt, Fig.12
Die Tasten werden dann auch noch prellen,
wenn nix gedrückt wird sollte zumindest kein INT ausgelöst werden.

Wenn der M128 beim INT auf falling reagiert, sollte das schon mal dir richtige Richtung sein.

PicNick
02.11.2005, 09:04
der INT -ausgang ist open-drain, verständlicherweise. Hast du das berücksichtigt ?

RHS
02.11.2005, 17:56
@PicNick

was sagt mir das genau?

Ich habe jetzt den PullUp beim INT installiert (10K gegen VCC) und
es läuft immer noch nicht ...

Was muss ich noch einstellen, damit der M128 das Signal auswerten
kann?

Gruß: - Reinhard -

PicNick
02.11.2005, 18:11
Ist der INT-Pin am 128-er als Input definiert ? Ich kann in den diversen Beschreibungen nicht entnehmen, ob das automatisch mit der Interrupt-definition geschieht.

was sagt mir das genau?
--> Pullup. Hat sich aber eledigt, seh ich.

RHS
02.11.2005, 20:40
@PicNick

Den INT-Pin am M128 habe ich nicht explizit als Eingang definiert.

Der folgende Code läuft fast richtig:


' TestInt5.bas
' ------------
' PCF 8574 : P0 <- Taster gegen GND
' P4 -> grüne LED -> R -> VCC
' P5 -> gelbe LED -> R -> VCC
' P5 -> rote LED -> R -> VCC
' INT -> 10K -> VCC
'
' M128 :PE5 (INT5) <- CD4050 <- INT von PCF8574


$regfile = "m128def.dat"

$hwstack = 64
$framesize = 64
$swstack = 64
$crystal = 16000000 'Quarzfrequenz 16 MHz

$baud = 19200 'Baudrate COM1
$baud1 = 19200 'Baudrate COM2

Const PCF_Adr = &H40

Dim PCF_Port As Byte
Dim B As Byte


Dim i As Integer

Config Sda = Portd.1
Config Scl = Portd.0


I2cinit 'I2C-Bus initialisieren
Waitms 250


'1.Hardware UART
'keine Definition notwendig (Ausgaben mit einfachem Print möglich)

'2.Hardware UART
Open "Com2:" For Binary As #1


'alle LED's aus (invertiertes Schalten)
PCF_Port = &B11111111
I2CSend PCF_Adr , PCF_Port


Config Int5 = Rising
On Int5 INT5_ISR
Enable Interrupts
Enable Int5


i = 0


Print #1 , "Start ..."


Do

Print #1 , i ; "->" ; Bin(PCF_Port)

'Tastenstatus lesen
I2CReceive PCF_Adr , PCF_Port

'gelbe LED an Port P5 einschalten
PCF_Port.5 = 0
I2CSend PCF_Adr , PCF_Port

Waitms 250

'grüne LED an Port P4 einschalten
PCF_Port.4 = 0
I2CSend PCF_Adr , PCF_Port

Waitms 250

'gelbe & grüne LED aus
PCF_Port.5 = 1
PCF_Port.4 = 1
I2CSend PCF_Adr , PCF_Port

Waitms 500

Loop


Close #1


End


'Service-Routine für INT5
INT5_ISR:

Incr i

'Tastenstatus lesen, mit entprellen
I2CReceive PCF_Adr , PCF_Port
Waitms 50
I2CReceive PCF_Adr , B

If PCF_Port.0 = B.0 then
'rote LED an Port P6 umschalten
Toggle PCF_Port.6
I2CSend PCF_Adr , PCF_Port
End if

Return


Fast deshalb, weil nach ein paar Tastendrücken der Port 0 des
PCF8574 (also der Port, wo der Taster angeschlossen ist) immer
auf 0 stehen bleibt ... also kein Interrupt mehr ausgelöst wird.

Grundsätzlich kann' s doch nicht so schwer sein ... :-(. Kann jemand
vielleicht noch mal über den Code schauen?

Gruß: - Reinhard -

PicNick
03.11.2005, 06:27
Was den INT betrifft, seh ich da nix Böses.

Äh, mir fällt ein, daß BasCom in der 1.117.4 Version Probleme mit den Interrupts hatte. Du hast ja wenigstens 1.11.7.8 oder 9 ?

linux_80
03.11.2005, 17:04
und sollte der INT nicht auf falling reagieren !?
Wir wärs, als hätte ich in so'nem Datenblatt was davon gelesen !

PicNick
03.11.2005, 18:36
Der Mega kann das schon. Nur in der .4 Version vom Bascom wurden die entsprechenden Flags nicht richtig gesetzt. Wenn das bei dir so ist, mußt du NACH dem config.. falling selbst die "falling/rising" bits lt. Datasheet setzen.

Überprüf es einfach im Simulator. der Config ist ja eh' ganz vorne.

linux_80
03.11.2005, 19:07
@PicNick,
ich mein ja nicht wegen dem Mega, sondern wegen dem PCF sollte man auf falling reagieren,
rising macht der INT ja erst wenn man den PCF dann ausliest.
oder... :-k

RHS
03.11.2005, 19:25
Hallo PicNick & linux_80,

ich habe die aktuelle Bascom-Version (.9). Mit "Falling" hat der
Interrupt nicht funktioniert. Hatte ich erst, siehe ganz oben ...

Was ich nicht verstehe ist, dass das Taster-Bit auf 0 geht und
da bleibt ... es sei denn, ich setzt das Bit einfach wieder auf 1.
Aber das kann's ja wohl nicht sein ...

Kann das vielleicht ein Timing-Problem sein? Bei mir ist es so,
das zwischen M128 und dem PCF8574 (derzeit noch auf Test-
board) ein 1m langes, geschirmtes Netzwerk-Patchkabel ver-
legt ist.

Andererseits habe ich auch schon Frank's RN-KeyLCD per I2C
und dem gleichen Kabel betrieben. Das funktionierte einwand-
frei.

Schon komisch das ganze ...

PicNick
03.11.2005, 19:34
Wir reden aneinander vorbei. Mit EINEM PCF ist natürlich "falling" angesagt. "rising" ist für dich nicht interessant.
Was ich meinte, ist, das der BasCom überhaupt probleme (hatte) irgendwas anderes als LOW-LEVEL zu setzen.

Für die INT0-3 hatt ich das damals überprüft. Deswegen mein' ich, du solltest sichergehen, ob der Bug noch besteht



2. INT3
ATMEGA128
There is a severe error in BasCom 1.11.7.8 with the setting of the sense-mode-Bits of INT3

2.1. Source

$crystal = 16000000
$regfile = "M128def.dat"

Config Int0 = Falling
Config Int1 = Rising
Config Int2 = Falling
Config Int3 = Falling

2.2. Disassembling

00C0 LDS r24,EICRA
00C4 ANDI r24,$FC ' 11111100 ISC01 ISC00
00C6 ORI r24,$02 ' 00000010 correct „falling edge“
00C8 STS EICRA,r24
‚------------------------------------------------------------

00CC LDS r24,EICRA
00D0 ANDI r24,$F3 ' 11110011 ISC11 ISC10
00D2 ORI r24,$0C ' 00001100 correct „rising edge“
00D4 STS EICRA,r24
‚------------------------------------------------------------

00D8 LDS r24,EICRA
00DC ANDI r24,$CF ' 11001111 ISC21 ISC20
00DE ORI r24,$20 ' 00100000 correct „falling edge“
00E0 STS EICRA,r24
‚------------------------------------------------------------

00E4 LDS r24,EICRA
00E8 ANDI r24,$3F ' 00111111 ISC30 ISC31

00EA ORI r24,$40 ' 01000000 ISC30 !

00EC STS EICRA,r24
‚------------------------------------------------------------

INT2, ISC20 is now correct (1.11.7.4 failed here)

For INT3, ISC30 has been set. This Mode is „reserved“

RHS
03.11.2005, 23:01
Hallo PicNick,

ich glaube mittlerweile auch, dass das Verhalten wohl ein Bug
in Bascom ist.

Ich habe jetzt "Falling" statt "Rising" genommen (wie es
auch korrekt ist, siehe Programm von gestern) und dabei
wird die Serviceroutine für INT5 genau 1-mal ausgeführt.

Mit INT4 exakt das gleiche Verhalten. Mir bleibt wohl nichts
anderes übrig, als die Tasten in einer Timer-Routine zu
prüfen ...

Gruß: - Reinhard -

PicNick
04.11.2005, 07:06
Wie gesagt, du kannst ja nach dem Config die Int-Register zu Fuß setzen.

RHS
04.11.2005, 13:59
@PicNick,

kannst Du mir dabei behilflich sein? Um die Register habe
ich bislang 'nen großen Bogen gemacht ... ;-).

Welche Register muß ich bedienen? Bzw. was "vergisst"
Bascom zu setzen?

Gruß: - Reinhard -

PicNick
04.11.2005, 14:13
Für INT4 bis INT7 ist "EICRB" zuständig

INT5 einstellen:
EICRB = EICRB AND &HF3 ' flags Löschen = low level

EICRB = EICRB OR &H08 ' Falling
oder
EICRB = EICRB OR &H0C ' rising
oder
EICRB = EICRB OR &H04 ' rising & falling

alles andere läßt du ganz normal den Bascom machen

RHS
04.11.2005, 19:35
Macht keinen Unterschied ...

Egal, ob per Config ... oder direktes setzen des EICRB-Registers:
der Interrupt wird einmal ausgeführt und das war's dann.

Wenn ich am Ende der Do ... Loop folgendes hinzufüge:


IF PCF_Port.0 = 0 Then
'Tastenstatus zurücksetzen
Set PCF_Port.0
I2CSend PCF_Adr , PCF_Port
End If

dann geht's. Finde ich schon mehr als seltsam.

Ich gehe den Aufbau noch mal durch:

- Taster an PCF8574 gegen Masse
- PullUp am INT-PCF gegen VCC
- Verbindung INT-PCF -> INT5-M128

Ist das so überhaupt richtig?

Gruß: - Reinhard -

PicNick
05.11.2005, 10:49
Der Taster am PCF hat aber schon auch einen Pullup ? Ich kann im DS keinen eingebauten erkennen.
Wie sind die andern PCF-I/O pins beschaltetet ?
Der Ablauf sollte der folgende sein:
1 PCF-Pins high oder low / INT5 Leitung high ---> Messen !
2 PCF Pin Änderung
3 INT5 -> LOW ---> Messen !
4 Interrupt
5 Read PCF-Pins
6 INT5 -> HIGH ---> Messen !
---> wieder bei State #1

Mach dein Programm so, daß du die jeweiligen Zustände stabil hältst und messen kannst.
d.h. zuerstmal machst enablest du keine Interrupts, dadurch kannst du bis #3 in Ruhe checken
Wenn es bis dahin paßt, enablest du und liest den PCF aus ---> check bis #6
In dieser Sequenz mußt du genau EINEN Interrupt haben.

Nu ?

RHS
06.11.2005, 18:29
@PicNick,

ich glaube, ich hab's. Mit folgender ISR-Routine funktioniert
es:


'Service-Routine für INT5
INT5_ISR:

'Tastenstatus lesen
I2CReceive PCF_Adr , PCF_Port

'prüfen, ob Taste gedrückt war
If PCF_Port.0 = 0 Then
'rote LED an Port P6 umschalten
Toggle PCF_Port.6
'Tastenstatus auf nicht gedrückt setzen,
'weil sonst INT5 nur ein einziges Mal
'ausgeführt wird!
PCF_Port.0 = 1
'Änderungen zum PCF8574 senden
I2CSend PCF_Adr , PCF_Port
End if

Return


Wenn ich PCF_Port.0 = 1 nicht drin habe, wird der Interrupt
bei Config Int5 = Falling nur ein einziges Mal ausgeführt!

Ich vermute, das liegt daran, das I2CSend eine Null auf
PCF_Port.0 zurückschreibt, obwohl in dem Moment die Taste
nicht mehr gedrückt und PCF_Port.0 = 1 ist.

Bzgl. Deiner Messanleitung: bei Schritt 3 geht der INT-Pin vom
PCF nur auf Low, wenn Config Int5 = Rising ist. Bei Falling tut
sich da überhaupt nix oder mein Meßgerät bekommt das nicht
mit. Könnte auch sein ...

D A N K E: - Reinhard -

PicNick
07.11.2005, 07:54
...bei Schritt 3 geht der INT-Pin vom PCF nur auf Low, wenn Config Int5 = Rising ist. Bei Falling tut sich da überhaupt nix .....
Das ist eigentlich seltsam, da ja der PCF-Chip nicht wissen kann, welche config-Bits im AVR gesetzt sind. Ich les mir jetzt nochmal genau die Int-Beschreibung des PCF durch. Wenn mir nach Mysterien zu Mute ist, schau ich mir einen Harry-Potter Film an. Bei der Elektronic schätze ich das überhaupt nicht.

RHS
07.11.2005, 21:35
@PicNick,

ja, ist schon sehr mysteriös ...

Kurz als Ergänzung: wenn ich den ganzen Interrupt-Kram auskommentiere,
dann geht auch der INT-Pin vom PCF auf Low ... Nur halt nicht, wenn der
M128 die Interrupts behandeln soll.

Viel Spaß bei Harry Potter ;-).

Gruß: - Reinhard -

PicNick
08.11.2005, 10:23
Vom PCF aus gesehen, ist das ok. Bei irgendeiner Flanke der Datenleitungen geht INT auf LOW, solange, bis der PCF gelesen oder geschrieben wird.

Ich les aber, eigentlich sollte man dem PCF erstmal lauter 1-er und dann 0-er reinschreiben, bevor man ihn als Input -Port verwendet (Seite 11, für mich im Moment ein wenig verwirrend).

Vorschlag Versuch:
Sende &HFF zum Pcf, dann &H00. (write-addr)
Und dann lies EINMAL das Port aus. (read-addr)
Und dann erst den Interrupt enablen.

Ich muß mal meine RNBFRA aktivieren und das mit dem Interrupt selber probieren, vielleicht werd' ich schlauer.


EDIT: Achja, Harry Potter: Solang' ich mit Robbies was zu tun hab, werd' ich wohl keinen Bedarf haben.