ATmega als "Ersatz" für MAX7219

Gast #4551451
Lesenswert?

Hallo zusammen!

Ich habe hier ein Gerät mit 7-Segment-Anzeigen mit insgesamt 12 Stellen.
Die 7-Segment-Anzeigen werden mit 2 MAX7219 angesteuert.
Nun möchte ich die angezeigten Daten gerne mit einem ATmega abgreifen 
und dann über UART ausgeben.

Die MAX7219 werden ja (wenn ich das richtig verstanden habe) über SPI 
angesteuert. Kann ich da einfach den ATmega ZUSÄTZLICH mit dranhängen? 
Also die Anzeige soll danach trotzdem noch funktionieren.

Leider habe ich von SPI nicht wirklich viel Ahnung. Hat jemand schon mal 
so etwas gemacht und vielleicht ein bissche C-Code für mich? :)

Ich danke euch jetzt schon mal^^
Gast #4551570
Lesenswert?

Da sieht man, wie bekloppt das AVR-SPI ist.
Möglich wäre auch
- die SPI-Daten paral. in Shift-Register zu übertragen,
    und das dann (ser. oder par.) auszulesen
- direkt am MAX-Baustein die DIGITs u SEGMs abzugreifen
    (ist zeitl ja viel langsamer)
- andere CPU, bsp PIC24 (die haben zudem SPI-FIFOs) für SPI
Gast #4553055
Lesenswert?

Guten Abend!

Erstmal vielen Dank für die Antworten.

Ich habe mir die Schaltung nochmal genauer angeschaut.
Also kaskadiert sind die zwei MAX wohl nicht. Beide haben getrennte 
"LOAD" Leitungen - DIN ist bei beiden direkt verbunden, DOUT bei beiden 
unbelegt.

Das abgreifen nach dem MAX fällt wohl eher weg... Da bräuchte ich ja 
Unmengen an IO-Pins (12x DIG + 2x (für jeden MAX7219) 8 Segmente = 28 
PINs, oder?^^)

Wie gesagt kenne ich mich mit SPI eigentlich überhaupt nicht aus.

Habe zwar schon das ein oder andere Projekt mit AVRs umgesetzt, jedoch 
noch nie irgendwas mit SPI (selbst) gemacht. Wenn dann eher Copy&Paste^^


Angenommen ich versuche das jetzt einfach mal mit nem ATmega und schaue 
ob der damit zurechtkommt.
Die Leitung die am MAX7219 zu DIN geht muss am ATmega dann an MOSI, 
oder?
Was mache ich mit den LOAD Leitungen?
Und was ist mit CLK?

Sorry, aber ich blicke gerade einfach nicht durch.
Auch wenn ich mich wiederhole: Bin totaler SPI noob :(

Ich danke euch für eure Geduld :)
#4553286
Lesenswert?

Sind es nur Ziffern, müßten 5 Segmente reichen.
Der Multiplextakt (max 1,3kHz) ist ja konstant, es reicht also ein 
Synchronsignal, was man dann mit dem Timerinterrupt unterteilt.
Dann sollten 12 Inputs reichen.

Mit SPI ist eh tricky, da man nicht weiß, ob das Latchsignal nur am Ende 
erfolgt und man für 2 Latchsignale nur einen /SS-Pin hat.
Gast #4553561
Lesenswert?

