PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zu doof zum Bits verschieben? [Gelöst!]



Jaecko
14.12.2007, 15:06
Moin.

Bin gerade dabei, ein Handy-Display an nem AVR zum laufen zu kriegen. Geht soweit auch fast.

Um ein Pixel darzustellen, werden 2 Byte = 16 Bit benötigt, wobei die Anzahl der Bits pro Farbe Rot:Grün:Blau = 5:6:5 ist.

Da die Eingabewerte aus dem 3-Byte-System kommen (also pro Farbe 0-255), habe ich eine Funktion, die die Werte entsprechend anpassen soll:

R, G1, G2, B1, ColorData1, ColorData2 jeweils Byte; SendData = Funktion zur Ausgabe der Daten.

Dabei soll das erste Byte (ColorData1) aus den 5 höherwertigsten roten Bits und den 3 höherwertigsten grünen Bits bestehen.
Das zweite Byte (ColorData2) soll aus den Grünbits 4-6 sowie den höherwertigsten blauen Bits bestehen.

Bei einem Testbild klappen die Farben Rot (Setpixel 255,0,0), Gelb (Setpixel 255,255,0) und grün (Setpixel 0,255,0) problemlos.
Nur blau geht irgendwo verloren. Wenn ich mit Setpixel 0,0,255 blau erzeugen möchte, erscheint der Bereich schwarz; gleiches mit weiss (255,255,255): erscheint als gelb.



Sub SETPIXEL(RED AS BYTE , GREEN AS BYTE , BLUE AS BYTE)
If ColorMode = MODE_16Bit Then
R = RED AND &b11111000
G1 = GREEN AND &B11100000
G2 = GREEN AND &B00000111
B1 = BLUE AND &B11111000
SHIFT G1 , right , 5
SHIFT G2 , left , 5
SHIFT B1 , right , 3
ColorData1 = R OR G1
ColorData2 = G2 OR B1
SendData ColorData1
SendData ColorData2
EndIf
End Sub


Schreibe ich statt "SendData ColorData2" gleich "SendData &B00011111" (also alle Blaubits auf 1), dann wird korrekt ein blauer Bereich erzeugt.
In dem Codeteil muss also irgendwo die Information für Blau verlorengehen. Nur find ich nicht wo...

Sieht jemand den Fehler?

MfG

fumir
14.12.2007, 15:40
schau mal in 9.5 ten zeile.
da steckt ein rosaroter panther und malt immer über die blaue farbe drüber :-)

ne - mal im ernst:

erst mal muss es heisen
G2 = GREEN AND &B00011100
sollen ja die zwei niedrigsten bits unter den tisch fallen, oder?

dann muss da sein
SHIFT G2 , left , 3

for_ro
14.12.2007, 15:55
Bist du denn sicher, das BLUE richtig übergeben wird?
Wenn da nichts kommt, kannst du viel hin und herschieben.

Gruß

Rolf

Jaecko
14.12.2007, 15:57
ups... stimmt... hab da die falschen 3 Bits erwischt; sollen tatsächlich die mittleren 3 sein, nicht die letzten... hätte sich wohl auch nur bei "Zwischenfarbstufen" mit grün ausgewirkt;
Der blaue Bereich bleibt aber weiterhin schwarz...

Wenn ich beim Initialisieren des LCD die Befehlsfolge von RGB auf BGR "umdrehe", dann gibts das gleiche Problem, nur eben mit rot; es scheint also so, als wäre ColorData2 immer 0 (was aber nach Simulator nicht der Fall ist)

Nachtrag: der Wert für BLUE wird korrekt übergeben (zumindest lt. Simulator)

fumir
14.12.2007, 17:09
also wenn colordata2 mit > 0 an senddata übergeben wird, dann brauchen wir in obigem code nicht weiter nach fehlern zu suchen!

kann man denn die 16bit wirklich in 2 bytes an das display schicken, oder muss das womöglich in einem rutsch erfolgen (ist der zeitliche abstand zwischen den beiden senddata zu groß)?
womöglich irgendwas am display nicht richtig für die communikation eingestellt?
womöglich ein hardwareproblem (timing bei datenübergabe) ?

was für ein display ist es denn?
ich hab auch mal drüber nachgedacht ein hdy-display zu benutzen.
jemand meinte, die seien schwierig zu kontaktieren, weil die anschlüsse so klein sind.

Jaecko
14.12.2007, 18:15
In dem Codestück find ich ja auch keine Fehler, darum hab ichs ja hier mal reingestellt, ob ja doch einer drin ist.
Dass es in einem Durchgang sein muss, glaub ich nicht, da es ja funktioniert, wenn ich statt dem ColorData2 direkt &B00011111 sende. (oder direkt &B11111111, dann hat das blau nen leichten Grünstich), die Kommunikation an sich klappt, da ja die anderen Farben soweit fehlerfrei arbeiten.

