PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Attiny 2313 BCD Eingang und Stromstoßschaltung Ausgang



baschdi1649
02.08.2011, 14:53
Hallo Leute,
ich will mich noch kurz vorstellen, da ich neu hier im Board bin.
Nun zu meinem Problem:
Ich habe hier einen DTMF Dekoder (MT8870). Dieser gibt die DTMF Töne als BCD aus.
Da ich mir einen BCD zu Dezimaldekoder sparen möchte will ich das ganze mit dem Attiny 2313 erledigen.
Dazu kommt noch, dass die Ausgänge getoggelt werden sollen.
Ich habe das Problem, dass der Attiny in der Schaltung nicht vom 0 auf 1 Zustand schaltet. Egal welche Zahl ich dem DTMF Dekoder vorgebe.
Das Signal liegt aber bei jeder Zahl am Attiny an.
Hier der geschriebene Quellcode:


$regfile = "attiny2313.dat"
$crystal = 8000000

Config Portd.0 = Input 'für die BCD Eingänge
Config Portd.1 = Input 'für die BCD Eingänge
Config Portd.2 = Input 'für die BCD Eingänge
Config Portd.3 = Input 'für die BCD Eingänge

Config Portd.4 = Output
Config Portd.5 = Output
Config Portb.7 = Output
Config Portb.6 = Output
Config Portb.5 = Output
Config Portb.4 = Output
Config Portb.3 = Output
Config Portb.2 = Output
Config Portb.1 = Output
Config Portb.0 = Output
Config Portd.6 = Output

Const 1 = &B0001 'BCD Code für 1, usw.
Const 2 = &B0010
Const 3 = &B0011
Const 4 = &B0100
Const 5 = &B0101
Const 6 = &B0110
Const 7 = &B0111
Const 8 = &B1000
Const 9 = &B1001
Const S = &B1011 'BCD Code für Stern
Const R = &B1100 'BCD Code für Raute

Portd.4 = 0 'Ausgänge auf GND
Portd.5 = 0
Portb.7 = 0
Portb.6 = 0
Portb.5 = 0
Portb.4 = 0
Portb.3 = 0
Portb.2 = 0
Portb.1 = 0
Portb.0 = 0
Portd.6 = 0


S_ausgang Alias Portd.4 'Ausgang für Stern
R_ausgang Alias Portd.5 'Ausgang für Raute
1_ausgang Alias Portb.7 'Ausgang für 1, usw.
2_ausgang Alias Portb.6
3_ausgang Alias Portb.5
4_ausgang Alias Portb.4
5_ausgang Alias Portb.3
6_ausgang Alias Portb.2
7_ausgang Alias Portb.1
8_ausgang Alias Portb.0
9_ausgang Alias Portd.6

Do

If Portd = 1 Then
Toggle 1_ausgang
Waitms 200
End If

If Portd = 2 Then
Toggle 2_ausgang
Waitms 200
End If

If Portd = 3 Then
Toggle 3_ausgang
Waitms 200
End If

If Portd = 4 Then
Toggle 4_ausgang
Waitms 200
End If

If Portd = 5 Then
Toggle 5_ausgang
Waitms 200
End If

If Portd = 6 Then
Toggle 6_ausgang
Waitms 200
End If


If Portd = 7 Then
Toggle 7_ausgang
Waitms 200
End If


If Portd = 8 Then
Toggle 8_ausgang
Waitms 200
End If


If Portd = 9 Then
Toggle 9_ausgang
Waitms 200
End If


If Portd = S Then
Toggle S_ausgang
Waitms 200
End If


If Portd = R Then
Toggle R_ausgang
Waitms 200
End If

Loop

End

Ich hoffe, dass mir jemand helfen kann.;)

da_reefer
02.08.2011, 17:39
Hallo,

Da der PortD teilweise auch als Ausgang konfiguriert ist vermute ich hier den Fehler... Versuche mal den Port vor der Abfrage zu maskieren, zb. so:



Dim MaskedPort as Byte
...
MaskedPort = Portd And &b00001111
If MaskedPort = S Then
...

mfg

Besserwessi
02.08.2011, 17:59
Das Signal von Eingängen an Port d fragt man über das Register Pind ab, nicht über Portd. Portd ist für das Ausgangssignal bzw. zum Aktivieren von Pullups.