Es sind leider nicht nur Ziffern - auch der Dezimalpunkt wird benötigt 
:(

Mir ist gerade eingefallen das mein Multimeter auch Frequenzen messen 
kann (lt. Anleitung von 10 Hz bis 10 MHz) - zwar sicher nicht so genau 
wie ein Oszi, aber als Anhaltspunkt bestimmt verwendbar.
Angezeigt wird ein Wert von 79.24 Hz. Das ist nicht sonderlich schnell, 
oder?(Übrigens ist die Leitung zwischen dem Haupt-µC und dem Bedienteil 
rund 3 Meter lang)
#4553617
Lesenswert?

@ MCUA (Gast)

>Da sieht man, wie bekloppt das AVR-SPI ist.

Nobody is perfect. Da der AVR sowieso nix besseres zu tun hat, kann er 
das SPIIF Flag auch pollen, das geht sehr schnell. Dann klappt das auch 
mit einer schnelleren Übertragung. Ausserdem haben die neueren AVRs 
einen UART, der im SPI-Mode laufen kann, man bräuchte hier also einen 
größeren AVR mit 2 UARTs. Oder man sendet die Daten mit einem Soft-UART, 
das ist auch eher unkritisch.

Zusätzlliche Hardware ist zwar möglich, aber eher uncool, zuviel 
Aufwand.
Man kriegt das mit dem AVR in Software hin.
Gast #4553785
Lesenswert?

>Nobody is perfect.
bekloppt ist aber mehr als 'nicht perfekt'
selbst ein STM8 für 0,25eu hat da Buffer!

>Da der AVR sowieso nix besseres zu tun hat, kann er
>das SPIIF Flag auch pollen, das geht sehr schnell. Dann klappt das auch
>mit einer schnelleren Übertragung.
pollen ist norm. die allerschlechteste Lösung.

>Ausserdem haben die neueren AVRs
>einen UART, der im SPI-Mode laufen kann
aber nur im Master-Mode

>Besser als Software müsste es sein, wenn man einen Controller hat,
>der die SPI per DMA auslesen kann.  Sollte eigentlich schon ein
>Xmega können oder ein kleiner ARM halt.
Auch der Xmega (mit DMA) hat da kein reibungslosen Ablauf, weil auch 
dort der betr. Buffer fehlt! (DMA ersetzt nicht diesen Buffer)
Moderator Persönliche Seite #4553789
Lesenswert?

MCUA schrieb:
> Auch der Xmega (mit DMA) hat da kein reibungslosen Ablauf, weil auch
> dort der betr. Buffer fehlt! (DMA ersetzt nicht diesen Buffer)

Bei DMA benutzt du den RAM als Puffer.

Bist du etwa der Meinung, der SPI-Modul dort hätte das Schieberegister
direkt als Datenregister?  Nein, das sind schon zwei getrennte, man
kann also das Datenregister (so gesehen ein einstufiger Puffer) lesen,
während das nächste Byte reingetaktet wird.  Man muss es halt nur
gelesen haben, bevor die nächsten 8 Taktimpulse vom Master durch
sind.
Gast #4553839
Lesenswert?

Nochmal, das SPI beim xmega ist das gleiche wie beim xmega (mit den 
bekanten Nachteilen), und DMA kann (den) fehlende(n) Buffer Nicht 
ersetzen.
Jeder halbwegs vernünftige uC hat selbstverständlich entspr. 
Buffer-Register am SPI, auch wenn DMA (und evtl zus FIFOs) vorhanden.
bloss AVR nicht.
Moderator Persönliche Seite #4553843
Lesenswert?

MCUA schrieb:
> Nochmal

Nochmal: was ist für dich ein “buffer” in diesem Zusammenhang?

Selbstverständlich hat der SPI-Empfänger im AVR (und Xmega) einen
solchen, ob du das nun wahrhaben willst oder nicht.  Inwiefern man
die Behauptung des Datenblatts:
1
The system is single buffered in the transmit direction and double buffered in the receive direc-
2
tion.

nun teilen mag oder als Marketinggeschwätz abtut, ist Ansichtssache.
Für mich wäre es eher ungepuffert in Senderichtung und einfach
gepuffert in Empfangsrichtung.  Die nächsten Sätze dokumentieren
das dann aber ziemlich klipp und klar:
1
 This means that bytes to be transmitted cannot be written to the SPI Data Register before
2
the entire shift cycle is completed. When receiving data, however, a received character must be
3
read from the SPI Data Register before the next character has been completely shifted in. Oth-
4
erwise, the first byte is lost.

Damit kann man im Zusammenhang mit DMA (beim XmegaA) auf jeden Fall
beliebig lange Bytefolgen erstmal in den RAM gelesen bekommen ohne
zu riskieren, dass ein Byte verloren geht.

SPI-Antwortverhalten ist bei einem Software-Slave natürlich immer
noch ein anderes Problem, aber das steht ja in diesem Falle hier
gar nicht.
#4553844
Lesenswert?

AVRs ersetzen halt die ehere magere Peripherie durch einen (für 
8-Bitter) ziemlich potenten Prozessor.
Bei dem TO würde ich locker 20€ verwetten, dass ein AVR (zumindest wenn 
der Programmierer kein Idiot ist) das SPI spielend "mitlesen" kann ohne 
eine FIFO oder so einen Kram (allein die mehreren Meter Kabel diktieren 
schon eine langsame Taktrate).
Gast #4553846
Lesenswert?

>The system is single buffered in the transmit direction and double >buffered in 
the receive direction.
Das stand früher so da, was klar falsch ist. Nun haben die es verbessert 
(nur den Satz im DB, aber nicht das Interface!).
Gast #4553863
Lesenswert?

Martin Schenk schrieb:
> (Übrigens ist die Leitung zwischen dem Haupt-µC und dem Bedienteil
> rund 3 Meter lang)

Das läßt doch hoffen, daß die CLK-Frequenz nicht allzu hoch ist. Diese 
CLK-Frequenz solltest Du auch messen - zur Not per Timer1 Deines AVR 
(Abstand zwischen zwei pos. Flanken an ICP1)!
Bis rund 50 kHz kann man die seriellen Daten dann auch per ISR einlesen.
Moderator Persönliche Seite #4553882
Lesenswert?

MCUA schrieb:
> Das stand früher so da, was klar falsch ist. Nun haben die es verbessert
> (nur den Satz im DB, aber nicht das Interface!).

Im Datenblatt des ATmega328PB (*) steht das nach wie vor genauso.
Updated: 10/2015.

(*) Einer der neuesten AVRs, schätzungsweise ja auch einer der letzten –
der ATtiny104 ist neuer, hat aber keinen SPI-Slave.

Wie ist es denn deiner Meinung nach?  Womit hast du das getestet?
Gast #4553994
Lesenswert?

Ohje, da hab ich ja ne Diskussion losgetreten :D

Ähm... Die f

Axel R. schrieb:
> auf welcher Leitung denn, bitte? Das konnte ich nicht heraus lesen...

Ähm... Gemessen hab ich zwischen GND und CLK am MAX... Keine Ahnung ob 
das korrekt war :D


Ich werde jetzt am WE einfach mal etwas rumtüfteln und schauen was dabei 
rauskommt. Ich danke euch jedenfalls jetzt schon mal für eure Hilfe :)
#4554058
Lesenswert?