Das Display selbst ist von nem Nokia 6100; Programmvorlage stammt von thomaspfeifer.net; wurde von C nach Bascom übersetzt. Und da isses eigentlich auch so. (Nur werden da vom grünen Wert tatsächlich die letzten 3 Bits verwendet, wie bei dem hier geposteten Code von mir)

Das Problem mit dem Kontaktieren hatt ich auch; mit ner Adapterplatine auf 2,54mm-Raster gehts aber problemlos.

*ratlos*
Scheint wirklich so, als würde das Programm im AVR was anderes machen als im Simulator...

fumir
14.12.2007, 20:16
wenn es mit senddata &B00011111 geht, dann kannst du nur noch die einzelnen zwischenwerte davor kontrollieren.

wenn das alles stimmt, dann könnts natürlich ein compilerfehler sein.
aber das ist nun wirklich sehr unwahrscheinlich (aber nicht unmöglich)
gibts da vielleicht irgendwelche optimierungsoptionen?
die können schon mal dafür sorgen, das der resultierende maschinencode nicht mehr dem hochsprachencode entspricht.

mir ist noch aufgefallen das du einmal &B00xxx und einmal &b00xxx schreibst. aber das ist vermutlich egal, oder?

Jaecko
14.12.2007, 21:59
Gross/Kleinschreibung ist bei Bascom (u.a. auch VBasic, QBasic) im Gegensatz zu C egal.

Aber hab das Problem jetzt umgangen; ich hab mir die Funktion umgebaut, so dass ich die Farbe als HTML-Farbcode-String ("FF00FF" für Magenta z.B.) abspeicher und in der Funktion dann zerlege.

Also die Hex-Anteile in 3 Bytes umwandeln, da dann die gleiche Bit-Schieberei wie im ersten Versuch... und siehe da: So klappts.

Code:



...
'Aufruf:
ColorString = "FFFF00":SetPixelHex
...

Sub SetPixelHex
StrRed = mid(ColorString , 1 , 2)
StrGreen = mid(ColorString , 3 , 2)
StrBlue = mid(ColorString , 5 , 2)
BRed = hexVal(StrRed)
BGreen = hexVAL(StrGreen)
BBlue = hexVAL(StrBlue)
R = BRed AND &B11111000
G1 = BGREEN AND &B11100000
G2 = BGREEN AND &B00011100
B1 = BBLue AND &B11111000
SHIFT G1 , right , 5
SHIFT G2 , left , 3
SHIFT B1 , right , 3
ColorData1 = R OR G1
ColorData2 = B1 OR G2
SendData ColorData1
SendData ColorData2
End Sub

fumir
15.12.2007, 09:05
prima, dann weißt du jetzt, das vermutlich mit der parameterübergabe etwas nicht in ordnung war.

würde sich womöglich lohnen dem problem trotzdem weiter nachzugehen - für künftige programme.

wie ist denn der zusammenhang zwischen logischem UND und bitweise UND beim bascom?
in C gibts ja unterschiedliche operatoren, die u.a. das höchste bit/vorzeichen unterschiedlich behandeln. bei bitoperationen muss man sich solche details immer genau anschauen.

ebenso beim shift. das kann man logisch oder bitweise interpretieren (mit unterschiedlichem ergebnis)

Jaecko
15.12.2007, 12:49
Also lt. Simulator wurden die Parameter davor ja auch übergeben... aber lt. Hardware dann doch nicht. Wo genau da dann was veroren ging, wird sich wohl nie herausstellen.

Soweit ich das in Bascom kenn, sind logisches und bitweises Und der gleiche Befehl (AND), je nach Kontext.
"x = 8 AND 4" liefert x = 0; aber es geht auch "IF x>2 AND x<10"
Beim Shift isses auch so, dass da die Bits verschoben werden, wobei dass dann halt nicht nur bei Byte-Variablen sondern auch z.B. Word geht.
(Anders als bei "Rotate" gehen bei "Shift" die rausgeschobenen Bits verloren)

Naja mit der Technik gehts jetzt; was halt jetzt noch ansteht, ist ne Optimierung, da der Bildaufbau mit 6 sec doch noch etwas lang dauert.
Lt. Datenblatt kann der Controller nen Clock-Schaltabstand von 60ns, in Bascom kann ich aber nur bis 10µs runter, noch kürzere Abstände kann das Display dann doch nicht mehr.
Angenommen ich würde nun ohne Pausen die Ports nacheinander direkt setzen, und dazu würde man nur einen Takt brauchen, dann würde ein Takt bzw. Schaltvorgang bei 8 MHz nur 125 ns dauern, sollte also ohne Pausen auch ausreichen. Aber erst ab Pausen von 10µs reagiert das Display darauf. (Befehl waitus 10 bzw. Sprung in ne Sub mit ein paar NOP drin)

