www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C lib für SSD1305


Autor: Humpawumpa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tag allerseits

Ich versuche gerade ein OLED Display mit einem SSD1305 Controller 
anzusteuern, habe gesucht, ob ich vielleicht eine fertige C lib für 
String und Bildausgabe finde. Ist aber alles kostenpflichtig

Hat jemand von euch schon was damit gemacht?

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi

vielleicht hilft dir das weiter, ich hab ein 2,7" Oled damit gesteuert, 
und funktioniert einwandfrei!

http://www.icplan.de/seite24.htm

Autor: Humpawumpa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bringe einfach nix aufs Display, ich brauch n Licht am Ende des Tunnels 
-.-
Habe nen ARM Controller und ein 128x64Pixel OLED von Densitron


#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "FreeRTOS.h"
#include "task.h"
#include "croutine.h"
#include "queue.h"
#include "semphr.h"

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "utils/ustdlib.h"

// Display Includes
#include "drivers/dd12864.h"


// ## All defines
// @OLED display
#define SYSCTL_PERIPH_GPIO_OLEDDC     SYSCTL_PERIPH_GPIOF
#define GPIO_OLEDDC_BASE              GPIO_PORTB_BASE
#define GPIO_OLEDDATA_BASE        GPIO_PORTF_BASE
#define GPIO_OLEDDC_PIN               GPIO_PIN_6
#define GPIO_OLEDWR_PIN          GPIO_PIN_5
#define GPIO_OLEDEN_PIN                GPIO_PIN_4
#define GPIO_OLEDRS_PIN          GPIO_PIN_3
#define GPIO_OLEDCS_PIN          GPIO_PIN_2
#define GPIO_OLEDMODE          GPIO_PIN_0 | GPIO_PIN_1
#define OLED_DATAPORT          GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7
// @others
#define mainHEARTBEAT_TASK_LED      2
#define mainBUTTEN_DOWN          GPIO_PIN_4
#define mainHEARTBEAT_PERIOD      ( ( portTickType ) 500 / portTICK_RATE_MS  )

// Flag to indicate if SSI port is enabled for display usage.
static volatile tBoolean g_bSSIEnabled = false;


//-----------------------------------------------------------

int main(void) {

  // Set the clocking to run directly from the crystal.
  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN
      | SYSCTL_XTAL_8MHZ);

  initOLEDDisplay();

  return 0; //should never reach this line
}


