Forum: Mikrocontroller und Digitale Elektronik Pollin Display 12232, in ASM klappts, in C nicht


von J. T. (chaoskind)


Angehängte Dateien:

Lesenswert?

MoinMoin,

ich hatte mal eine Routine in ASM geschrieben, um dieses Datavision 
Display von Pollin anzusteuern. Ich hab versucht diese nun in C 
umzusetzen, aber irgendwie klappt das ganze nicht so recht.
Ich arbeite mit Atmel Studio6, win8.1, nem JTAG ICE3 und nem Tiny2313.

Das Display ist angeschloßen wie im Quelltext, in ASM klappts ja auch...

Die beiden Quelltexte mal als Anhang.

Wenn ich das ganze per debugwire debugge, kann ich in ASM beliebige 
"pixel" senden, wenn ich per Hand den entpsrechenden Port setze, und 
dann per Hand Enable aus und wieder an schalte. Im C-teil geht auch das 
nicht, daher vermute ich, das der Fehler irgendwo in der Initsequenz 
steckt, jedoch finde ich ihn nicht, für hilfreiche Hinweise wäre ich 
dankbar =)

MfG Chaos

von Thomas (kosmos)


Lesenswert?

habe gerade mal das .asm File "gebuildet" 235 bytes, jetzt würde mich 
mal das .c File interessieren, leider bekomme ich es nicht gebacken es 
zu compilieren. Oder kann das mal jemand machen der AVR Studio WinAVR 
und Gnu Plugin drauf hat.

von Fer T. (fer_t)


Lesenswert?

Thomas O. schrieb:
> habe gerade mal das .asm File "gebuildet" 235 bytes, jetzt würde mich
> mal das .c File interessieren, leider bekomme ich es nicht gebacken es
> zu compilieren. Oder kann das mal jemand machen der AVR Studio WinAVR
> und Gnu Plugin drauf hat.

Wenn ich die C Datei kompiliere bekomme ich folgendes (mit AVR-GCC):

AVR Memory Usage:
-----------------
Device: attiny2313

Program:     362 bytes (17.7% Full)
(.text + .data + .bootloader)

Data:          1 bytes (0.8% Full)
(.data + .bss + .noinit)


Errors: none

MfG,
Fer_T

von J. T. (chaoskind)


Lesenswert?

Mhhh fehlerfrei kompilieren kann ich es auch, bei mir wirds aber 364 
byte groß.. ich hatte testhalber auch mal ohne optimierung kompiliert, 
da sind aber 146% speicher voll oder sowas in der Größenordnung 
rausgekommen.
Es sieht auch so aus, als würd er die Wartezeiten wegoptimieren, wenn 
ich nämlich die Wartezeiten zwischen den EN aus an Sequenzen im ASM 
weglasse, läuft es auch nicht mehr....

Ich hab nun auch schon erfolglos versucht, die Wartezeiten zu 
verlängern, jedoch optimiert er die scheinbar weiter weg...

P.S. in C und vor allem den ganzen Toolchain/makefile und 
wer-weiß-nich-was-Geschichten bin ich noch völlig grün hinter den Ohren.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

j. t. schrieb:

> Ich hab nun auch schon erfolglos versucht, die Wartezeiten zu
> verlängern, jedoch optimiert er die scheinbar weiter weg...

Ganz sicher nicht.

Die _delay_ms Zeiten stimmen nur dann, wenn du
* den Optimizer auf -Os stehen hast
* F_CPU der Wahrheit entspricht

Läuft dein µC wirklich mit 8Mhz?
Hast du es kontrolliert?

von Karl H. (kbuchegg)


Lesenswert?

Ich habs jetzt nicht nachgerechnet.
Aber das hier
1
del1ms:
2
3
  ldi    a2,2
4
  ldi    a1,73
5
6
  del1ms1:
7
8
    dec    a1
9
    brne  del1ms1
10
    dec    a2
11
    brne  del1ms1
12
    ret
ergibt doch nie und nimmer 1ms bei 8Mhz. Da brauch ich gar nicht 
rechnen.

: Wiederhergestellt durch User
von J. T. (chaoskind)


Lesenswert?

Grad nochmal kontrolliert, die Fuse ist auf interner 8MHz, mit längster 
Anlaufzeit. Die Optimierung stand aber auf -O1 habs nun auf -Os 
versucht, jedoch auch erfolglos.

Ich hab nun nochmal versucht, nachzuverfolgen, ob er die _delay_ms 
aufruft, jedoch verschluckt er sich irgendwo in meiner DispDel().....
Ich versuche das nochmal näher einzugrenzen.

