So ich nochmal...
nachdem mir nun langsam der RAM ausgeht und diese Methode nun doch einige Probleme aufwirft, möcht ich doch nochmal die anderen Routinen verwenden.
Hab diese dann nochmal komplett neu aufgebaut, in der Hoffnung, dass der Fehler verschwindet. Aber wie damals auch: das Problem bleibt.
Wo der Fehler herkommt, weiss ich immer noch nicht. Nach bisherigen Erkenntnissen gibt es beim Auslesen des Displayinhalts Probleme, d.h. es wird beim Zeilenwechsel ein falscher Wert ausgelesen.
Evtl ist hier ja jemand, der so ein Display hat und den Code mal testen kann...
Hier mal die neuesten Codes:
tg12864b.c
Code:
#include "tg12864b.h"
// This file contains routines for the Pollin 128x64 GLCD.
// All GLCD-Functions transfer data directly to the display RAM after
// reading back the current display contents.
// Enable this for display color inversion (to be done)
// #define INVERTED
volatile stc_DisplayPosition DPos;
ui8_t state_rw;
ui8_t state_di;
ui8_t state_cs1;
ui8_t state_cs2;
static inline void _delay4Cycles(ui16_t __count)
{
if (__count == 0)
{
__asm__ __volatile__("rjmp 1f\n 1:");
}
else
{
__asm__ __volatile__ (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__count)
: "0" (__count)
);
}
}
#define delay(us) _delay4Cycles(((F_CPU / 4000)*us)/1000)
void GLCD_Init(void)
{
// Set Ports & Pins as Output
TG12864B_DATA_PORT = 0x00;
TG12864B_DATA_DDR = 0xFF;
TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
TG12864B_EN_DDR |= (1 << TG12864B_EN_PIN);
TG12864B_RW_PORT &=~ (1 << TG12864B_RW_PIN);
TG12864B_RW_DDR |= (1 << TG12864B_RW_PIN);
TG12864B_DI_PORT &=~ (1 << TG12864B_DI_PIN);
TG12864B_DI_DDR |= (1 << TG12864B_DI_PIN);
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN);
TG12864B_CS1_DDR |= (1 << TG12864B_CS1_PIN);
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN);
TG12864B_CS2_DDR |= (1 << TG12864B_CS2_PIN);
TG12864B_RST_PORT &=~ (1 << TG12864B_RST_PIN);
TG12864B_RST_DDR |= (1 << TG12864B_RST_PIN);
_delay_ms(10);
TG12864B_RST_PORT |= (1 << TG12864B_RST_PIN);
_delay_ms(10);
// Send commands for init
GLCD_WriteCommand(TG12864B_ON, DRIVER1); // Power on both drivers
GLCD_WriteCommand(TG12864B_ON, DRIVER2); // Power on both drivers
GLCD_WriteCommand(TG12864B_DISP_START, DRIVER1); // Display start line = 0
GLCD_WriteCommand(TG12864B_DISP_START, DRIVER2); // Display start line = 0
}
ui8_t GLCD_ReadCell(ui8_t x, ui8_t page)
{
volatile ui8_t driver;
volatile ui8_t address;
volatile ui8_t data = 0;
volatile ui8_t i;
// select driver
if (x < 64)
{
address = x;
driver = DRIVER1;
}
else
{
address = x - 64;
driver = DRIVER2;
}
// set position
GLCD_WriteCommand(TG12864B_SET_PAGE | page, driver);
GLCD_WriteCommand(TG12864B_SET_ADD | address, driver); // set x address on active chip
if (driver == DRIVER1)
{
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN); // Driver 2 Off
TG12864B_CS1_PORT |= (1 << TG12864B_CS1_PIN); // Driver 1 On
}
else
{
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN); // Driver 1 Off
TG12864B_CS2_PORT |= (1 << TG12864B_CS2_PIN); // Driver 2 On
}
// read cell
TG12864B_DATA_DDR = 0x00; // Data port = Input
TG12864B_DATA_PORT = 0x00; // Reset data port
TG12864B_DI_PORT |= (1 << TG12864B_DI_PIN); // D/I = 1 = Data
TG12864B_RW_PORT |= (1 << TG12864B_RW_PIN); // R/W = 1 = Read
TG12864B_EN_PORT |= (1 << TG12864B_EN_PIN);
asm volatile("nop\n\t""nop\n\t""nop\n\t"::);
TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
asm volatile("nop\n\t""nop\n\t""nop\n\t"::);
TG12864B_EN_PORT |= (1 << TG12864B_EN_PIN);
asm volatile("nop\n\t""nop\n\t""nop\n\t"::);
data = TG12864B_DATA_INPUT;
TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
for(i = 0 ; i < 5 ; i++);
TG12864B_DATA_DDR = 0xFF; // Data port = output
return (data);
}
void GLCD_WriteCell(ui8_t x, ui8_t page, ui8_t data)
{
ui8_t driver;
ui8_t address;
// calc coordinates
if (x < 64)
{
address = x;
driver = DRIVER1;
}
else
{
address = x - 64;
driver = DRIVER2;
}
// set position
GLCD_WriteCommand(TG12864B_SET_ADD | address, driver); // set x address on active driver
GLCD_WriteCommand(TG12864B_SET_PAGE | page, driver); // set page on active driver
if (driver == DRIVER1)
{
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN); // Driver 2 Off
TG12864B_CS1_PORT |= (1 << TG12864B_CS1_PIN); // Driver 1 On
}
else
{
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN); // Driver 1 Off
TG12864B_CS2_PORT |= (1 << TG12864B_CS2_PIN); // Driver 2 On
}
// write cell
TG12864B_DI_PORT |= (1 << TG12864B_DI_PIN); // D/I = 1 = Data
TG12864B_RW_PORT &=~ (1 << TG12864B_RW_PIN); // R/W = 0 = Write
TG12864B_DATA_DDR = 0xFF; // Data port = Output
TG12864B_DATA_PORT = data;
GLCD_Enable();
}
void GLCD_WriteCommand(ui8_t cmd, ui8_t driver)
{
switch(driver)
{
case DRIVER1:
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN); // Driver 2 Off
TG12864B_CS1_PORT |= (1 << TG12864B_CS1_PIN); // Driver 1 On
break;
case DRIVER2:
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN); // Driver 1 Off
TG12864B_CS2_PORT |= (1 << TG12864B_CS2_PIN); // Driver 2 On
break;
}
TG12864B_DI_PORT &=~ (1 << TG12864B_DI_PIN); // D/I = 0 = Instruction
TG12864B_RW_PORT &=~ (1 << TG12864B_RW_PIN); // R/W = 0 = Write
TG12864B_DATA_DDR = 0xFF; // Data port = Output
TG12864B_DATA_PORT = cmd;
GLCD_Enable();
}
void GLCD_Enable(void)
{
volatile ui8_t i;
TG12864B_EN_PORT |= (1 << TG12864B_EN_PIN);
asm volatile(
"nop\n\t"
"nop\n\t"
"nop\n\t"
::);
TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
for(i = 0 ; i < 8 ; i++);
}
void GLCD_SetPixel(ui8_t x, ui8_t y, ui8_t color)
{
ui8_t driver; // which driver controls the selected Pixel?
ui8_t address; // address on the selected driver
ui8_t page; // page, which contains the pixel
ui8_t rel_y; // relative y coordinate in page
ui8_t celldata;
ui8_t dbgbefore;
ui8_t dbgafter;
ui8_t dbgchange;
// calculate address + driver
if (x < 64)
{
address = x;
driver = DRIVER1;
}
else
{
address = x - 64;
driver = DRIVER2;
}
// calculate page:
//page = floor(y / 8);
page = y / 8;
rel_y = (y - (page * 8));
// Read current cell
celldata = GLCD_ReadCell(x, page);
dbgbefore = celldata;
// set or clear pixel
if (color == 0)
{
celldata &=~ (1 << rel_y);
}
else
{
celldata |= (1 << rel_y);
}
dbgchange = (1 << rel_y);
dbgafter = celldata;
// Write cell back
GLCD_WriteCell(x, page, celldata);
/*
if (1==0)//x < 8)
{
sprintf(dbgtext, "Before: 0x%02X Change: 0x%02X After: 0x%02X", dbgbefore, dbgchange, dbgafter);
DBG_Print(dbgtext);
_delay_ms(1000);
}
*/
}
tg12864b.h
Code:
#ifndef _TG12864B_H_
#define _TG12864B_H_
#include <math.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <string.h>
#include <stdio.h>
#include "glob_defs.h"
#include "glob_type.h"
#define ELEM_BRIGHTNESS 1
#define ELEM_AUTOOFF 2
#define ELEM_AUTOOFFACT 3
#define TG12864B_DATA_PORT PORTK
#define TG12864B_DATA_DDR DDRK
#define TG12864B_DATA_INPUT PINK
#define TG12864B_EN_PORT PORTF
#define TG12864B_EN_DDR DDRF
#define TG12864B_EN_PIN 7
#define TG12864B_RW_PORT PORTF
#define TG12864B_RW_DDR DDRF
#define TG12864B_RW_PIN 6
#define TG12864B_DI_PORT PORTF
#define TG12864B_DI_DDR DDRF
#define TG12864B_DI_PIN 5
#define TG12864B_CS1_PORT PORTJ
#define TG12864B_CS1_DDR DDRJ
#define TG12864B_CS1_PIN 7
#define TG12864B_CS2_PORT PORTA
#define TG12864B_CS2_DDR DDRA
#define TG12864B_CS2_PIN 0
#define TG12864B_RST_PORT PORTA
#define TG12864B_RST_DDR DDRA
#define TG12864B_RST_PIN 1
// Commands
#define TG12864B_ON 0x3F
#define TG12864B_OFF 0x3E
#define TG12864B_SET_ADD 0x40
#define TG12864B_SET_PAGE 0xB8
#define TG12864B_DISP_START 0xC0
#define INCREMENT_X 0
#define NO_INCREMENT_X 1
#define DRIVER1 0
#define DRIVER2 1
#define ICON_ARROWLEFT 130
// New functions:
void GLCD_Init(void);
void GLCD_WriteCommand(ui8_t cmd, ui8_t driver);
ui8_t GLCD_ReadCell(ui8_t x, ui8_t page);
void GLCD_WriteCell(ui8_t x, ui8_t page, ui8_t data);
void GLCD_Enable(void);
void GLCD_SetPixel(ui8_t x, ui8_t y, ui8_t color);
typedef struct {
ui8_t x;
ui8_t y;
ui8_t driver;
ui8_t addr;
ui8_t page;
ui8_t rel_y;
} stc_DisplayPosition;
typedef struct{
ui8_t data[7];
} stc_font5x7;
#endif
Testprorgamm in der main.c:
Code:
int main (void)
{
ui8_t x;
ui8_t y;
while(1)
{
// Test area for GLCD-Commands [START]
GLCD_Init();
for (y = 0 ; y < 8 ; y++)
{
for (x = 0 ; x < 128 ; x++)
{
// Clears whole display
GLCD_WriteCell(x,y , 0x00);
}
}
while(1)
{
for (y = 0 ; y < 64 ; y++)
{
for (x = 0 ; x < 128 ; x++)
{
// Set Display white
GLCD_SetPixel(x, y, 1);
}
}
for (y = 0 ; y < 64 ; y++)
{
for (x = 0 ; x < 128 ; x++)
{
// Set Display blue
GLCD_SetPixel(x, y, 0);
}
}
}
while(1);
// Test area for GLCD-Commands [END]
}
Lesezeichen