// initialize the OLED dsplay
void initOLEDDisplay() {


// Enable the SSI0 and GPIO port blocks as they are needed by this driver.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIO_OLEDDC);


  GPIODirModeSet  ( GPIO_OLEDDATA_BASE, OLED_DATAPORT, GPIO_DIR_MODE_OUT );
    GPIOPadConfigSet( GPIO_OLEDDATA_BASE, OLED_DATAPORT, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD );


// Configure the GPIO port pin used as a D/Cn signal for OLED device,
// and the port pin used to enable power to the OLED panel.
    GPIOPinTypeGPIOOutput  (GPIO_OLEDDC_BASE, GPIO_OLEDRS_PIN | GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN | GPIO_OLEDMODE);
    GPIOPadConfigSet    (GPIO_OLEDDC_BASE, GPIO_OLEDRS_PIN | GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN | GPIO_OLEDMODE,
               GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
// Set Mode to parallel 8080
     GPIOPinWrite      (GPIO_OLEDDC_BASE, GPIO_OLEDMODE, GPIO_OLEDMODE);
//     GPIOPinWrite      (GPIO_OLEDDC_BASE, GPIO_OLEDRS_PIN | GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN | GPIO_OLEDMODE,
//               GPIO_OLEDRS_PIN | GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN | GPIO_OLEDMODE);


// Set the 15V
    GPIOPinTypeGPIOOutput  (GPIO_PORTH_BASE, GPIO_PIN_3);
    GPIOPadConfigSet    (GPIO_PORTH_BASE, GPIO_PIN_3,
               GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
    GPIOPinWrite      (GPIO_PORTH_BASE, GPIO_PIN_3, GPIO_PIN_3);

// Reset
    GPIOPinWrite      (GPIO_OLEDDC_BASE, GPIO_OLEDRS_PIN, 0);
    SysCtlDelay(30);
    GPIOPinWrite      (GPIO_OLEDDC_BASE, GPIO_OLEDRS_PIN, GPIO_OLEDRS_PIN);

  sendCommand(0x00);                         /* Set Lower Column Address */
  sendCommand(0x10);                         /* Set Higher Column Address */

  sendCommand(0x40);                         /* Set Display Start Line */

  sendCommand(0x81);                         /* Set Contrast Control */
  sendCommand(0x30);                         /* 0 ~ 127 */

  sendCommand(0xA0);                         /* [A0]:column address 0 is */
  sendCommand(0xC8);                         /* oben / unten */

  sendCommand(0xA4);                         /* A4=ON */

  sendCommand(0xA6);                        /* Normal Display*/

  sendCommand(0xA8);                         /* Set Multiplex Ratio */
  sendCommand(0x3f);

  sendCommand(0xAD);                         /* Set DC-DC */
  sendCommand(0x8E);                         /* 8B=ON, 8A=Off */

  sendCommand(0xAF);                        /* AF=ON , AE=OFF*/

  sendCommand(0xD3);                         /* Set Display Offset */
  sendCommand(0x00);                         /* No offset */

  sendCommand(0xD5);                         /* Set Clock Divide */
  sendCommand(0x61);                         /* Set to 80Hz */

  sendCommand(0xD8);                         /* Set Area Color On or Off */
  sendCommand(0x00);                         /* Mono Mode */

  sendCommand(0xDA);                         /* Set Pins Hardware */
  sendCommand(0x12);

  sendCommand(0xDB);                         /* Set VCOMH */
  sendCommand(0x00);

  sendCommand(0xD9);                         /* Set VP */
  sendCommand(0x22);                         /* P1=2 , P2=2 */



}




// Commandroutine
void sendCommand(const unsigned char command){
    // Set the command/control bit to enable data mode.
    GPIOPinWrite  (GPIO_OLEDDC_BASE, GPIO_OLEDDC_PIN | GPIO_OLEDCS_PIN | GPIO_OLEDWR_PIN | GPIO_OLEDEN_PIN , GPIO_OLEDEN_PIN);

    GPIOPinWrite  (GPIO_OLEDDATA_BASE, OLED_DATAPORT, command);
    GPIOPinWrite  (GPIO_OLEDDC_BASE, GPIO_OLEDWR_PIN, GPIO_OLEDWR_PIN);

}


// Dataroutine
void sendData(unsigned char data) {
    GPIOPinWrite  (GPIO_OLEDDC_BASE, GPIO_OLEDDC_PIN | GPIO_OLEDCS_PIN | GPIO_OLEDWR_PIN | GPIO_OLEDEN_PIN , GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN);

    GPIOPinWrite  (GPIO_OLEDDATA_BASE, OLED_DATAPORT, data);
    GPIOPinWrite  (GPIO_OLEDDC_BASE, GPIO_OLEDWR_PIN, GPIO_OLEDWR_PIN);
}

// Clear the display
void clearDisplay() {

}

void setPixel(int x, int y){

}





Autor: Humpawumpa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grundsätzlich würde ich einfach sehr gerne wissen wie ich ein Pixel 
setzten kann. Damit ich zumindest weiss, dass die Hardware funktioniert.

Autor: Martin 567 (martink11)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm mit ARM kenn ich mich eig überhaupt niad aus, habe zwar einen 
rumliegen, aber hab nie was damit gemacht ich habe nen avr at90can128.

und ein pictiva 128x64 2.7" von OSRAM damit gehts, ich habs nach dieser 
anleitung oder beispiel gemacht und es ging, hab dann die funktionen ein 
wenig erweitert.

aber du verwendest ja erstens mal einen anderen Controller-IC vom 
display, das kann schon wieder ganz anders sein.

aber da steht doch bestimmt im datenblatt so eine art initialisierung 
wie du schon gemacht hast,

wenn gar nix geht (nicht mal ein blinken oder irgendwas) tippe ich erst 
mal auf einen Verdrahtungsfehler

servus martin!!!!!

Autor: Humpawumpa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, den ersten Layout Fehler hätte ich gefunden. Der Stecker war um 1Pin 
verschoben, dies hat dazu geführt, dass VCOMH 15V gesehen hat.
Zudem hab ich von paralleler Ansteuerung auf I2C gewechselt, leider 
kommt kein Acknoledge zurück, hab nun mal ein Ersatzdisplay bestellt.

Um aber nichts unversucht zu lassen, hier mal die I2C Ansteuerung
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "FreeRTOS.h"
#include "task.h"
#include "croutine.h"
#include "queue.h"
#include "semphr.h"

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_sysctl.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"

#include "utils/ustdlib.h"

// Display Includes
#include "drivers/rit128x96x4.h"


// ## All defines
// @OLED display
#define SYSCTL_PERIPH_GPIO_OLEDDC     SYSCTL_PERIPH_GPIOA
#define GPIO_OLEDDC_BASE              GPIO_PORTB_BASE
#define GPIO_OLEDDATA_BASE        GPIO_PORTA_BASE
#define GPIO_OLEDDC_PIN               GPIO_PIN_6
#define GPIO_OLEDWR_PIN          GPIO_PIN_5
#define GPIO_OLEDEN_PIN                GPIO_PIN_4
#define GPIO_OLEDRS_PIN          GPIO_PIN_3
#define GPIO_OLEDCS_PIN          GPIO_PIN_2
#define GPIO_OLEDMODE          GPIO_PIN_0 | GPIO_PIN_1
#define OLED_DATAPORT          GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7
// @others
#define mainHEARTBEAT_TASK_LED      2
#define mainBUTTEN_DOWN          GPIO_PIN_4
#define mainHEARTBEAT_PERIOD      ( ( portTickType ) 500 / portTICK_RATE_MS  )

// Flag to indicate if SSI port is enabled for display usage.
static volatile tBoolean g_bSSIEnabled = false;


//-----------------------------------------------------------

int main(void) {

  // Set the clocking to run directly from the crystal.
  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN
      | SYSCTL_XTAL_8MHZ);

//  initOLEDDisplay();
  /*
  // Set the 15V
      GPIOPinTypeGPIOOutput  (GPIO_PORTH_BASE, GPIO_PIN_3);
      GPIOPadConfigSet    (GPIO_PORTH_BASE, GPIO_PIN_3,
                 GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
      GPIOPinWrite      (GPIO_PORTH_BASE, GPIO_PIN_3, GPIO_PIN_3);*/
    // Initialize the OLED display.
    RIT128x96x4Init(1000000);
    RIT128x96x4StringDraw("oops?", 30, 24, 15);
    i2croutine();
    RIT128x96x4StringDraw("i did it again", 30, 44, 15);
  return 0; //should never reach this line
}


void i2croutine() {

  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

  GPIODirModeSet  ( GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_OUT );
    GPIOPadConfigSet( GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD );
    GPIOPinWrite  ( GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_PIN_0 );
    SysCtlDelay(30*100);
    GPIOPinWrite  ( GPIO_PORTB_BASE, GPIO_PIN_1, GPIO_PIN_1 );
    SysCtlDelay(30*10);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
  GPIOPinTypeI2C(GPIO_PORTB_BASE,GPIO_PIN_2 | GPIO_PIN_3);

  I2CMasterEnable(I2C0_MASTER_BASE);
  I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), false);

  I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x3C, false);
  I2CMasterDataPut(I2C0_MASTER_BASE,0x80);
  I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
  while(I2CMasterBusy(I2C0_MASTER_BASE)){}
  I2CMasterDataPut(I2C0_MASTER_BASE, 0xAE);
  I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
  while(I2CMasterBusy(I2C0_MASTER_BASE)){}




  char error[10];
  unsigned long mongobilli = I2CMasterErr(I2C0_MASTER_BASE);
  switch (mongobilli){
  case I2C_MASTER_ERR_NONE:
    usprintf(error,"none-nigga");
    break;
  case I2C_MASTER_ERR_ADDR_ACK:
    usprintf(error,"adr_akk");
    break;
  case I2C_MASTER_ERR_DATA_ACK:
    usprintf(error,"data_ack");
    break;
  case I2C_MASTER_ERR_ARB_LOST:
    usprintf(error,"arb_lost");
    break;
  default:
    usprintf(error,"error %x",mongobilli);
    break;
}
    RIT128x96x4StringDraw(error, 10,10,10);


}