Danke schonmal für eure Versuche =)

von Karl H. (kbuchegg)


Lesenswert?

j. t. schrieb:

> Ich hab nun nochmal versucht, nachzuverfolgen, ob er die _delay_ms
> aufruft

die wird auch im eigentlichen Sinne nicht aufgerufen.
Der Compiler inlined die und erzeugt genauso Warteschleifen, wie du das 
auch gemacht hast. Nur das diesmal die Zeitberechnung der Compiler 
macht.

von J. T. (chaoskind)


Lesenswert?

P.S.
Ja da hast du recht, die Sprungmarke hatte ich anfänglich mal so 
genannt, und mich dann an den Wert rangetastet, wo es dem Display zu 
schnell wurde, und ich hab es nur nicht umbenannt.
Aber dennoch ein guter Hinweis fürs C-Programm wenn es denn mal läuft, 
da kann man dann sicher auf _delay_us(irgendwas in der größenordnung10 
oder so) ausweichen.

von J. T. (chaoskind)


Lesenswert?

hmmmmmmm....
Also das _delay_ms "führt" er anständig aus...
1
void DispDel(void)
2
{
3
  uint8_t i = 0;
4
  
5
  LCD_Data = 0;
6
  
7
  
8
    DispCtrl &= ~(1<<A0);
9
    DispData = Page0;
10
    ACK();
11
    DispCtrl |= (1<<A0);
12
        
13
    i = 0;
14
    while(i<61)
15
    {
16
      DispWrite();
17
      i++;
18
    }
jedoch optimiert er mir das i hier weg, das wird vermutlich der Grund 
sein, das er sich dort "aufhängt".
Ist dies einer der Fälle für dieses ominöse volatile?

also würde es mit
1
void DispDel(void)
2
{
3
  volatile uint8_t i = 0;
4
  
5
  LCD_Data = 0;
6
  
7
  
8
    DispCtrl &= ~(1<<A0);
9
    DispData = Page0;
10
    ACK();
11
    DispCtrl |= (1<<A0);
12
        
13
    i = 0;
14
    while(i<61)
15
    {
16
      DispWrite();
17
      i++;
18
    }
funktionieren?
Direkt mal testen...

von J. T. (chaoskind)


Lesenswert?

Nun optimiert er das i nicht mehr weg, jedoch bleibt er immernoch in der 
Funktion DispDel hängen.

Ich hab nach der Funktion einen Breakpoint gesetzt, jedoch wird dieser 
nicht erreicht..
P.S.
Oh doch, nun hat er ihn erreicht, aber das hat ca 3 minuten gedauert... 
ich lasses direkt nochmal laufen

: Bearbeitet durch User
von J. T. (chaoskind)


Lesenswert?

P.P.S.
Nun ist mir noch etwas aufgefallen. Normalerweise blinkt eine der grünen 
LED´s am ICE3 während des freerunning modus beim Debuggen, aber während 
er in dieser "Hängephase" ist, die übrigens immer wieder laaaange 
braucht, ist diese LED aus....

@Fer_t

Das klingt plausibel, dann werd ich mal versuchen, das i doch nicht 
volatile zu machen, sondern in der Zählschleife etwas zu ändern, danke 
dafür.

Mh aber er ruft doch die DisplayWrite auf, in der ja jedesmal der EN aus 
und angemacht wird... Da wird ja also mehr getan, als nur PortD = 0...
Hach ASM ist so schön direkt, was sowas angeht, aber rechnen damit ist 
anstrengend, darum versuch ich mir ja C zu Gemüte zu führen

: Bearbeitet durch User
von J. T. (chaoskind)


Lesenswert?

So ich habs hinbekommen. Der Fehler lag in der DispDel.

statt
1
DispCtrl &= ~(1<<A0);
2
    DispData = Page0;
3
    ACK();
4
    DispCtrl |= (1<<A0);


hätte es
1
DispCtrl &= ~(1<<A0);
2
    DispData = Page0;
3
    ACK();
4
    DispData = Collumn0;
5
    ACK();
6
    DispCtrl |= (1<<A0);
heißen müssen.

Ich hatte einfach vergessen den Collumn Zähler zurücksetzen, so hat er 
zwar mehr oder weniger aufs Display geschrieben, aber in Bereiche, die 
man nicht sehen kann, oder gar völlig ins Leere gehen.

Danke für die Hilfsversuche =)

MfG

Chaos

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.