- LiFePO4 Speicher Test         
Ergebnis 1 bis 5 von 5

Thema: KS0108 / Pollin 128x64 LCD: Probleme [gelöst]

  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009

    KS0108 / Pollin 128x64 LCD: Probleme [gelöst]

    Anzeige

    Powerstation Test
    Moin.

    Bin gerade dabei, einige Routinen in Eigenarbeit für ein LCD (128x64, Klassiker von Pollin mit KS0108-kompatiblem Controller) zu erstellen.
    Es gibt zwar schon ein paar fertige Routinen, nur möcht ich das ganze selbst von Grund auf erstellen, um genau zu wissen, was ich da eigentlich mach.

    Im Anhang ist der bisherige Stand.
    Das Testprogramm in der main.c soll vom Prinzip her das gleiche machen, wie die Funktion TG12864B_Fill(), nur dass eben jedes Pixel gezielt angesprochen werden kann.
    Problem ist nun hier, dass die Fläche nach dem Test nicht durchgehend weiss ist, sondern am linken Rand jedes "Treibers" dieses Muster hier aufweist:

    Bild hier  

    Wobei dieses "Muster" erst während des Aufbaus entsteht; d.h. die erste Zeile wird durchgehend gesetzt. Sobald die 2. Zeile beginnt, wird das erste Pixel wieder gelöscht. Beginnt die 3. Zeile, rutscht das gelöschte Pixel aus der ersten Zeile eins weiter ... usw, bis am Ende eben dieses Muster entsteht.
    Der Fehler müsste entweder irgendwo in ~_SetPixel() oder ~_Goto() sein. Nur seh ich ihn nicht. Evtl jemand von euch?

    Hier die Codes:
    main.c
    Code:
    int main (void)
    {
      ui8_t x=0;
      ui8_t y=0;
    
      TG12864B_Init();
      for (y = 0; y < 64  ; y++)
      for (x = 0; x < 128 ; x++)
      {
        {
          TG12864B_SetPixel(x,y,1);
    //      _delay_ms(100);
        }
      }
      while(1)
      {
      
      }
      return(0);
    }
    tg12864b.c
    Code:
    #include "tg12864b.h"
    
    stc_DisplayPosition DPos;
    volatile ui8_t readdata = 0;
    
    
    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 TG12864B_Init(void)
    {
      // Prepare Timer 0, PWM Channel B
      //TCCR0A  = (1 << WGM00) | (1 << COM0B1);
      //TCCR0B = (1 << CS00) | (1 << CS01);
      //OCR0B = 0;
    
      // Set Ports & Pins as Output
      TG12864B_DATA_PORT = 0x00;
      TG12864B_DATA_DDR = 0xFF;
    //  TG12864B_LIGHT_DDR |= (1 << TG12864B_LIGHT_PIN);
      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
      DPos.x = 0;
      DPos.y = 0;
      DPos.page = 0;
      DPos.addr = 0;
      DPos.driver = 0;
      DPos.rel_y = 0;
      TG12864B_SendCmd(TG12864B_ON, 1);          // Power on both drivers
      TG12864B_SendCmd(TG12864B_ON, 2);          // Power on both drivers
      TG12864B_SendCmd(TG12864B_DISP_START, 1);  // Display start line = 0
      TG12864B_SendCmd(TG12864B_DISP_START, 2);  // Display start line = 0
      TG12864B_Fill(0x00);
    }
    
    void TG12864B_SendCmd(ui8_t cmd, ui8_t driver)
    {
      switch(driver)
      {
        case 1:
        TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN);  // Driver 2 Off
        TG12864B_CS1_PORT |=  (1 << TG12864B_CS1_PIN);  // Driver 1 On
        break;
        case 2:
        TG12864B_CS2_PORT |=  (1 << TG12864B_CS2_PIN);  // Driver 2 On
        TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN);  // Driver 1 Off
        break;
        case 3:
        TG12864B_CS1_PORT |=  (1 << TG12864B_CS1_PIN);  // Driver 1 On
        TG12864B_CS2_PORT |=  (1 << TG12864B_CS2_PIN);  // Driver 2 On 
        break;
        default:
        TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN);  // Driver 1 Off
        TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN);  // Driver 2 Off
        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;   // Port = Output
      TG12864B_DATA_PORT = cmd;   // Set data
      TG12864B_EN_Pulse();        // Enable Clock
      TG12864B_DATA_PORT = 0x00;  // Reset data port
    }
    
    void TG12864B_EN_Pulse(void)
    {
      TG12864B_EN_PORT |=  (1 << TG12864B_EN_PIN);
      delay(4);
      TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
      delay(4);
    }
    
    void TG12864B_Fill(ui8_t pattern)
    {
      ui8_t add;
      ui8_t page;
      for (page = 0; page < 8 ; page++)
      {
        for (add = 0 ; add < 64 ; add++)
        {
          TG12864B_SendCmd(TG12864B_SET_ADD | add, 3);
          TG12864B_SendCmd(TG12864B_SET_PAGE | page, 3);
          TG12864B_SendDataRaw(pattern,3);
        }
      }
    }
    
    void TG12864B_SendDataRaw(ui8_t data, ui8_t driver)
    {
      switch(driver)
      {
        case 1:
        TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN);  // Driver 2 Off
        TG12864B_CS1_PORT |=  (1 << TG12864B_CS1_PIN);  // Driver 1 On
        break;
        case 2:
        TG12864B_CS2_PORT |=  (1 << TG12864B_CS2_PIN);  // Driver 2 On
        TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN);  // Driver 1 Off
        break;
        case 3:
        TG12864B_CS1_PORT |=  (1 << TG12864B_CS1_PIN);  // Driver 1 On
        TG12864B_CS2_PORT |=  (1 << TG12864B_CS2_PIN);  // Driver 2 On 
        break;
        default:
        TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN);  // Driver 1 Off
        TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN);  // Driver 2 Off
        break;
      }
      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;   // Port = Output
      TG12864B_DATA_PORT = data;   // Set data
      TG12864B_EN_Pulse();        // Enable Clock
      TG12864B_DATA_PORT = 0x00;  // Reset data port
    
    }
    
    void TG12864B_Goto(ui8_t x, ui8_t y)
    {
      DPos.x = x;
      DPos.y = y;
    
      // Check: coordinates are valid
      if (x > 127) { x = 127; }
      if (y > 63)  { y = 63;  }
      
      // Calculate Coordinates:
      // Get driver nr. & relative x coordinate (= address)
      if  ( x >= 128) 
      { 
        return;
      }
    
      if ( x <  64 )
      { 
        DPos.driver = 1;
        DPos.addr = x;
      }
      
      if (( x >=  64 ) && ( x < 128 )) 
      { 
        DPos.driver = 2; 
        DPos.addr = x - 64;
      }
    
      // Get Page:
      /*
      if               (y <  8)  {DPos.page = 0;}
      if ((y >=  8) && (y < 16)) {DPos.page = 1;}
      if ((y >= 16) && (y < 24)) {DPos.page = 2;}
      if ((y >= 24) && (y < 32)) {DPos.page = 3;}
      if ((y >= 32) && (y < 40)) {DPos.page = 4;}
      if ((y >= 40) && (y < 48)) {DPos.page = 5;}
      if ((y >= 48) && (y < 56)) {DPos.page = 6;}
      if ((y >= 56) && (y < 64)) {DPos.page = 7;}
      */
      DPos.page = floor(y / 8);
      DPos.rel_y = (y-DPos.page*8);
      //DPos.rel_y = y & 8;
    }
    
    ui8_t TG12864B_ReadData(void)
    {
      ui8_t data;
      TG12864B_DATA_PORT = 0x00;  // Data = 0
      TG12864B_DATA_DDR = 0x00;   // Data = Input
    
      if (DPos.driver == 1)
      {
        TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN);  // Driver 2 Off
        TG12864B_CS1_PORT |=  (1 << TG12864B_CS1_PIN);  // Driver 1 On
      }
      if (DPos.driver == 2)
      {
        TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN);  // Driver 1 Off
        TG12864B_CS2_PORT |=  (1 << TG12864B_CS2_PIN);  // Driver 2 On 
      }
    
      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);
      delay(10);
      data = TG12864B_DATA_INPUT;
      delay(10);
      TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
      delay(10);
      TG12864B_DATA_DDR = 0xFF;   // Data = Output
      return (data);
    }
    
    void TG12864B_SetPixel(ui8_t x, ui8_t y, ui8_t value)
    {
      TG12864B_Goto(x, y);
      TG12864B_SendCmd(TG12864B_SET_ADD | DPos.addr, DPos.driver);
      TG12864B_SendCmd(TG12864B_SET_PAGE | DPos.page, DPos.driver);
      readdata = TG12864B_ReadData();
      if (value == 0)
      {
        readdata &=~ (1 << DPos.rel_y);
      }
      else
      {
        readdata |= (1 << DPos.rel_y);
      }
      TG12864B_SendCmd(TG12864B_SET_ADD | DPos.addr, DPos.driver);
      TG12864B_SendCmd(TG12864B_SET_PAGE | DPos.page, DPos.driver);
      TG12864B_SendDataRaw(readdata, DPos.driver)  ;
      
    }
    tg12864b.h
    Code:
    #ifndef _TG12864B_H_
    #define _TG12864B_H_
    
    #include <math.h>
    #include <avr/io.h>
    #include <util/delay.h>
    #include "glob_defs.h"
    #include "glob_type.h"
    
    #define TG12864B_DATA_PORT     PORTA
    #define TG12864B_DATA_DDR      DDRA
    #define TG12864B_DATA_INPUT    PINA
    
    #define TG12864B_EN_PORT       PORTD
    #define TG12864B_EN_DDR        DDRD
    #define TG12864B_EN_PIN        4
    
    #define TG12864B_RW_PORT       PORTD
    #define TG12864B_RW_DDR        DDRD
    #define TG12864B_RW_PIN        5
    
    #define TG12864B_DI_PORT       PORTD
    #define TG12864B_DI_DDR        DDRD
    #define TG12864B_DI_PIN        6
    
    #define TG12864B_CS1_PORT      PORTB
    #define TG12864B_CS1_DDR       DDRB
    #define TG12864B_CS1_PIN       2
    
    #define TG12864B_CS2_PORT      PORTB
    #define TG12864B_CS2_DDR       DDRB
    #define TG12864B_CS2_PIN       3
    
    #define TG12864B_RST_PORT      PORTD
    #define TG12864B_RST_DDR       DDRD
    #define TG12864B_RST_PIN       3
    
    // 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
    
    
    
    void TG12864B_Init(void);
    void TG12864B_SendCmd(ui8_t cmd, ui8_t driver);
    void TG12864B_SendDataRaw(ui8_t data, ui8_t driver);
    void TG12864B_EN_Pulse(void);
    void TG12864B_Fill(ui8_t pattern);
    void TG12864B_Goto(ui8_t x, ui8_t y);
    ui8_t TG12864B_ReadData(void);
    void TG12864B_SetPixel(ui8_t x, ui8_t y, ui8_t value);
    
    
    typedef struct {
    	ui8_t x;
    	ui8_t y;
    	ui8_t driver;
      ui8_t addr;
      ui8_t page;
      ui8_t rel_y;
    } stc_DisplayPosition;
    
    
    #endif
    mfG
    #ifndef MfG
    #define MfG

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,

    evtl. passt die Berechnung bei TG12864B_Goto nicht ganz, probier einfach mal einzelne Pixel zu setzen, und zähl dann aus ob die an der richtigen Stelle gelandet sind.
    Evtl. macht floor nicht ganz das was es soll, das sollte man aber auch ganz weglassen können, da nur Integers verwendet werden.

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    Also wenn einzelne Pixel gesetzt werden sollen, dann gehts schon so halb; nur wenn dann Pixel gesetzt werden, die in der gleichen "Page", aber untereinander liegen, dann verschwinden die darüber bzw. "togglen".

    Hab von diesem Phänomen jetzt auch mal ein Video, die Pixel werden langsam zeilenweise gezeichnet, entsprechend der beiden for-Schleifen in der main.c; dort sieht man deutlich, wie dieses Muster entsteht.

    http://cihome.kilu.de/_forendaten/lcd01.avi
    (DivX 6.8, ca. 1,7MB, 22 sec, no Audio)

    Das mit dem floor war so geplant, dass z.B. auch 7/8 (=0,875) noch 0 ergibt und nicht auf 1 aufgerundet wird, wo ich mir nicht sicher bin, ob "7/8" allein das auch ergibt. In der Sache bin ich immer etwas vorsichtiger, da dort jedes Programm was anderes macht. Die einen runden, die andern schneidens einfach ab.


    EDIT: Nachtrag:
    Habs gerade so versucht, dass ich den Displayinhalt im RAM des Controllers zwischenspeichere und dort lese, was bereits am Display steht.
    Dort verschwindet der Effekt nun. Bringt zwar noch den weiteren Vorteil, dass das Pixel setzen nochmal ne Stufe schneller wurde, aber der erhebliche Nachteil ist, dass z.B. beim ATMega32 jetzt etwa 63% vom RAM nur für das Display draufgehen... schon etwas viel, naja aber bis es anders geht, lass ichs mal so.
    #ifndef MfG
    #define MfG

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    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]
      }
    #ifndef MfG
    #define MfG

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von Jaecko
    Registriert seit
    16.10.2006
    Ort
    Lkr. Rottal/Inn
    Alter
    41
    Beiträge
    2.009
    Und zum dritten:
    Habs mittlerweile geschafft, den Fehler auszubügeln bzw. zu umgehen.
    Der "Trick" an der Sache ist einfach der, das Display 2x auszulesen und den ersten (falschen) Wert zu verwerfen; Sprich, dem eigentlichen Read ein Dummy Read voranstellen. Dann gehts.
    #ifndef MfG
    #define MfG

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test