fumir
15.12.2007, 13:51
probier doch mal was bei
shift -3, left, 1
rauskommt.

wenn das ergebnis negativ ist, hat er oben ne 1 und keine 0 reingeschoben.

Jaecko
15.12.2007, 14:37
naja die Syntax bei Shift ist SHIFT Variable, Richtung, Weite.
Aufgefüllt wird hier dann immer mit 0.

Das komische ist ja, dass lt. Simulator alles korrekt verschoben wird; die eigentliche Funktion SendData bekommt dann auch (angeblich!) die Daten korrekt... naja...
Evtl doch ein Problem im Compiler...

Jaecko
15.12.2007, 17:26
Sodele... Fehler gefunden:

Nach einiger Probiererei in Sachen Zeitoptimierung hab ich das mit der Übergabe der getrennten Werte nochmals versucht... und (ich weiss nicht wie) bin auf die Idee gekommen: Hey, was is eigentlich mit dem Soft Stack? Kann ja dann nur daran liegen, dass zwar am PC genug Platz da ist, aber im AVR dann einfach selbiger ausgeht...
Nachgeschaut und Tatsache, der war "nur" auf 8 eingestellt; Nach dem Verdoppeln des Wertes auf 16 läuft diese Möglichkeit auch. Und da somit die ganze Umwandlung von String nach Byte etc. wegfällt, wurde Zeit eingespart und der Bildaufbau beschleunigt.

stefan_Z
15.12.2007, 18:03
Jau, bei so komischem Verhalten und vielen Daten in den Subs muss man die Stacks anpassen...

fumir
15.12.2007, 19:29
ah ja, dann ist das eigentlich ein schwachpunkt der simulation, die sollte eigentlich merken,das der stack des conrollers hier nicht reicht, oder?

Bluesmash
21.12.2007, 21:50
ich habe letztens auch die homepage von thomas pfeifer gefunden und dachte darüber nach den C quellcode in bascom zu übersetzen... währe es möglich das du deinen code hier veröffentlichst? es würden sich sicher viele darüber freuen :) insbesondere ich :)

gruss bluesmash

Jaecko
22.12.2007, 14:20
Also hier im Anhang ist mal der Code. Funktionen sind eigentlich nur das Setzen einzelner Pixel mit 16-Bit-Farbinformation. Aufruf erfolgt über den SetPixel-Befehl, gefolgt von den Werten für Rot, Grün, Blau; jeweils Bytes (0-255); werden dann automatisch in den 16-Bit-Code umgewandelt.

Der Code an sich liegt jetzt jedoch im Archiv, da ich kurz nach der Problemlösung herausgefunden hab, dass ja Bascom selbst bereits alle Befehle für die Ansteuerung dieser Displays bereitstellt (u.a. mit der Lib lcd-pcf8833.lbx)... man glaubt garnicht, wie ver*** man sich danach vorkommt, wenn man 2 Tage lang an nem Problem arbeitet und sucht und dann feststellt, dass es das ja alles schon fertig gibt... und dass das alles auch vielfach schneller läuft.

Naja, hat aber auch Vorteile; man lernt eben, wie man solche Displays zu Fuss ansteuert oder auch wie man die Bildausgabe um 90/180/270° drehen kann.

Hier der Code:


'! Nur 16-Bit Ansteuerung funktionsfähig
' HW-Stack: 32
' Soft Stk: 16
' Framesize: 24
' µC: ATMega8 @ 8MHz

'-------------------------------------------------------------------------------
' Declaration: Subs
'-------------------------------------------------------------------------------
Declare Sub SendCMD(byval CMD as Byte)
Declare Sub SendDATA(byval CMD as Byte)
Declare Sub SetPixel(byval xRed as Byte , byval xGreen as Byte , byval xBlue as Byte)


'-------------------------------------------------------------------------------
' Declaration: Ports
'-------------------------------------------------------------------------------
config pinC.5 = output
config pinC.4 = output
config pinC.3 = output
config pinC.2 = output
Config PINC.1 = output

CS ALIAS PortC.5
CLK ALIAS PORTC.4
SDA ALIAS PORTC.3
RST ALIAS PORTC.2
LED ALIAS PORTC.1