@ MCUA (Gast)

>bekloppt ist aber mehr als 'nicht perfekt'
>selbst ein STM8 für 0,25eu hat da Buffer!

Bla. Daß der AVR hier eine Schwäche hat ist bekannt. So what!
In diesem Fall ist das durch Knoff Hoff kompensierbar!
Man könnte es auch eine Herausforderung nennen.

>pollen ist norm. die allerschlechteste Lösung.

Hier ist es schlicht ausreichend und voll OK. Siehe mein LCD-Expander.

>Auch der Xmega (mit DMA) hat da kein reibungslosen Ablauf, weil auch
>dort der betr. Buffer fehlt! (DMA ersetzt nicht diesen Buffer)

Quark. Du kannst das SPI vom ATXmega im Slave Modus mit bis zu 1/4 F_CPU 
dauerhaft mit Daten füttern, es wird bei DMA-Nutzung KEINERLEI Daten 
verschlucken. Und das bei 0% CPU-Last. Reicht das?
Gast #4554089
Lesenswert?

hallo martin,
das klingt nach einer interessanten aufgabe was du da vorhast.

das "mitlauschen" auf den spi-leitungen ist sicher kein problem.
wie schon erwähnt muss der avr als spi slave arbeiten. eine 5V-Type wäre 
sinnvoll.

DIN des MAX9219 verbindest du mit MOSI des avr.
CLK des MAX9219 verbindest du mit SCK des avr.
die beiden LOAD der MAX9219 führst du über ein AND-gatter auf SS* des 
avr und npcjh jeweils auf ein port, welches einen interrupt auslöst, 
wenn CS* low wird. damit kann der avr erkennen, welcher MAX7219 
angesprochen wurde.

wichtig ist noch rauszufinden, welcher spi mode verwendet wird.
CPOL=0, CPHA=1 müsste pasen.