Beschwert sich der der Compiler nicht über Definitionen wie
Const 1 = &B0001 'BCD Code für 1, usw.

da_reefer
02.08.2011, 18:28
Hallo,

Pind, natürlich :)
Der Compiler meckert zwar nicht bei dieser Konstantendefinition, scheint ihn intern aber doch durcheinanderzubringen.
Ist so aber auf jeden Fall eine sehr potente Fehlerquelle, da würde ich einen Präfix dazuschreiben, zb. Const Bcd_1 = &B0001

mfg

baschdi1649
03.08.2011, 10:39
hi,
ich probiere das, wie da_reefer meinte, mit maskedport aus. Jedoch verstehe ich das nicht ganz.


Dim MaskedPort as Byte
...
MaskedPort = Pind And &b00001111
If MaskedPort = S Then
...

ich muss dim maskedport as byte nur einmal erwähnen.
Dann MaskedPort = Pind And &b00001111 so abändern, dass da wo die 4 Einsen sind die BCD Codes hinkommen. Also so etwa?

Dim Maskedport As Byte

Maskedport = Pind And &B00000001
Maskedport = Pind And &B00000010
Maskedport = Pind And &B00000011
Maskedport = Pind And &B00000100
Maskedport = Pind And &b00000101
Maskedport = Pind And &B00000110
Maskedport = Pind And &B00000111
Maskedport = Pind And &B00001000
Maskedport = Pind And &B00001001
Maskedport = Pind And &B00001011
Maskedport = Pind And &B00001100

aber wo werden dann die BCD Namen verteilt, wie 1, 2, 3, 4, ..., s, r?
Oder stehe ich aufem Schlauch ;)?
gruß baschdi1649

radbruch
03.08.2011, 11:48
Hallo

BCD-Namen sind unsinnig, weil BCD ja lediglich bedeutet, dass die Ziffern 0 bis 9 in jeweils einem Nipple dargestellt werden. Deshalb würde ich es einfach so lösen:

$regfile = "attiny2313.dat"
$crystal = 8000000

Config Portd.0 = Input 'für die BCD Eingänge
Config Portd.1 = Input 'für die BCD Eingänge
Config Portd.2 = Input 'für die BCD Eingänge
Config Portd.3 = Input 'für die BCD Eingänge

Dim Bcd_input As Byte

S_ausgang Alias Portd.4 'Ausgang für Stern
R_ausgang Alias Portd.5 'Ausgang für Raute
1_ausgang Alias Portb.7 'Ausgang für 1, usw.
2_ausgang Alias Portb.6
3_ausgang Alias Portb.5
4_ausgang Alias Portb.4
5_ausgang Alias Portb.3
6_ausgang Alias Portb.2
7_ausgang Alias Portb.1
8_ausgang Alias Portb.0
9_ausgang Alias Portd.6

Config S_ausgang = Output
Config R_ausgang = Output
Config 1_ausgang = Output
Config 2_ausgang = Output
Config 3_ausgang = Output
Config 4_ausgang = Output
Config 5_ausgang = Output
Config 6_ausgang = Output
Config 7_ausgang = Output
Config 8_ausgang = Output
Config 9_ausgang = Output

'Const 1 = &B0001 'BCD Code für 1, usw.
'Const 2 = &B0010
'Const 3 = &B0011
'Const 4 = &B0100
'Const 5 = &B0101
'Const 6 = &B0110
'Const 7 = &B0111
'Const 8 = &B1000
'Const 9 = &B1001
'Const S = &B1011 'BCD Code für Stern
'Const R = &B1100 'BCD Code für Raute

Declare Sub All_leds_off
All_leds_off

Do

Bcd_input = Pind And 15 'nur die Bits 0 bis 3 beachten

Select Case Bcd_input
Case 0 : All_leds_off
Case 1 : Toggle 1_ausgang
Case 2 : Toggle 2_ausgang
Case 3 : Toggle 3_ausgang
Case 4 : Toggle 4_ausgang
Case 5 : Toggle 5_ausgang
Case 6 : Toggle 6_ausgang
Case 7 : Toggle 7_ausgang
Case 8 : Toggle 8_ausgang
Case 9 : Toggle 9_ausgang
Case 11 : Toggle S_ausgang
Case 12 : Toggle R_ausgang
End Select

Waitms 200

Loop

End

Sub All_leds_off
S_ausgang = 0
R_ausgang = 0
1_ausgang = 0
2_ausgang = 0
3_ausgang = 0
4_ausgang = 0
5_ausgang = 0
6_ausgang = 0
7_ausgang = 0
8_ausgang = 0
9_ausgang = 0
End Sub
Das ist allerdings ungetestet.

Allerdings ist die direkte Abfrage der Eingangspins kritisch, weil die Pins nie gleichzeitig ihre Pegel wechseln, bzw. erreichen. Deshalb verwendet man bei parallelen Schnittstellen wenigstens ein Gültig-Signal an dem der lesende Partner erkennt, dass alle Datenpins stabile Spannungen haben:

' Pseudocode für Sender
set_bcd_daten
waitms 10 ' warten bis alle Pegel passen
set_bcd_gültig
waitms 300 ' warten bis mindestens einmal gelesen wurde
unset_bcd_gültig
waitms 10 ' warten bis lesen wirklich beendet ist
unset_bcd_daten

' Code für Empfänger:
if bcd_gültig then Bcd_input = Pind And 255


Gruß

mic

[Edit]
Das Gültig-Signal beim MT8870 heißt vermutlich StD:


Q1-Q4 4-BIT DECODED TONE OUTPUT.
StD DELAYED STEERING OUTPUT. INDICATES THAT VALID FREQUENCIES HAVE BEEN PRESENT/ABSENT FOR THE REQUIRED
GUARD TIME THUS CONSTITUTING A VALID SIGNAL.
19544

Sauerbruch
03.08.2011, 11:58
Oder stehe ich aufem Schlauch :wink:?

Ein bisschen, aber das kriegen wir hin ;-)

Die Idee mit dem "Maskieren" beruht auf folgendem Ansatz:

Wenn X ein Bit ist (also die Werte 0 oder 1 annehmen kann), dann gilt folgendes:

X AND 0 = 0 (egal welchen Wert X hat: Eine "und"-Verknüpfung mit 0 ergibt immer 0)
X AND 1 = X (0 AND 1 = 0, 1 AND 1 = 1)

Wenn Du also folgenden Befehl ausführst:

Byte = Byte AND &B00001111

dann werden die linken 4 Bits auf 0 gesetzt, während die rechten 4 Bits ihren Wert unverändert beibehalten. Logisch, oder?

Und darauf bezog sich auch die Antwort von da_reefer: Wenn der BCD-Wert an PIND.0-3 anliegt, Du aber den kompletten Port abfragst (Byte = PIND), könnte es theoretisch sein, dass die Bits PIND.4-7 das Byte verfälschen. Deshalb solltest Du sie sicherheitshalber mit dem AND &B00001111-Befehl löschen. Und der ist in der Tat nur ein mal erforderlich, und zwar nachdem Du den Wert von PIND in ein Byte übernommen hast.

baschdi1649
03.08.2011, 14:10
Der Quellcode von radbruch funktioniert einigermaßen. Jedoch benötigt der Microcontroller am Eingang ein Signal von ca. 2-4 Sekunden. Dann wird derjenige Anschluss geschaltet. Die Dauer des Signals am Ausgang hällt aber nur ca.4 Sekunden an. Weiß der Geier warum.:)

Zur Erklärung von Sauerbruch:
Müsste ich dann zwischen meinen geschriebenen Quellcode
Config Portd.6 = Output

Const 1 = &B0001 'BCD Code für 1, usw. reinschreiben:

Config Portd.6 = Output

Dim MaskedPort as Byte
MaskedPort = Portd And &b00001111 'oder 15

Const 1 = &B0001 'BCD Code für 1, usw.
oder?
mfg
baschdi1649

radbruch
03.08.2011, 14:25
MaskedPort = Pind And &b00001111 'oder 15

Läuft dein Tiny wirklich mit 8MHz?


Dim Bcd_input As Byte , Bcd_input_old As Byte

Declare Sub All_leds_off
All_leds_off
Bcd_input_old = 0

Do

Do
Bcd_input = Pind And 255 'nur die Bits 0 bis 3 beachten
Loop Until Bcd_input <> Bcd_input_old

Select Case Bcd_input
Case 10 : All_leds_off '10 ist Ziffer "0"
Case 1 : Toggle 1_ausgang
Case 2 : Toggle 2_ausgang
Case 3 : Toggle 3_ausgang
Case 4 : Toggle 4_ausgang
Case 5 : Toggle 5_ausgang
Case 6 : Toggle 6_ausgang
Case 7 : Toggle 7_ausgang
Case 8 : Toggle 8_ausgang
Case 9 : Toggle 9_ausgang
Case 11 : Toggle S_ausgang
Case 12 : Toggle R_ausgang
End Select

Bcd_input_old = Bcd_input

'Waitms 200

Loop

End

baschdi1649
03.08.2011, 15:28
In dem einen Buch "Einfacher Einstieg in die Elektronik mit AVR..." steht hinten unter Attiny 2313 "Default-Takt: 8,00 MHz/8=1MHz.
Ich dachte dann nehme ich 8MHz. Was würdet ihr nehmen?
Danke für den Quelltext. Werde ihn später ausprobieren da momentan ein Gewitter bevorsteht :)

baschdi1649
03.08.2011, 16:57
Hi,
ich hab den Quelltext ausprobiert. Konnte ihn aber nicht richtig testen, da ich ein anderes Problem habe.
Die LEDs an den Ausgängen flackern ständig. Einmal werden sie hell einmal dunkel. Dann nur die Eine dann die Andere.
Dann binn ich hingegangen und habe in den Quelltext umgeändert und den Pullup Widerstand aktiviert. Den hab ich direkt unter die Input Definition der BCD Eingängen geschrieben. Das Flackern war weg, aber beim Anlegen eines Signals haben die LEDs aber nicht geschaltet:confused:
Woran kann das liegen?

radbruch
03.08.2011, 17:36
Hallo

Bitte entschuldige, aber den letzten Quellcode habe ich nicht richtig durchdacht und leider auch nur hingeschleudert (Pind and 255?). Ich glaube, ohne Auswertung von StD wird das nicht funktionieren, weil der MT8870 zwischen den Tönen die Pegel nicht hält. Hier hilft mein theoretisches Programmieren offensichtlich nicht weiter.

Für einen schnellen Test könntest du mal den StD-Ausgang des MT8870 auf PD3 legen (Q4 hängt dann frei):

$regfile = "attiny2313.dat"
$crystal = 1000000 ' default für Tiny 2313

Config Portd.0 = Input 'für die BCD Eingänge
Config Portd.1 = Input 'für die BCD Eingänge
Config Portd.2 = Input 'für die BCD Eingänge
Config Portd.3 = Input 'Eingang StD

S_ausgang Alias Portd.4 'Ausgang für Stern
R_ausgang Alias Portd.5 'Ausgang für Raute
1_ausgang Alias Portb.7 'Ausgang für 1, usw.
2_ausgang Alias Portb.6
3_ausgang Alias Portb.5
4_ausgang Alias Portb.4
5_ausgang Alias Portb.3
6_ausgang Alias Portb.2
7_ausgang Alias Portb.1
8_ausgang Alias Portb.0
9_ausgang Alias Portd.6


Config S_ausgang = Output
Config R_ausgang = Output
Config 1_ausgang = Output
Config 2_ausgang = Output
Config 3_ausgang = Output
Config 4_ausgang = Output
Config 5_ausgang = Output
Config 6_ausgang = Output
Config 7_ausgang = Output
Config 8_ausgang = Output
Config 9_ausgang = Output

Dim Bcd_input As Byte

Declare Sub All_leds_off
All_leds_off
Bcd_input = 0

Do
If Pind.3 = 1 Then 'PD3 ist Std, gesetzt wenn Daten bereit
Bcd_input = Pind And 7 'nur die Bits 0 bis 2 beachten
While Pind.3 = 1 ' warten bis StD wieder low ist
Wend
End If

Select Case Bcd_input
Case 1 : Toggle 1_ausgang
Case 2 : Toggle 2_ausgang
Case 3 : Toggle 3_ausgang
Case 4 : Toggle 4_ausgang
Case 5 : Toggle 5_ausgang
Case 6 : Toggle 6_ausgang
Case 7 : Toggle 7_ausgang
'(
Case 8 : Toggle 8_ausgang
Case 9 : Toggle 9_ausgang
Case 10 : All_leds_off '10 ist Ziffer "0"
Case 11 : Toggle S_ausgang
Case 12 : Toggle R_ausgang
')
End Select

Waitms 200
Loop

End

Sub All_leds_off
S_ausgang = 0
R_ausgang = 0
1_ausgang = 0
2_ausgang = 0
3_ausgang = 0
4_ausgang = 0
5_ausgang = 0
6_ausgang = 0
7_ausgang = 0
8_ausgang = 0
9_ausgang = 0
End Sub
Die Megas und Tinies werden defaultmässig mit internem Takt /8 ausgeliefert, das sollte dann 1MHz (1,2 MHz beim Tiny13) entsprechen. Waitms funktioniert nur richtig, wenn $crystal richtig angegeben ist ($crystal ändert nicht die Fuses!). Deshalb ist das waitms 200 kritisch, weil möglicherweise das StD zu kurz gesetzt wird und dein Tiny währenddessen in der Wait-Schleife hängt. Da hilft nur eins: Versuch macht kluch :)

Wenn's funktioniert wäre es clever, wenn du StD auf einen interruptfähigen Eingang (INTx) legen würdest.

Gruß

mic

[Edit]
Der Standartspruch im Datenblatt des 2313 unter "Default Clock Source":

The device is shipped with CKSEL = “0100”, SUT = “10”, and CKDIV8 programmed.
The default clock source setting is the Internal RC Oscillator with longest start-up time
and an initial system clock prescaling of 8. This default setting ensures that all users can
make their desired clock source setting using an In-System or Parallel programmer.Wobei CKSEL = “0100” eben "Calibrated internal RC Oscillator 8MHz" bedeutet und zusammen mit dem aktivierten "clock prescaling of 8" dein Tiny wohl mit 1MHz rennt.

[Edit2]
Ups, der 2313 hat gar nicht soviele Pins wie erwartet. Zufällig ist PD3 auch INT1, deshalb müsste Q4 dann auf PA0 oder PA1 gelegt werden, wenn man das Std-Signal per Pinchange-Interrupt abfragen möchte. Bei internem Takt sollten diese zwei Pins frei nutzbar sein, aber das weiß ich nicht sicher.

Ungetesteter Code mit Q4 an PA0 und StD an PD3, Auswertung per Int1-Interrupt:

$regfile = "attiny2313.dat"
$crystal = 1000000

Config Portd.0 = Input 'für die BCD Eingänge
Config Portd.1 = Input 'für die BCD Eingänge
Config Portd.2 = Input 'für die BCD Eingänge
Config Porta.0 = Input 'für die BCD Eingänge PA0 ???
Config Portd.3 = Input 'Eingang StD

S_ausgang Alias Portd.4 'Ausgang für Stern
R_ausgang Alias Portd.5 'Ausgang für Raute
1_ausgang Alias Portb.7 'Ausgang für 1, usw.
2_ausgang Alias Portb.6
3_ausgang Alias Portb.5
4_ausgang Alias Portb.4
5_ausgang Alias Portb.3
6_ausgang Alias Portb.2
7_ausgang Alias Portb.1
8_ausgang Alias Portb.0
9_ausgang Alias Portd.6


Config S_ausgang = Output
Config R_ausgang = Output
Config 1_ausgang = Output
Config 2_ausgang = Output
Config 3_ausgang = Output
Config 4_ausgang = Output
Config 5_ausgang = Output
Config 6_ausgang = Output
Config 7_ausgang = Output
Config 8_ausgang = Output
Config 9_ausgang = Output

Config Int1 = Rising
On Int1 Int1_isr
Enable Int1
Enable Interrupts

Dim Bcd_input As Byte

Declare Sub All_leds_off
All_leds_off
Bcd_input = 0

Do
Select Case Bcd_input
Case 1 : Toggle 1_ausgang
Case 2 : Toggle 2_ausgang
Case 3 : Toggle 3_ausgang
Case 4 : Toggle 4_ausgang
Case 5 : Toggle 5_ausgang
Case 6 : Toggle 6_ausgang
Case 7 : Toggle 7_ausgang
Case 8 : Toggle 8_ausgang
Case 9 : Toggle 9_ausgang
Case 10 : All_leds_off '10 ist Ziffer "0"
Case 11 : Toggle S_ausgang
Case 12 : Toggle R_ausgang
End Select

Waitms 200
Loop

End

Int1_isr:
Bcd_input = Pind And 7 'nur die Bits 0 bis 2 beachten
If Pina.0 = 1 Then Bcd_input = Bcd_input + 8 ' PA0 ist Q4
Return

Sub All_leds_off
S_ausgang = 0
R_ausgang = 0
1_ausgang = 0
2_ausgang = 0
3_ausgang = 0
4_ausgang = 0
5_ausgang = 0
6_ausgang = 0
7_ausgang = 0
8_ausgang = 0
9_ausgang = 0
End SubWenn das funktioniert könnte man noch die "0" auf PA1 legen... *träum*

Besserwessi
03.08.2011, 19:44
Wenn man den internen Takt nutzt, kann man die Pins, die sonst für den Quarz sind, normal nutzen. Man hat dann also 17 IO Pins zur Verfügung. Nur die beiden Pins für die Versorgung gehen nicht und den Reset Pin sollte man nicht nutzen, das geht aber mit viel Aufwand (HV Programmierung) auch.

baschdi1649
03.08.2011, 20:12
ok,
ich kann dir nicht ganz folgen aber etwas komm ich nach. :-)
Es ist nur so, dass ich StD mit TOE verbunden habe. Dadurch werden die Zahlen nur für etwa eine halbe Sekunde ausgegeben.
Das mit dem StD am Tiny probier ich jetzt mal aus.
Melde mich dann später!
Danke für die vielen Infos!

baschdi1649
04.08.2011, 18:52
hi,
der Quellcode hat leider nicht funktioniert.
Ich bin einfach hingegangen und habe einen BCD Dezimaldecoder hinter den DTMF IC (MT8870) geschaltet, Parallel dazu noch 4 LEDs, damit man sehen kann, wann die BCD Signale rauskommen. Dann habe ich hinter den BCD Dezimaldecoder den Attiny 2313 gemacht. Und an die Ausgänge des Attiny 2313 habe ich einen ULN 2803 geschaltet.
Den Quellcode habe ich mal selbst geschrieben, ist sehr simpel und sieht folgender Maßen aus:

$regfile = "attiny2313.dat"
$crystal = 1000000

Config Portd.0 = Input
Config Portd.1 = Input
Config Porta.1 = Input
Config Porta.0 = Input
Config Portd.2 = Input
Config Portd.3 = Input
Config Portd.4 = Input
Config Portd.5 = Input

Taster_1 Alias Pind.0
Taster_2 Alias Pind.1
Taster_3 Alias Pina.1
Taster_4 Alias Pina.0
Taster_5 Alias Pind.2
Taster_6 Alias Pind.3
Taster_7 Alias Pind.4
Taster_8 Alias Pind.5


Config Portb.7 = Output
Config Portb.6 = Output
Config Portb.5 = Output
Config Portb.4 = Output
Config Portb.3 = Output
Config Portb.2 = Output
Config Portb.1 = Output
Config Portb.0 = Output

LED_1 Alias Portb.7
LED_2 Alias Portb.6
LED_3 Alias Portb.5
LED_4 Alias Portb.4
LED_5 Alias Portb.3
LED_6 Alias Portb.2
LED_7 Alias Portb.1
LED_8 Alias Portb.0

LED_1 = 0
LED_2 = 0
LED_3 = 0
LED_4 = 0
LED_5 = 0
LED_6 = 0
LED_7 = 0
LED_8 = 0



Do

Waitms 200

If Taster_1 = 1 Then
Toggle LED_1
Waitms 200
End If

If Taster_2 = 1 Then
Toggle LED_2
Waitms 100
End If

If Taster_3 = 1 Then
Toggle LED_3
Waitms 100
End If

If Taster_4 = 1 Then
Toggle LED_4
Waitms 100
End If

If Taster_5 = 1 Then
Toggle LED_5
Waitms 100
End If

If Taster_6 = 1 Then
Toggle LED_6
Waitms 100
End If

If Taster_7 = 1 Then
Toggle LED_7
Waitms 100
End If

If Taster_8 = 1 Then
Toggle LED_8
Waitms 100
End If

Loop

End

Danke euch vielmals für die Hilfe!:)