'-------------------------------------------------------------------------------
' Declaration: Variables
'-------------------------------------------------------------------------------
DIM i as word
dim j as word
DIM ColorMode As Byte
DIM ColorString As String * 7
DIM R as Byte
DIM G1 as Byte
DIM G2 As Byte
DIM B1 as Byte
DIM ColorData1 As Byte
DIM ColorData2 As Byte
DIM ColorNibble As Byte
Dim CMDTEMP AS BYTE


'-------------------------------------------------------------------------------
' Declaration: Constants
'-------------------------------------------------------------------------------
Const Mode_8Bit = 8
CONST Mode_12Bit = 12
CONST Mode_16Bit = 16


'-------------------------------------------------------------------------------
' Display Initialization
'-------------------------------------------------------------------------------
ColorMode = MODE_16Bit
wait 1
CS = 0
SDA = 0
CLK = 1
RST = 1 : RST = 0 : RST = 1
CLK = 1 : SDA = 1 : CLK = 1

SendCMD &h01 'Software Reset
sendCMD &h11 'Sleep Out
SendCMD &h03 'Booster On
waitms 20
SendCMD &h29 'Display On
SendCMD &h13 ' Normal Mode
'sendCMD &H21 'Invert
sendCMD &HBA 'Data Order
sendCMD &h36 'MDAC
SendData 32 + 64 ' (RAM Y DIRECTION + MIRROR X = Rotate 90° CCW)
sendCMD &h3A ' 16 od. 12 Bit p. Pixel
If ColorMode = 8 Then SendData 2
If ColorMode = 12 Then SendData 3
IF ColorMode = 16 Then SendData 5
sendCMD &H25 'Contrast
sendData 63
sendCMD &H2A 'ColAdress
sendData 0
sendData 131
sendCMD &h2B 'PageAdress
sendData 0
sendData 131
sendCMD &h2c


'-------------------------------------------------------------------------------
' Test Screen: Color Bars
'-------------------------------------------------------------------------------
for j = 1 to 4
for i = 1 to 2112
Select Case j
Case 1 : SetPixel 255 , 255 , 255
Case 2 : SetPixel 000 , 255 , 255
Case 3 : SetPixel 255 , 000 , 255
Case 4 : SetPixel 255 , 255 , 000
End Select
next
Next
For j = 5 to 8
For i = 1 to 2113
Select Case j
Case 5 : SetPixel 000 , 000 , 255
Case 6 : SetPixel 255 , 000 , 000
Case 7 : SetPixel 000 , 255 , 000
Case 8 : SetPixel 000 , 000 , 000
End Select
Next
next


'-------------------------------------------------------------------------------
' MAIN LOOP
'-------------------------------------------------------------------------------
DO
Loop
End


'-------------------------------------------------------------------------------
' SUBs:
'-------------------------------------------------------------------------------
Sub SETPIXEL(BYVAL XRED AS BYTE , byval XGREEN AS BYTE , byval XBLUE AS BYTE)
'12-Bit Mode unvollständig!
If ColorMode = Mode_12Bit Then
R = xRed AND &B00001111
G1 = xGreen AND &B00001111
B1 = xBlue AND &B00001111
CLK = 0 : SDA = 1 : CLK = 1
ShiftOut SDA , CLK , R , 1 , 4 , 10
CLK = 0 : SDA = 1 : CLK = 1
ShiftOut SDA , CLK , G1 , 1 , 4 , 10
CLK = 0 : SDA = 1 : CLK = 1
ShiftOut SDA , CLK , B1 , 1 , 4 , 10
EndIf

If ColorMode = Mode_16Bit Then
R = xRed AND &B11111000
G1 = xGREEN AND &B11100000
G2 = xGREEN AND &B00011100
B1 = xBLue AND &B11111000
SHIFT G1 , right , 5
SHIFT G2 , left , 3
SHIFT B1 , right , 3
ColorData1 = R OR G1
ColorData2 = B1 OR G2
CLK = 0 : SDA = 1 : CLK = 1
ShiftOut SDA , CLK , ColorData1 , 1 , 8 , 0
CLK = 0 : SDA = 1 : CLK = 1
ShiftOut SDA , CLK , ColorData2 , 1 , 8 , 0
EndIf

End Sub


Sub SENDDATA(BYVAL CMD AS BYTE)
CLK = 0
waitus 10
SDA = 1
waitus 10
CLK = 1
waitus 10
ShiftOut SDA , CLK , CMD , 1 , 8 , 20
End Sub


Sub SENDCMD(BYVAL CMD AS BYTE)
CLK = 0
waitus 20
SDA = 0
waitus 20
CLK = 1
waitus 20
ShiftOut SDA , CLK , CMD , 1 , 8 , 30
End Sub