btw: ein scope ist für so einen fall kein fehler.
eine billige alternative ist in dem fall ein "logikanalysator" wie der 
Logicport (http://www.pctestinstruments.com/).

gruss
gerhard
Gast #4557325
Lesenswert?

In einem DB schreiben die:
"The system is single buffered in the transmit direction and double 
buffered in the receive direction."
In anderem DB schreiben die:
"The SPI module is unbuffered in the transmit direction and single 
buffered in the receive direction."
Also 2 verschiedene Aussagen fürs gleiche Interface, "toll" oder?

Danach steht dann jeweils:
"This means that bytes to be transmitted cannot be written to the SPI 
Data Register before the entire shift cycle is completed.",
und was nat. die völlige Unzulänglichkeit dieses Interfaces zeigt.



>>Auch der Xmega (mit DMA) hat da kein reibungslosen Ablauf, weil auch
>>dort der betr. Buffer fehlt! (DMA ersetzt nicht diesen Buffer)
>Quark.
Der Quark von Intel. Die könnens nämlich, Atmel nicht.


>Du kannst das SPI vom ATXmega im Slave Modus mit bis zu 1/4 F_CPU
>dauerhaft mit Daten füttern, es wird bei DMA-Nutzung KEINERLEI Daten
>verschlucken. Und das bei 0% CPU-Last.
Damit willst du (bewusst oder unbewusst) Kaschieren, dass das Kein 
vollwertiges SPI-DMA-Interface ist.
Moderator Persönliche Seite #4557339
Lesenswert?

MCUA schrieb:
> und was nat. die völlige Unzulänglichkeit dieses Interfaces zeigt.

Oben hast du noch stock und steif behauptet, es wäre in
Empfangsrichtung absolut ungepuffert und daher völlig unzulänglich.

Ja, die Aussagen sind wischiwaschi, ich würde sie in Empfangsrichtung
auch als einfach gepuffert bezeichnen.  Das ist aber ein großer
Unterschied zu ungepuffert: Wenn in Empfangsrichtung das Schieberegister
nicht nochmal gepuffert ist, kann man in der Tat nicht garantieren,
dass da kein Datenverlust eintritt.  Es ist aber gepuffert (Schiebe-
und Datenleseregister sind getrennt).  Damit kann man auch
„Rücken-an-Rücken“-Daten lesen, sofern die CPU es schafft, innerhalb
eines Bytes das vorherige abzuspeichern, die Zeiger zu erhöhen und
das Ende der Transaktion zu testen.  (Bei DMA geht dies alles ohne
CPU.)

Dass es in Senderichtung nicht nochmal gepuffert ist, bedeutet
lediglich, dass man keine „Rücken-an-Rücken“-Daten raussenden kann,
da zwischen den Bytes noch eine kleine Denkpause nötig ist (Flag
pollen, danach Senderegister neu laden).  Das ist aber nun alles andere
als „völlig unzulänglich“.
#4557429
Lesenswert?

@Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite

>und Datenleseregister sind getrennt).  Damit kann man auch
>„Rücken-an-Rücken“-Daten lesen, sofern die CPU es schafft, innerhalb
>eines Bytes das vorherige abzuspeichern, die Zeiger zu erhöhen und
>das Ende der Transaktion zu testen.

Da man so oder so max. 1/4 CPU Takt als SP-Takt verwenden kann (Slave 
mode!), hat die CPU min. 32 Takte dafür Zeit.
Das reicht locker. Zumal sie sinnvollwerweise per Interrupt sofort auf 
eine fallende FLanke des SS Signal reagiert und dann dort in einer 
Polling-Schleife die Daten einliest.

>Dass es in Senderichtung nicht nochmal gepuffert ist, bedeutet
>lediglich, dass man keine „Rücken-an-Rücken“-Daten raussenden kann,
>da zwischen den Bytes noch eine kleine Denkpause nötig ist (Flag
>pollen, danach Senderegister neu laden).

Und selbst das hat keinen davon abgehalten, ein Videoterminal in 
Software mit dem AVR zu generieren. Wahnsinn!!
Und die GANZ GROßEN Könner haben sogar richtig gute Animationen + 
Midi-Sound generiert.
Oder die diversen Mini-Spielkonsolen.

Das andere Ende des Leistungsspektrums verlegt sich halt auf seine 
Kernkompetenz des Jammerns und Meckerns.
Auch Fußpilz hat seine göttliche Daseinsberechtigung ;-)
Gast #4558605
Lesenswert?

>> und was nat. die völlige Unzulänglichkeit dieses Interfaces zeigt.
>Oben hast du noch stock und steif behauptet, es wäre in
>Empfangsrichtung absolut ungepuffert und daher völlig unzulänglich.
Nein, hab ich nicht.
Ich sagte, es hat keinen Buffer. Nicht, es hat keinen RX-Buffer.

>ich würde sie in Empfangsrichtung auch als einfach gepuffert bezeichnen.
(betr RX-Buffer) hab ich nicht bestritten.
>..sofern die CPU es schafft, innerhalb eines Bytes das vorherige abzuspeichern,
das sollte der Normalfall (ohne DMA) sein.

>Da man so oder so max. 1/4 CPU Takt als SP-Takt verwenden kann (Slave
>mode!), hat die CPU min. 32 Takte dafür Zeit.
(nur betr RX) ist völlig normal, streitet keiner ab.
aber bei gleichzeit. TX gehts so nicht mehr,
da bremst der fehlende TX-Buffer das RX aus!


>Dass es in Senderichtung nicht nochmal gepuffert ist, bedeutet lediglich...
nicht 'lediglich'. Das ist extremer Design-Mangel(!), weil es dadurch 
viel zu lange dauert bzw viel zu lange unterbrochen wird.
Insbes ist da kein continuierl. Fluss möglich (obgleich das beim RX der 
anderen Seite keinen Fehler ergeben muss).
Diesbez hilft da DMA nichts (auch nicht bei 1/4 CPU-Takt), weil DMA das 
niemals so schnell nachladen kann.