Sieht jemand die Ursache? Die Routine wird ausgeführt und die Ausgabe 
ist "error c"

Autor: Erwin Unger (Firma: privat) (eunger)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Vielleicht eine Hilfe. Ich habe gerade einen ersten Erfolg erzielt mit 
Atmega8 auf SDD1305 mittels I2C. Ich hoffe, es stimmt, was ich erzähle, 
aber immerhin sehe ich was am Display. Allerdings kenne ich mit mit dem 
ARM nicht aus, aber was ich gesehen habe, hast du eine Reihe von 
send_command()-Befehlen, die ich ziemlich gleich verwende:
  sendCommand(0x00);                         /* Set Lower Column Address 
*/
  sendCommand(0x10);                         /* Set Higher Column 
Address*/

  sendCommand(0x40);                         /* Set Display Start Line 
*/

  sendCommand(0x81);                         /* Set Contrast Control */
  sendCommand(0x30);                         /* 0 ~ 127 */

  sendCommand(0xA0);                         /* [A0]:column address 0 is 
*/
  sendCommand(0xC8);                         /* oben / unten */

  sendCommand(0xA4);                         /* A4=ON */

  sendCommand(0xA6);                        /* Normal Display*/

  sendCommand(0xA8);                         /* Set Multiplex Ratio */
  sendCommand(0x3f);

  sendCommand(0xAD);                         /* Set DC-DC */
  sendCommand(0x8E);                         /* 8B=ON, 8A=Off */

  sendCommand(0xAF);                        /* AF=ON , AE=OFF*/

  sendCommand(0xD3);                         /* Set Display Offset */
  sendCommand(0x00);                         /* No offset */

  sendCommand(0xD5);                         /* Set Clock Divide */
  sendCommand(0x61);                         /* Set to 80Hz */

  sendCommand(0xD8);                         /* Set Area Color On or Off 
*/
  sendCommand(0x00);                         /* Mono Mode */

  sendCommand(0xDA);                         /* Set Pins Hardware */
  sendCommand(0x12);

  sendCommand(0xDB);                         /* Set VCOMH */
  sendCommand(0x00);

  sendCommand(0xD9);                         /* Set VP */
  sendCommand(0x22);                         /* P1=2 , P2=2 */

Allerdings sieht es bei mir so aus:
    write_command (0x00); //set low column address
    write_command (0x10); //set high column address
    write_command (0x40); //display start set
    write_command (0x20); //stop horizontal scroll, changed from 0x2e
    write_command (0xb0); //page address
    write_command2(0x81,0x7f); //set contrast control register
    write_command2(0x82,0x7f); //set brightness register
    write_command (0xa1); //set sement re-map
    write_command (0xa4); //normal display mode
    write_command (0xa6); //set normal/reverse display
    write_command2(0xa8,0x3f); //set multiplex ratio
    write_command2(0xd3,0x00); //set display offset
    write_command2(0xad,0x8e); //set dc-dc on/off
    write_command (0xc8); //set com output scan direction
    write_command2(0xd5,0xf0); //set display clock divide 
ratio/orcillator/frequency
    write_command2(0xd8,0x05); //set area color mode on/off & low power 
display mode
    write_command2(0xd9,0xc2); //set pre-charge period
    write_command2(0xda,0x12); //set com pins hardware configuration
    write_command2(0xdb,0x08); //set vcom deselect level

Dabei werden diese Routinen verwendet:

void write_command(unsigned char command)
{
    unsigned char address=OLED_write;
    char test;
    test = i2c_start(address);
    test = i2c_write(0x80);
    test = i2c_write(command);
    i2c_stop();
}

void write_command2(unsigned char command,unsigned char data)
{
    unsigned char address=OLED_write;
    char test;
    test = i2c_start(address);
    test = i2c_write(0xC0);
    test = i2c_write(command);
    test = i2c_write(data);
    i2c_stop();
}

Was ich damit sagen will, ich glaube, dass man Kommandos, die ein 
Zusatzbyte haben, anders schicken muss, als solche ohne Zusatzbyte. Z.B. 
verlangt das Kommando 0x81 (set contrast) danach ein Byte mit dem 
Kontrastlevel. In diesem Fall muss ich beim Controlbyte statt 0x80 ein 
0xC0 nehmen.

Allerdings weiss ich noch nicht, wie man Kommandos mit 2 oder mehr Bytes 
übertrage, das kriege ich momentan nicht hin.

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schönen Guten Abend,
auch wenn das hier schon etwas älter is, versuche ich es mal. Es braucht 
ja immer gleich einen neuen Thread.

Also ich hab ein Display mit dem gleichen Controller und nach den ersten 
Hindernissen wie die 100ms nach dem Reset vergessen, konnte ich es 
konfigurieren.
Achso ich nutze auch den I2C zur Kommunikation mit dem Display.

Jetzt hab ich aber das Problem, dass ich rein garnichts auf das Display 
bekomme. Nur der Datenmüll der im Speicher steht. Meine Vorgehensweise 
bis jetzt.

Ich Starte den I2C, dann Adresse mit write bit.
Kontrollbyte 0x40 für daten
dann die Daten z.B 0x00 in einer while um alle pixel dunkel zu haben
aber nichts passiert.


Hat jemand vielleicht eine Idee, was ich falsch mache?

Schon mal vielen Dank und einen schönen Abend

Autor: u8glib (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Setzt Du denn vorher auch die korrekte RAM-Adresse? Eigentlich sollte 
die Sequenz auf dem I2C Bus etwa so sein:
0x00 command mode
0x00 lower col
0x10 higher col
0x40 data mode
jetzt kommen erst die Pixel Daten. Es kann auch durchaus sein, dass noch 
weitere initalisierungen notwendig sind.

Wenn der SSD1305 kompatibel zum SSD1306 ist (ich meine der SSD1305 war 
der Vorgänger), dann könnte ggf U8glib funktionieren.

Oliver

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
vielen Dank für deine Antwort.
Bekomme leider immer noch nichts aufs Display.

Ich hab bestimmt irgendwo noch nen Denkfehler drin.
Könnte vielleicht jemand mal ein Beispiel vorstellen, wie einen Pixel 
oder auch mehrere einschalten kann.

Vielen Dank nochmal und schönes Wochenende!

Gruß Andi

Autor: Denis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, hab vor kurzen auch einen Display mit diesem Controller 
erstanden.
Würde mich für eine kurze Hilfestellung zum Start interessieren!

Also wenn jemand ein Stück Code posten könnte, wär das echt super!

Gruß Denis

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.