;**************************************************************************** ;* * ;* LCD Controller für Singlescan LCD mit 4bit * ;* * ;* für FT245 * ;* * ;* Version 0.3 * ;* * ;* © by Benedikt * ;* * ;* Email: benedikt83 ät gmx.net * ;* * ;**************************************************************************** ;* * ;* Die Software darf frei kopiert und verändert werden, solange sie nicht * ;* ohne meine Erlaubnis für kommerzielle Zwecke eingesetzt wird. * ;* * ;**************************************************************************** ;* * ;* Einfacher LCD Controller für ein beliebiges Singlescan SW LCD. * ;* Außer einem mega8515, einem Inverter, dem 74x573 Adresslatch im * ;* Datenbus, und einem SRAM (32-64kB mit 55ns oder schneller) werden * ;* keine weiteren Bauteile benötig. Neue Daten werden über ein paralleles * ;* Interface mit bis zu 250kByte in den Speicher geladen. * ;* Aufgrund der hohen Datenrate des Parallelports und der LCD Ausgang, * ;* läuft der AVR mit >10MHz und steuert das LCD mit bis zu 100Hz an. * ;* Wird nur ein 32kB SRAM verwendet, muss der Anschluss Q8 (A7) des 74x573 * ;* übersprungen werden. Dann sollte man bei XMax den Wert auf 128 stellen. * ;* Wird ein 32kB SRAM und die Graustufen verwendet, wird Q7 (A6) nicht * ;* angeschlossen. XMax muss auf >250 stehen bleiben, man muss dann * ;* allerdings aufpasssen, dass man den Bereich 64-127 und 192-255 einer * ;* Zeile nicht beschreibt. * ;* * ;* Fuse Bit High: 11001001 = 0XC9 (CKOPT enabled) * ;* Fuse Bit Low: 00101110 = 0x2E (externer Quarz, BOD enabled) * ;* * ;* * ;* Befehle: * ;* * ;* 001 Set Cursor. Gefolgt von zwei Parametern, nämlich der Zeilen * ;* und Spaltenadresse. Die Zeilenadresse liegt im Bereich 0-239, * ;* und die Spaltenadresse im Bereich 0-79 (plus 128, falls die * ;* Position in der unteren Displayhälfte liegt.) * ;* * ;* 002 Set PWM. Stellt das Tastverhältnis des PWM Ausgangs OC1B ein. * ;* Das Tastverhältnis folgt auf diesen Befehl als Parameter. * ;* * ;* 003 Set X Start. Stellt den Startwert für den Zeilenbeginn ein. * ;* Damit lässt sich ein Ausschnitt aus dem virtuellen 1000 Pixel * ;* breiten Bild im Speicher auf dem LCD anzeigen. * ;* * ;* 008 Graustufenmodus. Schaltet die Ausgabe auf 4 Graustufen um. * ;* Jeder Pixel besteht nun aus 2 Bits: Das MSB jedes Pixels * ;* beginnt an der normalen Adresse, das LSB an der Spalten Adresse * ;* plus 128. (Bsp: XStart=0: MSB Beginn=0, LSB Beginn=128, * ;* XStart=28: MSB Beginn=28, LSB Beginn=156 * ;* * ;* 009 Schwarzweismodus (Standart). Schaltet die Ausgabe auf SW um. * ;* * ;* 011 Clear LCD. Dieser Befehl löscht das LCD in extrem kurzer Zeit. * ;* Allerdings benötigt er einiges an Zeit um den kompletten * ;* Speicher zu löschen. Das LCD Timing wird zwar nicht ganz * ;* eingehalten, aber man merkt nichts davon kaum was, da ab und * ;* zu dummy Daten ans LCD gesendet werden. * ;* * ;* 192 Display Character. Mit diesem Befehl wird ein ASCII Zeichen * ;* mittels des interenen Character Generator dargestellt. Das * ;* gewünschte Zeichen wird als Parameter übergeben. Die * ;* Darstellung erfolgt als 8x8 Zeichen. Die Schriftart entspricht * ;* der auf einem PC im 640x480 Grafikmodus. * ;* * ;* Daten: Nach dem Senden eines Datenwertes wird dieser in den Speicher * ;* geschrieben, und der Adresszähler anschließend erhöht. * ;* Jedes Byte enthält 8 nebeneinanderliegende Pixel. Diese werden * ;* im SRAM abgelegt, und nacheinander in 4bit Blöcken ans LCD * ;* übertragen. Aufgrund der Speicherorganisation ist die Auflösung * ;* auf 1000x250 Pixel begrenzt. * ;* * ;* IO Pins: * ;* * ;* PA0-7 Adr/Dat Daten/Low Adresse für den SRAM * ;* PB0-7 Daten 8 Bit Befehle/Daten für den Controller * ;* PC0-7 Adresse High Adresse für den SRAM * ;* PD0 RXF\ RX Full von FT245 * ;* PD1 RD\ Read Impuls an FT245 * ;* PD2 NC * ;* PD3 NC * ;* PD4 LP Latchpuls. Der Impuls läd die Daten aus dem Schiebe- * ;* register ins Display. Dient als HSync. * ;* PD5 FLM VSync für das LCD. Das LCD springt in die erste Zeile. * ;* PD6 VWR\ Write Enable für den SRAM. * ;* PD7 VRD\ Output Enable für den SRAM und XSCL über den 74HC32 * ;* für das LCD. Bei jedem Lesevorgang werden die Daten ins * ;* LCD geladen * ;* PE0 EnLCD Schaltet über einen PNP und einen NPN Transistor die * ;* LCD Spannung, damit im Falle eines Fehlers (z.B. Ausfall* ;* der +5V) das LCD nicht zerstört wird. * ;* PE1 ALE Adress Latch für Low Adressen des SRAMs * ;* PE2 PWM PWM Ausgang, z.B. für Displaykontrast oder * ;* M Signal für Displayansteuerung * ;* * ;**************************************************************************** .include "m8515def.inc" .def null =r0 .def voll =r1 .def tempm =r2 .def temp =r16 .def temp2 =r17 .def temp3 =r18 .def NextOp =r19 ;Zähler für Parameter eines Befehls .def Flags =r20 ;Allgemeine Bits .def Grayscale =r21 ;Bildzähler für Graustufen .def XStart =r22 ;Beginn einer Spalte ab Nibble .def XScan =r23 ;Endadresse bei der Bildausgabe in X Richtung .def XAdresseLow=r26 ;Writepointer Spalte .def ZeileL =r27 ;Writepointer Zeile LSB .def AdresseLow =r28 ;Readpointer Spalte .def AdresseHigh=r29 ;Readpointer Zeile ;PortD .equ RXF =0 ;RXF\ .equ RD =1 ;RD\ .equ LP =4 ;HSync .equ FLM =5 ;VSync ;PortE .equ EnLCD =0 ;LCD Spannung ein/ausschalten ;Flags .equ ZeileH =7 ;Writepointer Zeile MSB, entscheidet zwischen obere und untere Displayhälte, also zwischen High und Low Nibble eines RAM Bytes .equ gray =6 ;Grayscale/SW Umschaltung ;NextOPs ;Werte um die nächste Operation nach einem Befehl festzulegen .equ SetCurL =1 .equ SetCurH =2 .equ SetPWMV =3 .equ CGChar =4 .equ SetScroll =5 .equ Escape =14 ;Wert des Escape Zeichens (=Beginn eines Befehls) .equ CD =7 ;Bit um zwischen Befehl/Daten zu unterscheiden .equ XSize =320 ;Bildgröße in X Richtung in Pixel .equ YSize =240 ;Bildgröße in Y Richtung pro Bild .equ XOScan =0 ;Anzahl der zusätzlich auszugebenden Bytes in X Richtung .equ YOScan =2 ;Anzahl der zusätzlich auszugebenden Zielen in Y Richtung (muss >=2 sein, sonst geht z.B. das Pollin LCD kaputt !) .equ XMax =252 ;Maximale Speicheradresse in XRichtung .equ YMin =4 ;Minimale Speicheradresse in Y Richtung .equ YMax =YMin+YSize ;Maximale Speicheradresse in Y Richtung .equ YScan =YMin+YSize+YOScan ;Endadresse bei der Bildausgabe in Y Richtung .equ XPos =40 ;Position des Logos in X Richtung in Pixeln .equ YPos =96 ;Position des Logos in Y Richtung in Zeilen .equ LXSize =240 ;Größe des Logos in X Richtung in Pixel .equ LYSize =48 ;Größe des Logos in Y Richtung in Pixel ;Maximale Größe des Logos: 43008 Pixel .equ CPUClock =16000000 ;Taktfrequenz .equ FrameFreq =100 ;Bildwiederholfrequenz in Hz .equ ACFreq =180 ;AC Drive (M) Frequenz in Hz .equ TReload = (CPUClock/8/(FrameFreq*(YSize+YOScan)))-1 ;Wert für Timer: Timertakt/Zeilenfrequenz-1 .equ ACDrive = (CPUClock/2048/ACFreq)-1 ;Wert für CTC: Timertakt/2/Frequenz-1 #define PWM ;Funktion von OC1B: PWM (für Kontrast) oder M (AC Drive für LCD) ;**************************************************************************** ; Interrupt Vektoren ;**************************************************************************** .org 0 rjmp Reset ;**************************************************************************** ; CPU Register Initialisierung ;**************************************************************************** Reset: ldi temp, low(RAMEND) out SPL, temp ;setup stack pointer ldi temp, high(RAMEND) out SPH, temp ;setup stack pointer clr null ser temp mov voll, temp ldi temp, (1< NextOp.Escape setzen. ret ;*** Bearbeitung der Daten *** Daten: cpi NextOp, 0 ;Paramter oder Daten ? brne Next sbrc Flags, ZeileH ;Pixel in der oberen oder unteren Displayhälfte ? rjmp untereHalfte obereHalfte: st X+,temp cpi XAdresseLow, XMax ;Spalten Adresse > Max ? brlo normal clr XAdresseLow ;Spalten Adresse = 0 inc ZeileL ;Zeilen Adresse ++ cpi ZeileL, YMax ;Zeilen Adresse > Max ? brlo normal ldi ZeileL, YMin ;Zeile = Beginn XRAM sbr Flags, (1< Max ? brlo normal clr XAdresseLow ;Spalten Adresse = 0 inc ZeileL cpi ZeileL, YMax ;Zeilen Adresse > Max ? brlo normal ldi ZeileL, YMin ;Zeile = Beginn XRAM cbr Flags, (1< Max ? brne normal2 clr XAdresseLow ;Spalten Adresse = 0 subi ZeileL, -8 ;Zeilen Adresse ++ cpi ZeileL, YMax ;Zeilen Adresse > Max ? brlo normal2 ldi ZeileL, YMin ;Zeile = Beginn XRAM ldi temp, (1<