Jede stinknormale moderne CPU (bzw Controller) hat SPI mit RX-TX-Buffer,
insbes. dann, wenn noch DMA vorhanden ist.
Diesen Witz gibts nur bei Atmel.
#4558668
Lesenswert?

MCUA schrieb:
>>Oben hast du noch stock und steif behauptet, es wäre in
>>Empfangsrichtung absolut ungepuffert und daher völlig unzulänglich.
> Nein, hab ich nicht.
> Ich sagte, es hat keinen Buffer. Nicht, es hat keinen RX-Buffer.

Den TS interessiert aber nun mal nur eine Bufferung in RX-Richtung. 
Können wir uns darauf einigen, dass seine Anwendung mit dem ATmega-SPI 
problemlos möglich ist?

Gruß, Stefan
#4558717
Lesenswert?

Stefan K. schrieb:
> Können wir uns darauf einigen, dass seine Anwendung mit dem ATmega-SPI
> problemlos möglich ist?

Nein.
Wir kennen das Timing nicht und ob überhaupt das notwendige /SS anliegt.
Oft wird für das LOAD nur eine kurzer 0-1-0 Puls erzeugt.

Und da es 2 nicht kaskadierte MAX7219 sind, müßte er die beiden LOADs 
noch irgendwie verwursten.
Man könnte die beiden LOADs auf Interrupts legen und der AVR erzeugt 
dann sein /SS selber über einen Output-Pin.
In der Hoffnung, daß nach jedem LOAD genügend lange gewartet wird, um in 
den Interrupt zu springen.

Wenn ich mir aber mal meinen MAX7221 Code ansehe, sende ich immer alle 8 
Digits am Stück ohne Pause.
Z.B. 3 MAX7221 kaskadiert:
1
void max7221_update()                           // need about 220µs @ 4MHz SPI clock 
2
{
3
  max7221_init();
4
  for( uint8_t i = 1; i < 9; i++ ){             // Digit 1 .. 8
5
    xMAX7221 = 0;
6
    max7221_out( i );
7
    max7221_out( display_data[i-1] );           // 1. MAX2771
8
    max7221_out( i );
9
    max7221_out( display_data[i+7] );           // 2. MAX2771
10
    max7221_out( i );
11
    max7221_last_out( display_data[i+15] );     // 3. MAX2771
12
    xMAX7221 = 1;
13
  }
14
}
Moderator Persönliche Seite #4558731
Lesenswert?

Peter D. schrieb:
> Wir kennen das Timing nicht und ob überhaupt das notwendige /SS anliegt.

Das ist allerdings ein völlig anderes Paar Schuhe dann.  Damit
wird man mit so ziemlich jeder MCU als Slave Probleme bekommen,
denn die wollen alle ein slave select haben, bevor die SPU unit
lostickt.  Ist halt nicht einfach nur ein Schieberegister.

Nur so als Schnapsidee: Einen Xmega nehmen, /SS ständig auf low,
Einlesen per DMA, mit dem Ladeimpuls ein Event generieren, welches
das zuletzt eingelesene SPI-Byte dann weiterverarbeiten lässt.
Gast #4558785
Lesenswert?

Jörg W. schrieb:
> Ich vermute mal, der TE hat nichts dafür geeignetes an Messgeräten.

Er hat doch einen ATmega, mit dem er auch hinreichend genau messen und 
per UART den Wert ausgeben kann.
Ferner kann er die Signale auf Verdacht einlesen und dabei sehen, ob es 
wie gewünscht funktioniert. Zunächst einen Kanal und dann den zweiten 
dazu nehmen.
Gast #4558813
Lesenswert?

Jörg W. schrieb:
> Den von Peter genannten kurzen Spike zur Übernahme der Daten in ein
> Schieberegister findest du damit nicht.

Dieser Spike ist zunächst virtuell und bei 3 m Anschlußleitung real wohl 
überhaupt nicht vorhanden. Aufspühren könnte man ihn dennoch mit einem 
flankenempfindlichen INTx oder ICP1-Eingang.

Jörg W. schrieb:
> Nein, ein ATmega taugt für manches, aber nicht als LA-Ersatz. ;-)

Es geht nicht darum, das exakte Timing zu dokumentieren, sondern die 
ser. Daten einzulesen und weiterzureichen. Ein kleines Programm zeigt 
recht schnell, ob es geht oder auch nicht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren