Forum: Mikrocontroller und Digitale Elektronik 1 Controller nur für Multiplexing??


von Sebastian (Gast)


Lesenswert?

Hi,

ich bastel gerade an einer kleinen Anzeige mit 8x 16 segmentanzeigen. 
Ich habe bei meinem ersten Sample einen Mega16 für das Multiplexing 
verwendet (ich brauche da keine Schieberegister, grins) und einen Mega 
168 für die eigentliche Applikation. Ich hatte auch versucht die 
Applikation mit in den M16 (multiplexer) zu bauen, allerdings habe ich 
folgende Probleme: Die empfangenen Daten (ca 192 bytes) kommen sehr 
schnell, daher kann ich selbst bei 20Mhz keine unterbrechung der 
Empfangsroutine (I²C) erlauben, sonst kommt nur Kauderwelsch an.
Ich habe versucht, das ganze so kurz wie möglich zu machen, also wird 
für jede Stelle der Inhalt vorher im Ram abgelegt, damit in der 
Multiplex-routine keine Berechnungen gemacht werden müssen. Leider 
dauert es immernoch zu lange..... :-(
Unterbreche ich für die Zeit des Empfangs den Multiplexer, ist ein 
deutliches Flackern (störend) zu erkennen.

Ich finde einen Mikrocontroller für NUR Multiplexing zu verwenden ist 
ganz schön vermessen. Ich hatte schon überlegt mit einem Ram und ein 
bisschen Logik das Multiplexing zu erledigen, aber da habe ich ja jede 
Mege Platinenplatz verschwendet... Was denkt ihr ist die bessere 
Alternative?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

I²C erlaubt es (normalerweise) durch Clockstretching den Sender 
anzuhalten, wäre das nicht eine möglichkeit?
Was für daten sind das überhaupt und wie hast du das Multiplexing 
realisiert? Doch hoffentlich nicht mit Warteschleifen ;)

Ansonsten könntest du auch das Multiplexing in der Mainloop machen und 
den I²C Empfang im Interrupt Betrieb. Erzähl einfach mal etwas mehr über 
die Anwendung. Denn "sehr schnell" und I²C bei 20Mhz hört sich doch 
etwas komisch an, ich dachte I²C geht nur bis zu ein paar khz

von Matthias L. (Gast)


Lesenswert?

>Die empfangenen Daten (ca 192 bytes) kommen sehr
>schnell, daher kann ich selbst bei 20Mhz keine unterbrechung der
>Empfangsroutine (I²C) erlauben, sonst kommt nur Kauderwelsch an.

Mit den Infos behaupte ic mal, dass das ein Konzept-problem in der 
Software ist. Das sollte immer möglich sein.

>8x 16 segmentanzeigen.
Somit hast du pro Segment ein word. und das acht mal. Also könnte der 
"video"speicher (mit zähl- und Hilfsvariable) etwa so deklariert sein:
1
struct scVideo
2
{
3
  uint16_t au16Data[8];
4
  uint8_t  au8ColMsk[8];
5
  uint8_t  u8Col;
6
};

Die Multiplexroutine könnte jetzt etwa so aussehen:
(Ich nehme mal an, das "Port1" die Bits 0..7,
das "Port2" die Bits 8..15 der 16-Segmetanzeige ist,
und das Port3 die Ansteuerung ist: Port3.0 -> Segment 0 ...)
1
ISR (irgendein Timer, viell. alle 1ms)
2
{
3
  //-- nächste Spalte 0..7 -----------
4
  scVideo.u8Col++; 
5
  scVideo.u8Col &= 0x07;
6
  //-- Element ausgeben --------------
7
  PORT1 = (uint8_t)  (scVideo.au16Data[scVideo.u8Col]     );
8
  PORT2 = (uint8_t)  (scVideo.au16Data[scVideo.u8Col] >> 8);
9
  PORT3 = scVideo.au8ColMsk[scVideo.u8Col];
10
}

Damit das funktioniert, muss vorher einmalig das Hilfsarray au8ColMsk 
folgendermassen initialisiert werden:
[c]
_u8TempMask = 0x01;
u8TempWhile = 0x00;
while ( _u8TempWhile!= 8 )
{
  scVideo.au8ColMsk[u8TempWhile++] = u8TempMask ;
  u8TempMask <<= 1;
}
[c]

Das arbeitet unabhängig von deiner Empfangsroutine. Jetzt kannst du, wo 
auch immer, in das Array scVideo.au16Data[] 16bit Werte reinschreiben.
Diese werden einfach angezeigt.


Aber denke dran: Die Werte in der Anzeige müssen nicht wirklich 
schneller als fünfmal in der Sekunde geändert werden, schneller sieht 
das Auge eh nicht...

von Sebastian (Gast)


Lesenswert?

Clockstretching fällt aus, der "Sender" haut die daten immer stupide 
raus.das is kein richtiges i²c.

die Multiplexroutine sieht so aus

timer1_irq:

Timer1 = Timervorgabe

Portc = 255
Porta = 255
Portd.7 = 1
Portb = 0

Incr Segment
If Segment = 9 Then Segment = 1

Porta = Byte1(segment)
Portc = Byte2(segment)
If Byte3(segment) = 128 Then Portd.7 = 0

If Segment = 1 Then Portb = 1
If Segment = 2 Then Portb = 2
If Segment = 3 Then Portb = 4
If Segment = 4 Then Portb = 8
If Segment = 5 Then Portb = 16
If Segment = 6 Then Portb = 32
If Segment = 7 Then Portb = 64
If Segment = 8 Then Portb = 128
Return



Daten einlesen komplett interruptfrei

variable = 0
i = 8
Do
Decr i

Do
Loop Until in_cl = 0       '# Wir warten auf die nächte HIGH Flanke
Do
loop until in_cl = 1

variable_i = in_da
Loop Until i = 0

'ack überspringen
Gosub Sub_jmpack

von Matthias L. (Gast)


Lesenswert?

Ich sag es doch:

Konzeptfehler!

machs so, wie vorgeschlagen!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.