Archiv verlassen und diese Seite im Standarddesign anzeigen : 4x7 Seg. mit 3 Ader SW SPI, Einstieg mit BASCOM u. ATtiny45
Searcher
31.01.2011, 12:09
Hallo,
weil es mit µC viel einfacher ist um alle technischen Probleme zu lösen, konnte ich der Versuchung nicht standhalten :-) und hab mit µC Anwendung begonnen. Zum Einstieg in die Programmierung und als Übungsprojekt sollte zunächst mal eine 4 X 7 Segment low current LED Anzeige angesteuert werden.
Die Anzeige hat 11 Anschlüsse. Sieben zur Segmentansteuerung plus vier zur Ziffernaktivierung. Gemeinsame Anode pro Ziffer. Wenn man vier Ziffern gleichzeitig darstellen möchte, muß also gemultiplext werden.
Außerdem hat der vorhandene ATtiny45 nur fünf verwendbare Portpins, vom RESET Pin mal abgesehen, - ein Portexpander muß also auch noch her.
Über den RN-Wissen Artikel (http://www.rn-wissen.de/index.php/Portexpander_am_AVR) ist angehängte Schaltung und folgendes BASCOM Testprogramm entstanden (In der Schaltung sind Abblock- und Pufferkondensatoren nicht eingezeichnet, VCC=5V)
'################################################# ##
'File: schiebe.bas
'Tests on three wire software spi - output only
'on Displayunit: 4 X 7 segment low current LED
'HW circuit: ATtiny45_4_X_7_Segment_SPI
'################################################# ######
$regfile = "attiny45.dat"
$eepleave
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 1000000
Dim X As Byte
Dim Y As Byte
Dim Init7segment As Byte
Dim Dunkelziffer As Byte
Dim Displaydigit(16) As Byte 'darzustellende Zeichen (hex 0..F)
'0gfedcba (segmente, msb immer 0)
Displaydigit(1) = &B01000000 'Ziffer "0", 0 = segment ein, 1 = aus
Displaydigit(2) = &B01111001 'Ziffer "1"
Displaydigit(3) = &B00100100
Displaydigit(4) = &B00110000
Displaydigit(5) = &B00011001
Displaydigit(6) = &B00010010
Displaydigit(7) = &B00000010
Displaydigit(8) = &B01111000
Displaydigit(9) = &B00000000
Displaydigit(10) = &B00010000
Displaydigit(11) = &B00001000
Displaydigit(12) = &B00000011
Displaydigit(13) = &B01000110
Displaydigit(14) = &B00100001
Displaydigit(15) = &B00000110
Displaydigit(16) = &B00001110
Dunkelziffer = &B01111111 'senden um eine Ziffer dunkel zu schalten
'Nutzung von Software SPI
Config Spi = Soft , Dout = Portb.0 , Ss = Portb.1 , Clock = Portb.2
Spiinit
'mit Senden von acht high bits sicherstellen, daß über Q7 des Schieberegisters
'der HEF4017 die erste Ziffer der 4 X 7 Segmentanzeige adressiert -> reset des 4017
Init7segment = &B11111111
Spiout Init7segment , 1
Do
'alle Segmente mit Ziffer 8 für ca. 10s flimmerfrei einschalten
For Y = 1 To 7
For X = 0 To 255
Spiout Displaydigit(9) , 1
Waitms 5 'bei "waitms 10" -> flimmern erkennbar
Next X
Next Y
'alle Hexziffern langsam der Reihe nach durchgehend anzeigen
'Ziffern müssen per Spiout byte für byte gesendet werden um die
'HW Ziffernweiterschaltung per SS sicherzustellen!
For X = 1 To 16
Spiout Displaydigit(x) , 1
Waitms 500
Next X
'alle Hexziffern der Reihe nach an der letzten (rechten) Seite des Diplays anzeigen
For Y = 1 To 16
For X = 1 To 3 'die ersten 3 Stellen ausschalten
Spiout Dunkelziffer , 1
Next X
Spiout Displaydigit(y) , 1
Waitms 500
Next Y
Loop
End
Anmerkung zur Funktionsweise: Wenn ein Byte per SPIOUT gesendet wird, wechselt die SlaveSelect-leitung kurz vor Anlegen des ersten Datenbit von HIGH auf LOW. Sind alle Bits von SPIOUT gesendet, wechselt die SS Leitung wieder nach HIGH. Das ist anders als es im Portexpanderartikel im Diagramm "Signalfolge" dargestellt ist.
Vielleicht liegt es am ATtiny und ATMegas verhalten sich anders?
Die Fuse Bits befinden sich im Auslieferungszustand und damit ist der Systemtakt 1MHz. Die Taktrate auf der Clock-leitung für SPI beträgt hier gemessene 25KHz.
Weil noch 2 Ports frei sind, könnte man noch ein Poti am ADC anschließen und am anderen ein Servo. Vielleicht ergibt das ein Servotester mit digitaler Anzeige der Pulsweite. Mal sehen, wo mich der Weg hinführt - hoffentlich nicht direkt in den GAU :) :-) :-) Wie auch immer - es macht Spaß!
Fragen, Kritiken, Kommentare, etc wie immer willkommen!
PS: Bis die Funktion endlich erfüllt war, ist die HW unbemerkt gewachsen :); auf dem Steckbrett kein Problem.
EDIT: alten Titel "4x7 Segment Anzeige mit 3 Ader SW SPI, Servotester?" geändert.
Gruß
Searcher
hardware.bas
31.01.2011, 19:33
Das ist natürlich eine ganz tolle Sache, wie Du versuchst, eine relativ
aufwendige Anzeigeschaltung mit wenig Pinports des Tinys anzusteuern.
Eine Alternative wäre natürlich auch ein "grösserer" AVR z.B. Atmega16
und dann brauchst Du NUR noch den AVR. Vorrausgesetzt die 7-Segment-
Anzeigen verlangen nicht nach Treibern. VG Micha
Hallo!
@ Searcher
Gratulation, du hast den ersten Schritt zu µC's schon hinter dich ! :D
Ich möchte das gleiche schaffen, bin aber immer noch in der Denkphase. Momentan überlege ich den Brenner aus der Schaltung von hardware.bas.
Nach erster Analise und Messungen möchte ich eine D-Sub Verlängerung (1,8 m lang, 9-adrig, mit 4 Adern für GND) mit abgeschnittenen Steckern und wegen ziemlich grossen Kapazitäten zwischen Adern um 200 pF, einen gesockelten Treiber 74F125 verwenden, um ihn auswechseln zu können, falls ein schwächerer (z.B. 74LS125 bzw. 74HC125) ausreicht. Ausserdem weiss ich noch nicht, welcher Programmer aus schon installierten "bascavr", ich zum Brennen wählen sollte, wenn meine Hardware irgendwann fertig ist.
Was für ein Kabel und Treiber (125) hast du fürs Verbinden des Brenners mit dem ATTiny verwendet ? ;)
Ich würde mich sehr freuen, wenn du mir die hifreiche Erfahrunginformationen verraten könntest. :)
MfG
Searcher
31.01.2011, 23:17
Hallo,
da haben sich ja gleich die beiden Auslöser für meinen µC Einstieg gemeldet :-)
@hardware.bas: Danke für die Anerkennung. Bestimmt wird man für die Anzeige einen größeren µC nehmen. Das Ding hab ich irgendwo ausgeschlachtet und leider kein Datenblatt gefunden. Ein Segment leuchtet mit 2mA schon recht hell. Müßte ohne Treiber also noch gehen. Der 74HC245 ist nur drin, weil der HEF4017 nicht viel Strom liefert. Mit 74HC4017 braucht man den 74HC245 in dieser Schaltung dann auch nicht. Ist aber noch kein festes Projekt sondern einfach Freude am Experimentieren und Räder neu erfinden :-)
@PICture: Auch Dir danke. Ich verwende die Schaltung von hardware.bas für den Programmierdongle. Bei meinen ersten Versuchen mit low current LED blinken lassen hatte ich festgestellt, daß ohne Stromversorgung und mit eingstecktem Dongle die LED schwach leuchtete. Konnte nur vom PC kommen. Als erste Abhilfe eine 1N4148 Diode in die + Leitung des Dongles geschaltet, so daß nur von µC Schaltung der Strom zum Dongle fließen kann.
Als nächstes fand ich auf der RESET Leitung ein GND nach Einschalten des PC, das auch nach vollständigem Booten des PC nicht verschwand (bei an beiden Enden gestecktem Programmierkabel und Spannung auf der µC Schaltung). Erst nach Starten von BASCOM und erstmaligem Ansprechen der Programmierschnittstelle verschwand der GND. Grund lag darin, daß bei meinem PC die entsprechenden LPT Pins auf LOW initialisiert waren - das hat den 74HC125 durchgeschaltet. Erst durch BASCOM wurden die dann "günstig" gesetzt. Dazu ist zu sagen, daß auf dem PC mit WINXP SP3 noch kein Drucker eingerichtet war und ich streng nach BASCOM Hinweis einen HP Laserjet 4 für BASCOM installiert habe. Der Effekt verschwand erst, nachdem ich dann einen "Generic / Text only" Drucker zusätzlich installiert hatte. Es spielt keine Rolle, welcher Drucker als Defaultprinter bestimmt ist - Jetzt sind nach Booten des PC alle LTP Pins auf HIGH.
Hab mal ein Foto von meiner "Testumgebung" angehangen. Für den Dongle benutze ich einen gesockelten :) M74HC125B1 von ST. Als Kabel hab ich das Erstbeste ausprobiert, das mir in die Hände gefallen ist - Es ist 6 adriges flaches Telefonkabel; 1,70m lang und mir war nicht ganz wohl dabei. Bin aber bis jetzt sehr zufrieden damit. Wenn ich mich recht erinnere hab ich da einen Programmiertakt von 48KHz ausgemacht, der sich sogar erhöhte, nachdem ich die $CRYSTAL Einstellung veränderte. Werd das bei Gelegenheit nochmal verifizieren. Hab alles so auf Lochraster bekommen das es in das SUB-D Gehäuse passt.
Scheint mir recht unempfindlich zu sein und bin gespannt, wie lange das noch gut geht :-)
Gruß
Searcher
EDIT: hier noch der Schaltplan zum Dongle (credits to hardware.bas). Bei mir ist in der + Leitung noch eine 1N4148 Diode mit Kathode in Richtung Dongle drin.
https://www.roboternetz.de/community/attachment.php?attachmentid=17932&d=1295037596
https://www.roboternetz.de/phpBB2/download.php?id=20551
Vielen Dank für das Foto und deine ausführliche Erklärung. :)
Bei mir wird nur sicher kein Steckbrett geben, weil ich gleich meine mit zwei NiMh Akuss (2,4 V) betriebene Spielzeuge programmieren will. Geht der Programmer auch mit nur 2,4 V auf dem AVR gut ?
Dass die LPT Schnittstelle unter Windows XP erst beim Starten entsprechendes Brennprogramms funktioniert, ist mir schon lange klar. Der zustand der LPT Pins direkt nach dem Booten, ist mir egal. Ich werde, wenn es geht, keinen "virtuellen" Drucker installieren, weil ich keinen brauche. Ausserdem möchte ich die +5 V durch entsprechenden RC Tiefpass aus USB meines Lapis nehmen. :D
Was für Programmertyp vom BASCOM muss man auswählen ? ;)
MfG
hardware.bas
01.02.2011, 07:07
Bei der Gelegenheit sorry an PICture, da ich schon mal versprochen habe,
diese Info zu geben, bin jedoch erst jetzt an mein Notebook wieder
rangekommen, da es für Loggingaufgaben blockiert war .
Bei BASCOM in Verbindung mit dem LPT-gestützen Programmer mit
74HC125-Tristate-Treiber folgende Einstellung in BASCOM-AVR Option
notwendig: In dem oberen Fenster bei Programmer muss stehen:
Universal MCS Interface
Und innerhalb des Fensters von Universal muss als Programmer stehen:
WinAVR and SP12
VG Micha
hardware.bas
01.02.2011, 07:10
Nachtrag: Zum Programmieren würde ich schon 5V nehmen, ich habe
keine Ahnung, ob bei niedrigerer Vcc die Speicherzellen richtig gesetzt
werden. Das Risiko würde ich nicht eingehen. Jedoch ist, wenn man USB
als Vcc direkt benutzt, ja 5V gewährleistet. VG Micha
Searcher
01.02.2011, 08:19
@PICture: Programmer Typ in BASCOM auswählen:
Bei BASCOM in Verbindung mit dem LPT-gestützen Programmer mit
74HC125-Tristate-Treiber folgende Einstellung in BASCOM-AVR Option
notwendig: In dem oberen Fenster bei Programmer muss stehen:
Universal MCS Interface
Und innerhalb des Fensters von Universal muss als Programmer stehen:
WinAVR and SP12
Kann ich bestätigen. :wink: So geht es. Hab oben in meiner ersten Antwort den Schaltplan des Dongles nochmal verlinkt.
2,4V Programmierspannung: Auf dem Foto kann man nur 2 Batterien erkennen. Tatsächlich sind es 4 schwächelnde Zellen in einem quadratischen Batteriehalter, die zusammen 5,25Volt bringen. Werd es später mal mit geringeren Spannungen als 5V versuchen und noch ein paar Messungen machen. Mein ATtiny ist kein V Typ und nur bis 2,7V zugelassen :-)
EDIT: Ich habe nun ein Programm compilieren lassen, der mir den ROM fast voll schreibt - über 4000 Byte und programmiert. Hat mit Writing ROM und Reading ROM (wahrscheinlich verify) unter 15 Sekunden gedauert.
Gleichzeitig mit Oszi auf der SCL Leitung mit Meßfunktion des Oszi den Takt gemessen: $CRYSTAL Einstellung = 1000000 -> 30kHz, $CRYSTAL = 8000000 -> 45kHz. -> Oszillatortakt unverändert auf 1MHz.
Der Takt ist weit entfernt von einem festen Taktverhältnis -> deshalb Meßfunktion von Oszi.
Programmieren bei 2,65V Boardversorgung auch gut mit 30kHz!
Belegung des flachen Kabels von links nach rechts: SCL GND MOSI MISO VCC RESET.
Gruß
Searcher
Hallo!
Herzlichen Dank, jetzt weiss ich schon alles. :D
Ich werde lieber gleich VCC = 5 V vom Brenner nehmen, anstatt zu experimentieren, weil später werde ich wachrscheinlich mit normalen AVR's (keine V Typen) etwas machen.
Da ich den internen Oszillator mit ca, 120 kHz nutzen möchte, kann ich auch anfangs mit 74HC125 probieren und falls nötig, auf stärkeren Treiber immer noch wechseln. ;)
MfG
hardware.bas
01.02.2011, 18:52
Ich denke mal, die 74HC125-Treiber, welche dazu da sind, den eigentlichen
LPT-Passivbrenner qualitativ zu verbessern und auf Grund des Tri-State-
Verhaltens die restliche Schaltung nicht zu stören, haben mit der
Taktfrequenz eigentlich nichts zu tun. VG Micha
Doch, da sie bei ziemlich grosser kapazitativen Last (be meinem Kabel ca. 200 pF zwischen biliebigen Adern), ausreichend scharfe Flanken garantieren müssen. Die Steilheit der Flanken hängt eben von (Um)ladestrom der Kapazitanzen ab (wie bei Gate vom MOSFET). ;)
MfG
hardware.bas
02.02.2011, 09:44
Das klingt plausibel. VG Micha
Searcher
02.02.2011, 11:14
Ich überlege schon die Kapazität meines Kabel nachzumessen; bin aber davon abgekommen, sonst funktioniert es danach plötzlich nicht mehr :-)
Trotzdem interessiert es mich, wie man das halbwegs zuverlässig machen würde. Hab ein Vielfachmeßinstrument mit Kapazitätsmessung, kleinster Meßbereich 2000pF, Oszi und ein Frequenzgenerator wäre auch aufzutreiben.
Ganz naiv würde ich einfach zwei Adern in das DMM stecken und gucken was die Anzeige zeigt? Am anderen Ende des Kabels die Adern natürlich offen lassen.
Gruß
Searcher
Hallo!
Es gibt immer min. zwei Möglichkeiten ein Problem zu lösen, falls überhaupt möglich: messen berechnen und prüfen bzw. das schlimmstmögliche annehmen, das bestvorhandene nehmen und prüfen.
Mir gefällt besser die zweite (einfachere) Möglichkeit, deswegen nehme ich als Treiber 74F125, da ich besseren nicht habe, und bei Problemen werde ich das Kabel kürzen bzw. anderes nehmen müssen. Ich brauche nicht wegen Stromersparnis den 74HC125 nehmen, da ich ohne Anmeldung bis zu 100 mA aus dem USB ziehen kann. ;)
Notfalls müsste man auf der AVR-Seite auch einen entsprechenden Treiber (z.B. im Stecker) für das MISO Signal anwenden.
MfG
Hubert.G
02.02.2011, 16:26
Ich habe lange Zeit mit einem Dongle mit einem 74HC244 und einem 4m Druckerkabel programmiert und hatte nie Probleme.
Habe zwar die Adernkapazität nie gemessen, bei 4m Kabel wird sie nicht sehr klein sein.
hardware.bas
02.02.2011, 17:53
Ich vermute übrigens auch, dass trotz dieses plausibel klingenden
Argumentes, welches ich nicht widersprechen möchte, die Diskussion,
noch "bessere" Treiber als die genannten ins Auge zu fassen, ins
Theoretische abgleitet. Erstens wird man nicht mit extrem langen
Kabeln proggen, Zweitens kann man die Treiberschaltung in die
Nähe des ISP-Anschlusses bringen und Drittens müsste man ja bei
Rechtfertigung eines "Powertreiber" die EMV und ev. auch Induktivität
des nun schon extrem lang eingeplanten Kabels berücksichten .
JEDOCH .... wir wollen doch nur lediglich einen Chip flashen. VG Micha
Searcher
02.02.2011, 18:38
Hallo,
danke an alle. Meine Vorsicht gegenüber der Telefonanschlußschnur hat den Hintergrund, daß ich sowas mal als 1,5m langes LAN Kabel in einem 100BaseT LAN ausprobiert habe. Die grünen Lämpchen in den Interfacekarten leuchteten aber es gingen keine Daten rüber. Mir ist schon bewußt das da andere elektr. Verhältnisse herrschen aber seither werfe ich auch immer ein kritisches Auge auf das Kabel. :) Falls ich da Probleme bekomme, weiß ich nun an welchen Schräubchen ich überall drehen kann.
Ein anderer thread hat mich nun dazu verleitet, zu versuchen, den Tiny auch über RS232 und Software UART an den PC anzuschließen. Einen TC232 chip zur Schnittstellenanpassung habe ich schon gefunden und bin gerade dabei, ihm einen geeigneten Platz auf dem Steckbrett zu suchen.
Gruß
Searcher
@ hardware.bas
Ich nehme, wie auch immer, deinen letzten Beitrag nur als deine Meinung und werde sicher so lange geschirmte Kabel mit nötigen Treiber verwenden, die problemlos funktionieren und für mich bequem sind. :)
Mir ist die gesetzliche Lage über EMV Störungen bekannt und beschwere mich nicht, wenn ich mit meinem Weltempfänger Funkamateure aus Amerika auf KW bzw. London auf LW nicht ungestört hören kann, wenn der HV Brenner im Keller den Zentralheizungoffen gerade zündet, weil ich in meiner Wohnung im Winter doch warm haben möchte. ;)
Übrigens, der von mir bisher benutzter Brenner für PIC's mit 3m langem USB Kabel (ca. 600 pF von jeder Ader gegen GND) hat mit 7406 als Treiber immer problemlos funktioniert, habe ich mir bei eBay diese Treiber: http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&item=310240719068&ssPageName=STRK:MEWNX:IT gekauft, weil ich es zufärlässig haben möchte und nur ein Stück von 74F125 bei mir gefunden habe.
MfG
Searcher
04.02.2011, 13:49
Hallo,
hab mal den Titel des threads geändert, da ich noch kein festes Ziel verfolge sondern eigentlich nur als Anfänger noch experimentiere.
Als neues Feature auf dem Steckbrett habe ich nun eine RS232 Verbindung zum PC geschaffen. Anleitung nach der BASCOM-AVR Hilfe unter "Using the UART".
Der HW Aufbau war überhaupt kein Problem und hat sofort funktioniert. Das Beispielprogramm für SW UART lief auch sofort nach Weglassen des $baud und Anpassen der Portpins in der OPEN Anweisung.
Weil das fehlerfreie Empfangen der Zeichen auf dem µC aber nicht sehr zuverlässig ist, begab ich mich auf die Suche durch verschiedene threads und hab mich dann zur Verwendung des Pin Change Interrupt entschieden. Der wird zwar öfter ausgelöst als notwendig; zunächst reicht das aber für mich.
Die Aktivierung des PCI auf Pin PB4 hat mich "einige" Schleifen durch Datenblatt, BASCOM Hilfe, Simulator und Tests drehen lassen. Zusammenfassend: Da könnte die BASCOM Hilfe und insbesondere auch die attiny45.dat verbessert werden. (Keine Ahnung, ob das in der neuesten Vollverion schon OK ist) Dazu einige Remarks in dem Testprogramm.
'################################################# ##
'File: SW_UART.bas
'IDE: BASCOM-AVR Demo Version 1.11.9.8
'Tests on three wire software spi - output only
'SW UART
'UART - Inputs at terminal are echoed back to terminal
'and displayed at 7 segment in HEX ASCII
'Displayunit: 4 X 7 segment low current LED
'HW circuit: ATtiny45_4_X_7_Segment_SPI (UART still missing)
'################################################# ######
$regfile = "attiny45.dat"
$eepleave
$framesize = 32
$swstack = 32
$hwstack = 64 'hwstack reichlich wg Interruptroutine
$crystal = 8000000
Dim B As Byte
Dim X As Byte
Dim Y As Byte
Dim Init7segment As Byte
Dim Dunkelziffer As Byte
Dim Displaydigit(16) As Byte 'darzustellende Zeichen (hex 0..F)
'0gfedcba (segmente, msb immer 0)
Displaydigit(1) = &B01000000 'Ziffer "0", 0 = segment ein, 1 = aus
Displaydigit(2) = &B01111001 'Ziffer "1"
Displaydigit(3) = &B00100100 'Ziffer "2"
Displaydigit(4) = &B00110000
Displaydigit(5) = &B00011001
Displaydigit(6) = &B00010010
Displaydigit(7) = &B00000010
Displaydigit(8) = &B01111000
Displaydigit(9) = &B00000000
Displaydigit(10) = &B00010000
Displaydigit(11) = &B00001000
Displaydigit(12) = &B00000011
Displaydigit(13) = &B01000110
Displaydigit(14) = &B00100001
Displaydigit(15) = &B00000110
Displaydigit(16) = &B00001110
Dunkelziffer = &B01111111 'Wert um eine Ziffer dunkel zu schalten
Init7segment = &B11111111 'Wert um Anzeige zu initialisieren
'Nutzung von Software SPI
Config Spi = Soft , Dout = Portb.0 , Ss = Portb.1 , Clock = Portb.2
Spiinit
'TRANSMIT Kanal für SW UART Ausgabe öffnen
Open "comb.3:19200,8,n,1" For Output As #1 'comb.3 -> TX ist Pin PB3
'RECEIVE Kanal für SW UART Empfang öffnen
Open "comb.4:19200,8,n,1" For Input As #2 'RX ist PB4
Pcmsk = &B00010000 'Pin Change Interrupt PCINT4 auf Pin PB4 erlauben
On Pcint0 Isr_inkey 'Spring zur ISR wenn PCIF (Pin Change Int. Flag) in GIFR gesetzt ist
Enable Interrupts 'Setzt Global Interrupt Enable in SREG
Enable Pcint0 'Setzt PCIE (Pin Change Interrupt Enable) in GIMSK Register
'################################################# #########################################
'So könnte es bei Änderung der attiny45.dat auch gehen (keine sonstigen Konsequenzen getestet!!!)
'PCMSK = PCINT4
'On PCINT Isr_inkey
'Enable Interrupts
'Enable PCINT
'################################################# #########################################
'mit Senden von acht high bits sicherstellen, daß über Q7 des Schieberegisters
'der HEF4017 die erste Ziffer der 4 X 7 Segmentanzeige adressiert -> reset des 4017
Spiout Init7segment , 1
'4 x 7 Segment ständig mit Anzeigedaten versorgen (später mal in Timerinterrupt unterbringen)
Do
Spiout Dunkelziffer , 1
Spiout Dunkelziffer , 1
Spiout Displaydigit(x + 1) , 1
Spiout Displaydigit(y + 1) , 1
Loop
Close #2 'Kanäle schließen
Close #1
End
'ISR holt Zeichen vom UART wenn an RX Leitung ein Pegelwechsel erkannt wurde
'Ausführung der ISR setzt PCIF in GIFR automatisch zurück
Isr_inkey:
B = Inkey(#2)
'Nur Ausführen, wenn Zeichen vollständig eingetroffen ist
If B > 0 Then
X = B
Y = B
Shift X , Right , 4 'Zeichen für 7 Segment aufbereiten -
Shift Y , Left , 4 '- x und y mit high und low nibble versorgen
Shift Y , Right , 4
Print #1 , Chr(b) ; " " 'Echo Zeichen zurück an Terminal
End If
Return
Fragen, Kommentare, etc ... Ihr wisst schon :) (Aber bitte noch nicht steinigen, lieber konstruktiv - ich möchte doch noch weiter machen :-) )
Gruß
Searcher
hardware.bas
04.02.2011, 19:57
Das 1m lange Anschlusskabel vom Dongle (mit Treiber) zu den 3 ISP-PINs,
sowie +5V, Masse und Reset ist bei mir übrigens auch abgeschirmt, warum?
Weil ich dieses Kabelschnippel gerade übrig hatte, Mit Klingeldraht gehts
auch, damit hatte ich kleine Miniplatinen mit Tinys geproggt und danach
abgeschnitten und vergossen. Das ist wirklich absolut problemlos und
daher erreicht man sein Ziel in Windeseile. Mein "richtiges"
Programmiergerät, welches übrigens auch nach den gleichen Schaltungs-
prinzip funktioniert sieht natürlich besser aus. Nur..... ich nutze es kaum,
da ich ISP meistens so verwende, wie es heisst und direkt in der
Zielschaltung ohne störanfällige IC-Fassungen progge. VG Micha
Searcher
06.02.2011, 13:05
So,
jetzt funktioniert auch die Ziffernausgabe mit Timer. Dabei mußte ich wohl den Fehler machen, das man in BASCOM mit sowas ohne Warnung Probleme kriegt:
Spiout Displaydigit(Displaydigitaddress(x) + 1) , 1
und besser so macht:
Y = Displaydigitaddress(x) + 1
Spiout Displaydigit(y) , 1
entsprechende Codeschnipsel:
.
.
'8 bit Timer zur Ziffernausgabe on Overflow 8MHz / 128 / 256 ~ 244 Hz ~ 60Hz pro Ziffer
Config Timer1 = Timer , Prescale = 128
On Ovf1 Isr_timer1
Enable Timer1
.
.
Isr_timer1: 'wird ca. 244 mal / Sek. aufgerufen und zeigt jedesmal 1 von 4 Ziffern an
If X > 4 Then
X = 1
End If
Y = Displaydigitaddress(x) + 1
Spiout Displaydigit(y) , 1
X = X + 1
Return
Gruß
Searcher
Searcher
11.02.2011, 00:29
Hallo,
ein weiteres Machwerk auf dem Weg zum Servotester mit Pulsweitenanzeige. Noch nicht ganz ausgereift und die Auflösung ist noch verbesserungswürdig. Aber damit hab ich hoffentlich schon ein paar Hürden zum Verstehen des ATtiny45 überwunden.
Mit dem CONFIG SERVO Befehl des BASCOM-AVR kam ich überhaupt nicht klar. Nach meinen Erfahrungen zu ungenau, abhängig von $CRYSTAL und sobald ISR laufen, nicht mehr kalkulierbar.
Deshalb den Timer1 "per Hand" für PWM konfiguriert. Da der Servo ein Impuls alle 20ms braucht, der zwischen 1 bis 2 ms lang sein soll und dieser Impuls auch noch möglichst fein einstellbar sein soll und auch noch sehr konstant sein muß, hab ich folgende Lösung versucht:
Kleinste Auflösung für Servopulseinstellung=16µs. Da man bei dem 8bit Timer damit nicht auf die 20ms Pulsabstand kommt - den Timer dann alle 5 Mal mit der Pulsweite als "Monoflop" Interrupt gesteuert auf den Ausgang wirken lassen - funktioniert.
Pulsweite einstellbar mit 10k Poti am ADC.
'################################################# ##
'File: Servotester mit Display.bas
'IDE: BASCOM-AVR Version 1.11.9.8
'HW circuit: ATtiny45_4_X_7_Segment_SPI (ADC- & Servoanschluß nicht eingezeichnet)
'Multiplexing und Servosignal via Timer1
'Servo an PB4. 10k Poti für Servopulseinstellung an PB3
'4 x 7 Segment zeigt Servopuls in ms an. Bereich 0,720ms bis 2,304ms in 16µs steps
'################################################# ######
$regfile = "attiny45.dat"
$eepleave
$framesize = 32
$swstack = 32
$hwstack = 96 'hwstack reichlich wg Interruptroutine
$crystal = 8000000
Dim X As Byte
Dim Y As Byte
Dim Z As Byte
Dim Init7segment As Byte
Dim Displaydigitaddress(4) As Word
Dim Displaydigit(17) As Byte 'darzustellende Zeichen (hex 0..F)
'0gfedcba (segmente, msb immer 0)
Displaydigit(1) = &B01000000 'Ziffer "0", 0 = segment ein, 1 = aus
Displaydigit(2) = &B01111001 'Ziffer "1"
Displaydigit(3) = &B00100100 'Ziffer "2"
Displaydigit(4) = &B00110000
Displaydigit(5) = &B00011001
Displaydigit(6) = &B00010010
Displaydigit(7) = &B00000010
Displaydigit(8) = &B01111000
Displaydigit(9) = &B00000000
Displaydigit(10) = &B00010000
Displaydigit(11) = &B00001000
Displaydigit(12) = &B00000011
Displaydigit(13) = &B01000110
Displaydigit(14) = &B00100001
Displaydigit(15) = &B00000110
Displaydigit(16) = &B00001110
Displaydigit(17) = &B01111111 'Wert um eine Ziffer dunkel zu schalten
Displaydigitaddress(1) = 16 'Wenn noch keine Ziffer eingegeben -> dunkel
Displaydigitaddress(2) = 16
Displaydigitaddress(3) = 16
Displaydigitaddress(4) = 16
X = 0 'Initialisierung von Zählvariablen
Y = 0 'Initialisierung von Zählvariablen
Z = 0 'Initialisierung von Zählvariablen
'Nutzung von Software SPI - nur Output
Config Spi = Soft , Dout = Portb.0 , Ss = Portb.1 , Clock = Portb.2
Spiinit
'mit Senden von acht high bits sicherstellen, daß über Q7 des Schieberegisters
'der HEF4017 erste Ziffer der 4 X 7 Segmentanzeige adressiert -> reset des 4017
Init7segment = &B11111111
Spiout Init7segment , 1
Config Portb.4 = Output 'PB4 as output
Gtccr = Gtccr Or &B01100000 'set PWM1B & OC1B (PB4) to clear on compare
Ocr1b = 94 'set pulse to 1504µs (on 8Mhz, prescaler = 128)
Ocr1c = 254 'set min pwm frequency (8Mhz / 128 / 255 =~ 245 Hz
Tccr1 = Tccr1 Or &B00001000 'set prescaler (128) switches timer on
On Ovf1 Isr_timer1
Enable Timer1
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Dim Comparematchvalue_ocr1b As Byte
Dim Adc_readout As Integer
Dim Adc_str As String * 5
Dim Char As String * 1
Dim Channel As Byte
Channel = 3 'ADC3 (auf Pin PB3)
Enable Interrupts
Do
Adc_readout = Getadc(channel)
If Adc_readout < 10 Then
Adc_readout = 10
Elseif Adc_readout > 1000 Then
Adc_readout = 1000
End If
Adc_readout = Adc_readout / 10
Adc_readout = Adc_readout + 43
Comparematchvalue_ocr1b = Adc_readout
Adc_readout = Adc_readout * 16
Adc_readout = Adc_readout + 10016
Adc_str = Str(adc_readout)
Char = Mid(adc_str , 2 , 1)
Displaydigitaddress(1) = Val(char)
Char = Mid(adc_str , 3 , 1)
Displaydigitaddress(2) = Val(char)
Char = Mid(adc_str , 4 , 1)
Displaydigitaddress(3) = Val(char)
Char = Mid(adc_str , 5 , 1)
Displaydigitaddress(4) = Val(char)
Loop
End
Isr_timer1:
X = X And &B00000011
X = X + 1
Y = Displaydigitaddress(x) + 1
Spiout Displaydigit(y) , 1
If Z >= 4 Then
Ocr1b = CompareMatchValue_OCR1B
Bitwait Pinb.4 , Set
Bitwait Pinb.4 , Reset
Ocr1b = 0
Z = 0
Else
Z = Z + 1
End If
Return
Praxistest mit echtem Servo steht noch aus (nur mit Oszi und 10k Pulldown probiert)
Anzeige flimmert leicht - warum auch immer - mal sehen...
EDIT: wg. Flimmern siehe verbessertes Listing im Beitrag vom 12.02.2011 weiter hinten im thread
Fazit - ich glaub ich hab den "nicht phasen korrekten PWM Timer" verstanden :-)
Bitte um Aufzeigen möglicher Probleme, Kommentare, Fragen, etc. willkommen.
(hab mir vorgenommen, den Code demnächst noch ein bißchen besser zu kommentieren)
Gruß
Searcher
Searcher
11.02.2011, 15:55
Servotester hat auch den Praxistest bestanden. Kleines Video dazu:
http://i3.ytimg.com/vi/V_cGd_rj_Xw/default.jpg (http://www.youtube.com/watch?v=V_cGd_rj_Xw)
Bild klicken zum Video
Die Anzeige flimmert zwar leicht, aber nicht sooo schlimm wie im Video. Meine/die Aufnahmetechnik hat da leider Grenzen.
Der chip links unten mit den 4 Kondensatoren sind noch Überbleibsel von den UART Versuchen.
Gruß
Searcher
hardware.bas
12.02.2011, 11:32
Mach Dir um das Flimmern im Video keine so grossen Gedanken.
Das ist der typische Stroboskopeffekt, oder Alaysingeffekt, den
man hat wenn das Multiplexing der Anzeige sich ungeradzahlig mit
der Abtastfrequenz des Videos verhält. Also ganz normal. VG Micha
Searcher
12.02.2011, 21:27
Hallo,
das Displayflimmern ist auf dem Video sehr stark und sicher größtenteils vom Stroboskopeffekt hervorgerufen worden. Es war aber sozusagen Angesicht zu Angesicht auch noch ein leichtes Flimmern zu erkennen, daß mir aber denn doch keine Ruhe gelassen hat.
Lag daran, daß eine von 5 Ausgaben mit SPIOUT scheinbar auf Beendigung des Pulses gewartet hat. Das führte dann zu ungleichmäßigen Zeitabständen bei der gemultiplexten Ziffernausgabe. Mir ist noch nicht klar wie das sein konnte.
Hab das Timing entzerrt und die Anzeige ist jetzt ganz sauber! Lasse nun auch keine anderen Aufgaben mehr vom Interrupt unterbrechen :-) und hab alles überarbeitet und kommentiert.
'################################################# ##
'File: Servotester mit Display.bas
'IDE: BASCOM-AVR Version 1.11.9.8
'HW circuit: ATtiny45_4_X_7_Segment_SPI (ADC- & Servoanschluß nicht eingezeichnet)
'Multiplexing und Servosignal via Timer1
'Servo an PB4. 10k Poti für Servopulseinstellung an PB3
'4 x 7 Segment zeigt Servopuls in µs an. Bereich 0,720ms bis 2,304ms in 16µs steps
'Version ohne flimmerndes Display :-)
'################################################# ######
$regfile = "attiny45.dat"
$eepleave
$framesize = 32 'default?
$swstack = 32 'default?
$hwstack = 48 'hwstack reichlich wg Interruptroutine
$crystal = 8000000
Dim X As Byte
Dim Y As Byte
Dim Z As Byte
Dim Init7segment As Byte
Dim Displaydigitaddress(4) As Byte
Dim Displaydigit(10) As Byte 'darzustellende Zeichen (hex 0..F)
'0gfedcba (segmente, msb immer 0)
Displaydigit(1) = &B01000000 'Ziffer "0", 0 = segment ein, 1 = aus
Displaydigit(2) = &B01111001 'Ziffer "1"
Displaydigit(3) = &B00100100 'Ziffer "2"
Displaydigit(4) = &B00110000
Displaydigit(5) = &B00011001
Displaydigit(6) = &B00010010
Displaydigit(7) = &B00000010
Displaydigit(8) = &B01111000
Displaydigit(9) = &B00000000
Displaydigit(10) = &B00010000
'Nutzung von Software SPI - nur Output
Config Spi = Soft , Dout = Portb.0 , Ss = Portb.1 , Clock = Portb.2
Spiinit
'mit Senden von acht high bits sicherstellen, daß über Q7 des Schieberegisters
'der HEF4017 erste Ziffer der 4 X 7 Segmentanzeige adressiert -> reset des 4017
Init7segment = &B11111111
Spiout Init7segment , 1
X = 0 'Initialisierung von Zählvariablen
Y = 0 'Initialisierung von Zählvariablen
Z = 1 'Initialisierung von Zählvariablen
Config Portb.4 = Output 'PB4 as output, Servosignal
Gtccr = Gtccr Or &B01100000 'set PWM1B & OC1B (PB4) to clear on compare
Ocr1a = 160 'timing for int OC1A behind pulse (> max ocr1b)
Ocr1b = 0 'if OCR1B = 0 -> Pin OC1B = low in PWM mode
Ocr1c = 249 'set pwm frq. (8Mhz / 128 / (249 + 1) = 250 Hz)
Tccr1 = Tccr1 Or &B00001000 'set prescaler (128) switches timer on
On Oc1a Isr_set_ocr1b 'execute ISR on Timer 1 Comparematch A
Enable Oc1a
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Dim Comparematchvalue_ocr1b As Byte
Dim Adc_readout As Integer
Dim Adc_str As String * 5
Dim Char As String * 1
Dim Adc_channel As Byte
Adc_channel = 3 'ADC3 (at Pin PB3)
Enable Interrupts
Do
Loop
End
'ISR wird angsprungen on Timer1 Compare Match A
'Der Zeitpunkt (Ocr1a = 160) liegt "oberhalb" des Pulses von OCR1B <= 143
'damit beeinflussen sich Ziffernausgabe und Pulserzeugung nicht
Isr_set_ocr1b:
X = X And &B00000011 'X does not exeed the value of 3
Incr X 'set digit position
Y = Displaydigitaddress(x) + 1
Spiout Displaydigit(y) , 1 'send digit to display
If Z >= 5 Then 'make one pulse out of five isr calls
Ocr1b = Comparematchvalue_ocr1b 'put value for pulse lemgth into OCR1B
Bitwait Pinb.4 , Set 'wait until pulse starts (TCNT1 at $00)
Bitwait Pinb.4 , Reset 'wait until pulse ends (match on OCR1B)
Ocr1b = 0 'keep PINB.4 LOW
Z = 1
Else 'if no pulse do all other tasks
Incr Z
Adc_readout = Getadc(adc_channel) 'read ADC
If Adc_readout < 10 Then 'trim small and large ADC values
Adc_readout = 10
Elseif Adc_readout > 1000 Then
Adc_readout = 1000
End If
Adc_readout = Adc_readout / 10 'calculate units for the timer
Adc_readout = Adc_readout + 43 'calculate units for the timer
Comparematchvalue_ocr1b = Adc_readout '16µs units -1 pulsewidth
Adc_readout = Adc_readout * 16 'prepare display register
Adc_readout = Adc_readout + 10016 'prepare display register
Adc_str = Str(adc_readout) 'prepare display register
Char = Mid(adc_str , 2 , 1) 'prepare display register
Displaydigitaddress(1) = Val(char) 'prepare display register
Char = Mid(adc_str , 3 , 1)
Displaydigitaddress(2) = Val(char)
Char = Mid(adc_str , 4 , 1)
Displaydigitaddress(3) = Val(char)
Char = Mid(adc_str , 5 , 1)
Displaydigitaddress(4) = Val(char) 'prepare display register
End If
Return
Entschuldigung wg. Mischmasch Deutsch-Englisch bei den Comments - Das Datenblatt macht einen komplett konfus :)
Gruß
Searcher
Searcher
01.03.2011, 22:14
Hallo,
diesmal habe ich mit einer IR-Fernbedienung gespielt. Einen TSOP an PB4 und das GETRC5 Kommando ausprobiert. Weil das so einfach lief habe ich dann noch den Power-down des µC und Watchdogfunktion hinzugefügt. Das war dann schon etwas verzwickter um eine annehmbare Funktion hinzubekommen.
'################################################# ##############################
'File: RC5.bas
'4 x 7 Segment zeigt via Infrarotfernbedienung empfangene RC5 Nachricht in hex
'IDE: BASCOM-AVR Demoversion 1.11.9.8
'HW circuit: ATtiny45_4_X_7_Segment_SPI (TSOP nicht eingezeichnet)
'Anzeigemultiplexing via Timer1
'TSOP an PB4. BASCOM Kommando Getrc5 nutzt Timer0 !!!
'
'Grober Ablauf:
'Nach Einschalten oder Watchdogablauf initialisieren und dann in "Power-down"
'Bei IR Empfang wird µC per Pin Change Interrupt aufgeweckt
'Mit Watchdog wird auf gültige RC5 Nachricht überwacht
'Ungültige Nachricht und Ausschalten wird 4s lang mit liegenden Strichen angekündigt
'Gültige Nachricht bleibt solange stehen bis sie durch neue gültige Nachricht ersetzt wird
'Ausschalten in den "Power-down" mit Standby Taste oder Watchdogablauf wg. ungültiger Nachricht
'################################################# ##############################
$regfile = "attiny45.dat"
$eepleave
$framesize = 32 'default?
$swstack = 32 'default?
$hwstack = 48 'hwstack reichlich wg Interruptroutine
$crystal = 8000000
$lib "mcsbyte.lbx" 'only byte operations
Dim Displaydigitaddress(4) As Byte 'pointer to segmentpattern
Dim Address As Byte , Command As Byte 'variables for getrc5
Dim Digitposition As Byte 'actual digit position, left to right = 1..4
Dim Helperbyte As Byte 'multipurpose
'Nutzung von Software SPI - nur Output
Config Spi = Soft , Dout = Portb.0 , Ss = Portb.1 , Clock = Portb.2
Spiinit
'mit Senden von acht high bits sicherstellen, daß über Q7 des Schieberegisters
'der HEF4017 erste Ziffer der 4 X 7 Segmentanzeige adressiert -> reset des 4017
Helperbyte = &B11111111
Spiout Helperbyte , 1
Config Timer1 = Timer , Prescale = 128 'Anzeigetimer ~60Hz pro Ziffer (RCO=8MHz)
On Ovf1 Isr_display_digit
Config Watchdog = 4096 '4096 ms timeout
Config Rc5 = Pinb.4 'TSOP at PB4
Set Pcmsk.pcint4 'enable Pin Change Interrupt on TSOP activity
On Pcint0 Show_dashes 'if PCINT then display dashes
Enable Interrupts
Enable Pcint0 'enable wake up on Pin Change Interrupt
Power Powerdown 'switch µC down, wait for PCINT (IR signal)
Disable Pcint0 'in power up avoid further PCINTs
Enable Ovf1 'enable display interrupt
Start Watchdog 'supervise for valid RC5 message
Do
Getrc5(address , Command) 'function returns FF FF if no RC5 message
If Address <> &HFF Then 'RC5 message received then...
Command = Command And &B01111111 'set toggle bit to zero
Stop Watchdog 'stop watchdog due to accepted RC5 message
If Command = &H0C Then 'if "Standby" command received then...
Gosub Show_dashes 'announce Power-down
Waitms 4000 'show dashes for 4 seconds
Gosub Display_dark 'switch all segments off
Enable Pcint0 'enable wake up on new TSOP (IR) signal
Power Powerdown 'switch µC down, wait for PCINT (IR signal)
Disable Pcint0 'in power up avoid further PCINTs
Start Watchdog 'supervise for valid RC5 message
Else
Gosub Message_to_display 'display all RC5 messages except "Standby"
End If
End If
Loop
Display_dark: 'all segments off
Displaydigitaddress(1) = 16
Displaydigitaddress(2) = 16
Displaydigitaddress(3) = 16
Displaydigitaddress(4) = 16
Waitms 100 'give time to multiplex
Return
Show_dashes: 'dashes to display
Displaydigitaddress(1) = 17
Displaydigitaddress(2) = 17
Displaydigitaddress(3) = 17
Displaydigitaddress(4) = 17
Return
Message_to_display: 'RC5 address and command to display
Displaydigitaddress(1) = Address
Shift Displaydigitaddress(1) , Right , 4
Displaydigitaddress(2) = Address
Displaydigitaddress(2) = Displaydigitaddress(2) And &H0F
Displaydigitaddress(3) = Command
Shift Displaydigitaddress(3) , Right , 4
Displaydigitaddress(4) = Command
Displaydigitaddress(4) = Displaydigitaddress(4) And &H0F
Return
Isr_display_digit: 'on each interrupt OVF1 send one digit
Digitposition = Digitposition And &B00000011 'if Digitposition = 4 -> 0
Incr Digitposition 'set digit position
Helperbyte = Lookup(displaydigitaddress(digitposition) , Segmentpattern)
Spiout Helperbyte , 1 'send digit to display
Return
Segmentpattern: 'darzustellende Zeichen (hex 0..F...)
'0gfedcba (segmente, msb immer 0)
Data &B01000000 'Ziffer "0", 0 = segment ein, 1 = aus
Data &B01111001 'Ziffer "1"
Data &B00100100 'Ziffer "2"
Data &B00110000
Data &B00011001
Data &B00010010
Data &B00000010
Data &B01111000
Data &B00000000
Data &B00010000
Data &B00001000
Data &B00000011
Data &B01000110
Data &B00100001
Data &B00000110 'Ziffer "E"
Data &B00001110 'Ziffer "F"
Data &B01111111 'dunkel
Data &B00111111 'nur Segment g eingeschaltet=Strich
Kritik, Fragen etc. willkommen.
Gruß
Searcher
Searcher
10.03.2011, 09:43
Hallo,
sportlicher Ehrgeiz varanlasste mich zu versuchen mit dem BASCOM-AVR SPIOUT Kommando die 4 X 7 Segmentanzeige mit nur noch zwei Adern anzusteuern. Vom ATtiny45 aus sind jetzt nur Dout und Clock notwendig:
Config SPI = Soft , Dout = PORTB.0 , Clock = PORTB.2
Ohne Slave Select werden benötigte Steuersignale für Schieberegister und Ziffernweiterschaltug per HW aus dem SPI Takt gewonnen. Dabei gelang es mir durch viel Fummelei einen stabilen Zustand beim Stromeinschalten herzustellen.
Schaltbild im Anhang
Die Schwierigkeit, die es zu überwinden galt, war der 4017 in der Mitte des Schaltbildes, der oft irgendwelche Zustände nach Einschalten hatte und dann Segmente und Ziffern durcheinanderwarf. Ohne aufwendige Resetschaltung haben dann die beiden 100k Widerstände an MR und CP1 geholfen. Wie stabil das auf Dauer ist unterliegt jetzt einer Langzeitstudie :-)
Natürlich ist der HW Aufwand unverantwortbar und jetzt auch noch überproportional zu der eingesparten Ader gestiegen :-b Die Experimente sind jedoch sehr aufschlußreich.
Gruß
Searcher
Searcher
19.07.2011, 20:06
Hallo,
ich hatte da noch ein paar Chips rumliegen und wie immer zu wenig Pins an meinem ATtiny45. Wie der Vorgänger wird diese Anzeige auch nur mit 2 Ader in SW-SPI angesteuert.
Bei dieser neuen Version ist es aber nicht mehr notwendig die einzelnen Ziffern vom µC aus zu multiplexen. Die einmalige Ausgabe aller 4 Ziffern wird in den kaskadierten Schieberegistern gespeichert und durch einen externen Takt zb von einem 555, an die Siebensegmentanzeige ausgegeben.
Die Inverter sorgen dafür, daß durch inaktiv schalten von Output Enable am 595 alle Ausgänge hochohmig werden, bis auf die, die gerade zur Segmentansteuerung gebraucht werden.
Jetzt brauch ich nur per SPI entsprechende Daten dann auszugeben, wenn sie wirklich anfallen und kann dadurch Recourcen zum Multiplexen einsparen.
Na gut, sowas könnte man sicher auch einfach haben. Für mich war und ist es eine schöne Übung. Konnte bisher nur 2 Ziffern realisieren, da mir noch zwei 595er fehlen.
VCC .-----------------.
+ | .---------)-. irgendein
| .------------)-------)---. | | Takt
o------)------------)-----. | .-)-----)-)-------<
| | | | | | | | | | |
Seg A | === | o_o_o_o_o_o_o_o
D1.->|--o-- Q0-------------------------------)--. GND | | 4017 |
| |B __ | | | |1_ _ _ _ _ _ _ |
|->|--)-- Q1---------------o------o|1 |o---o | | o o o o o o o o
| | Q2-------------o-)------o| |o---)--o ---------)--. | | | | | | | |
| Q3-----------o-)-)------o| |o---)--)------' /| | | | | | |
| Q4---------o-)-)-)------o| |o---)--)------o--O< |---)--)------. | | |
| Q5-------o-)-)-)-)------o| |o---)--)------' \| | | | | | |
| Q6-----o-)-)-)-)-)------o| |o---)--)----. Inverter| | | | | | SPI data
| | | | | | | -o| |o---o | | | '------)-)-)-----)-------<
Seg A| | | | | | | o--o|__|o---)--)--. | | | | | |
D2 ->|-o | | | | | | | 595 | | | | | | | | | SPI clock
| | | | | | | | __ | | | o-----------)---------)-)-)-----)-------<
D3 ->|-o | | | | | o---)--o|1 |o---o | | | | | | | |
| | | | | o-)---)--o| |o---)--o | | | | | | |
D4 ->|-' | | | o-)-)---)--o| |o---)--)--' | /| | | | | |
| | o-)-)-)---)--o| |o---)--)----)-o--O< |---)---------)-. | |
| o-)-)-)-)---)--o| |o---)--)----)-' \| | | | | |
4 X 7 Seg o-)-)-)-)-)---)--o| |o---)--)----o | | | | |
mit gem. Anode | | | | | | | -o| |o---o | | | | | | |
| | | | | | o--o|__|o---)--)--. | | | | | |
| | | | | | | 595 | | | | | | | | |
| | | | | | | __ | | | | | | | | |
| | | | | o---)--o|1 |o---| | | | | | | | |
| | | | o-)---)--o| |o---)--o | | | | | | |
| | | o-)-)---)--o| |o---)--)--' | /| | | | | |
| | o-)-)-)---)--o| |o---)--)----)-o--O< |---. | | | |
| o-)-)-)-)---)--o| |o---)--)----)-' \| | | | | |
o-)-)-)-)-)---)--o| |o---)--)----o | | | | |
| | | | | | | -o| |o---' | | | | | | |
| | | | | | o--o|__|o------)--. | | | | | |
| | | | | | | 595 | | | | | | | |
| | | | | === | | | | | | | ===
| | | | GND | | | /| | | | | GND
| | | | | | .--O< |---)---------)-)-.
| | | | | \| | | | |
eventuell Q6 Q0 | | | | | |
Treiber | | | |
/| Digit 1 | | | |
--< |-------------------------------------------------------------)---------' | |
\| D2 -------------------------------------------------------)-----------' |
D3 ---------------------------------------------------------- |
D4 --------------------------------------------------------------------------'
Pin Belegung
74HC595N HEF4017B
__ __
Q1 -o|1 |o- VCC Q5 -o|1 |o- VCC
Q2 -o| |o- Q0 Q1 -o| |o- MR
Q3 -o| |o- Ds Q0 -o| |o- CP0
Q4 -o| |o- OE (low aktiv) Q2 -o| |o- CP1 (low aktiv)
Q5 -o| |o- STcp Q6 -o| |o- Q5-9 (low aktiv)
Q6 -o| |o- SHcp . Q7 -o| |o- Q9
Q7 -o| |o- MR (low aktiv Q3 -o| |o- Q4
GND -o|__|o- Q7' GND -o|__|o- Q8
PS Frisch vom Basteltisch weiß ich noch nicht ob es versteckte Fehler gibt. Bis jetzt funktioniert es perfekt. (Hoffe natürlich auch, das ich die ASCII Art fehlerfrei hinbekommen habe :-)
Gruß
Searcher
Besserwessi
24.07.2011, 10:42
Wenn man die Anzeigen gar nicht gemultiplext ansteuern will, kann man sich den 4017 und die Transistoren ganz sparen, und die Anzeigen direkt an die HC595 legen. Und die Anoden fest auf VCC. Das geht aber nur wenn die Anzeigen nicht schon mit den Segmenten verbunden sind. Sonst wäre es einfacher statt der ganzen Logic einen kleinen µC (Tiny261 ) zu nehmen.
Bei der Schaltung so wie gezeigt braucht man wirklich die OE Pins. Es könnte noch der Anschluss für die Datenübernahme beim 595 fehlen.
Searcher
24.07.2011, 14:37
Das geht aber nur wenn die Anzeigen nicht schon mit den Segmenten verbunden sind
@Besserwessi: Danke für die Vorschläge. Leider muß ich multiplexen. Liegt an der Art des Displays. Wie im anderen thread (https://www.roboternetz.de/community/showthread.php?54131-Kollektorschaltung-als-LED-Treiber-von-7-Segmentanzeige) schon beschrieben, ist es eine 4-fach Anzeige in einem Block. Zur Ansteuerung aller 4 Ziffern (28 Segmente) gibt es nur 11 Anschlüsse. (1 Anschluß (gemeiname Anode) pro Ziffer = 4 und 7 Anschlüsse der gleichen parallel geschalteten Segmente aller Ziffern)
Datenübenahme klappt. Am 595 sind OE und STcp parallel geschaltet. Wenn dort getoggelt wird, gehen die Daten vom Shiftregister ins Outputregister. und spätestens beim nächsten Toggle auf die Ausgänge.
Anzeige ist ähnlich dieser mit CODE A: http://www.leds.com.hk/pdf/49KT40281AD.pdf
Gruß
Searcher
Searcher
28.07.2011, 22:26
So, die asynchron gemultiplexte 4-fach Siebensegmentanzeige mit SPI Interface existiert nun nicht mehr nur auf dem Steckbrett.
19463 19464 19465
Der Anzeigeblock ist für Multiplex vorgesehen und war bisher auf Lochraster nur mit Vorwiderständen für die Segmente aufgebaut. Nun wurde auf 2 weiteren Platinen die Schaltung nach angehangenem Schaltplan hinzugefügt, die ein Offline multiplexen durch Speicherung in Schieberegistern ermöglichen.
Die oberste Platine enthält den Memoryblock mit den vier Schieberegistern. Die darunter die Transistorzifferntreiber, den 4017er Dekadenzähler und den LUV04 sechsfach Inverter, Taktgenerator. Die unterste trägt den Anzeigeblock mit den Segment-LED Vorwiderständen.
Die anzuzeigende Information wird über zwei SPI Adern, DATA und CLOCK, zur Anzeige übertragen - GND und VCC natürlich auch mit dem SPI Sender verbunden. Die 74HC595 speichern die 4 Byte solange bis sie von anderen Bytes überschrieben werden. Die Verschaltung mit HEF4017 und Taktgenerator bringen die gespeicherten Informationen im Multiplex zur Anzeige.
Dadurch, daß das Ganze in HW realisiert wurde, wurden doch einige Verdrahtungsarbeiten fällig. Eigentlich wollte ich Höhe der beiden Zusatzplatinen auf die Höhe der Anzeige begrenzen. Das war mir jedoch nicht möglich. Damit ich wenigstens die angepeilte Fläche nicht überschritt, habe ich die vier Schiebergister im Huckepack auf die Platine gebracht und geriet doch noch in der Enge in Verdrahtungsnot. Einige Lötstellen sind nicht so schön, wie ich sie gerne gahabt hätte, egal - elektrisch einwandfrei ist besser als schöne geschmolzene Isolation bei Nachbesserungsversuchen.
Bei der nächsten wird es besser ... :-)
Gruß
Searcher
Searcher
02.08.2011, 20:50
Die Anzeige war mir doch etwas duster und habe das Display wieder umgebaut. Neuer Schaltplan anbei.
Damit die parallel geschalteten Ausgänge der 74HC595 nicht gleichzeitig eingeschaltet werden können, wird nur jedes zweite high an den Ausgängen des 4017 zur Durchschaltung genutzt. Nachteil vorher: die Segmente sind durch die gleichmäßige Taktung länger ausgeschaltet als es sein müßte, nur um ein sicheres Abschalten der Ausgänge vor Einschalten der nächsten Ausgänge zu gewärleisten.
Über Kondensator C2 wird nun, sobald ein Zwischenschritt auftritt, der 4017 sofort mit einer kleinen Verzögerung weitergeschaltet und die nächsten Ziffernsegmente aktiviert.
Damit ist die Ausschaltedauer gegenüber der Einschaltedauer erheblich verkürzt. Außerdem wurden die LED-Vorwiderstände auf 360 Ohm verringert und die Doppelpunkte in der Mitte der Anzeige auch noch angeschlossen. Pro Segment sind damit ca 5mA bei 5V VCC eingestellt. Der HEF4017B ist etwas schwach und seine Ausgangsspannung sinkt etwas, wenn die Transistoren viele Segmente treiben müssen. Wird bei Gelegenheit gegen 74HC4017 ausgetauscht obwohl optisch nicht wahrnehmbar.
Ich glaub jetzt bin ich wirklich zufrieden:confused: und könnte mit den Doppelpunkten nun sogar die Zeit anzeigen lassen :-) ...
PS Entschuldigung für die schlechte Qualität des Schaltbildes. Ich experimentiere noch, wie ich aus LTspice vernünftige PNGs rausbekomme.
Gruß
Searcher
Searcher
07.08.2011, 21:32
Weil es Spaß macht hab ich es nun weitergetrieben und ein UART Interface für das Asynchron gemultiplexte Display gemacht. Jetzt ist nur noch ein Draht (+GND) zur Datenausgabe notwendig und ein paar weitere Chips vergraben:-)
.-----------------------------. VCC
| | +
| | | |
.-. .-. | |
| |20k | |<------------o |
| | | |3k | |
'-' 1/4 TC4093 '-' --- 1nF |
| __ | __ --- |
'----| \ | .-| \ | | __ clock
| )o----o--| | )o----o---------)-----------| \ out
.--|__/ -|__/ | | | )o->
| 115200Hz | | .-|__/
'-----. | | ___ |
| .---o-)---------o--|___|--o
| | | | 100k |
| | | | | data
.---------)---------------)---)-)-------------------)-------->
| | | | | | out
| | | .-)-)---. |
| | | | | |___| | GND
| | | | | |CP1|Q9 | .----
uart | | | | | | | | | | | |
in (RX)| __ | o_o_o_o_o_o_o_o | |
>------o--| \ | | MR HEF4017 | | |
115200 | )o-' |1_ _ _ _ _ _ _ | | |
8n1 .--|__/ o o o o o o o o BS170 | |
>-. | | | | | | | | | |-+ |
| | |Q0 | | |
| '-----------------------------o---------)-------->|-+ |
| | | |
| | | |
| | | |
=== === === ===
GND GND GND GND
(created by AACircuit v1.28.6 beta 04/19/05 www.tech-chat.de)
Der Taktgenerator beginnt mit dem Startbit an zu arbeiten und erzeugt 9 Takte bevor er vom Johnson Counter 4017 und dem Stopbit wieder gestoppt wird. Das Ausgangsgatter für clock out läßt nur 8 high Flanken passend zu den 8 Datenbits passieren, die für das richtige Arbeiten der Schieberegister im Display wichtig sind.
Über das 3k Poti muß der Taktgenerator auf die Baudrate vom RX abgestimmt werden. Ist praktisch, da es mein Tiny mit internem Oszillator und SW-UART mit der Genauigkeit da nicht so genau nimmt.
Ohne ausführlich Tests und guter Einstellung klappte das sehr gut mit 115200 Baud.
Gruß
Searcher
Besserwessi
07.08.2011, 21:49
Bei dem Aufwand wäre ein Tiny2313 wohl wirklich einfacher.
Hallo!
Hardwaremässig sicher, aber soft-, spass- und zeitmässig ? :lol:
Searcher
08.08.2011, 10:55
Bei dem Aufwand wäre ein Tiny2313 wohl wirklich einfacher.
Hardwaremässig sicher, aber soft-, spass- und zeitmässig ?
Nachdem ich ja sowieso ein Programmierkabel habe, BASCOM funktionierend installiert ist und ich mich in die AVR Programmierung auch etwas eingearbeitet habe, damit ich die Anzeigedaten vom µC aus überhaupt auch schicken kann, wäre der Aufwand die 3-2-1-Adern Schnittstellen zur Siebensegmentanzeige alle auf einem kleinen µC zu vereinigen, sicher nun auch für mich zu bewältigen und schneller mit weniger HW Aufwand zu realisieren.
In diesem Fall übt das jedoch seltsamerweise keinen Reiz auf mich aus. Wäre möglicherweise schon zuuU einfach?!?
Während der unumgänglichen Beschäftigung mit RS232 empfand ich Bewunderung für den praktischen Aufbau des Protokolls und begann über Ursache und Wirkung zu sinnieren. Erst Protokoll und danach die HW oder mit vorhandener HW das Protokoll? Egal, die Phase wird vorübergehen :-) und danach werd ich mir auch keine Gedanken mehr machen, ob in meinen verwendeten Chips oder in einem µC mehr Transistoren involviert wären :-)
Ich glaube jetzt hat das Streben noch weitere Adern einzusparen so langsam ein Ende. Die Übertragung der Daten kann noch über IR erfolgen, aber mindestens ein Übertragungsmedium wird man brauchen:-)
Gruß
Searcher
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.