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


von Humpawumpa (Gast)


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?

von Martink11 M. (Firma: google) (martink11) Flattr this


Lesenswert?

hi

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

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

von Humpawumpa (Gast)


Lesenswert?

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


1
#include <stdlib.h>
2
#include <string.h>
3
#include <stdio.h>
4
5
#include "FreeRTOS.h"
6
#include "task.h"
7
#include "croutine.h"
8
#include "queue.h"
9
#include "semphr.h"
10
11
#include "inc/hw_memmap.h"
12
#include "inc/hw_types.h"
13
#include "inc/hw_sysctl.h"
14
#include "driverlib/sysctl.h"
15
#include "driverlib/gpio.h"
16
#include "utils/ustdlib.h"
17
18
// Display Includes
19
#include "drivers/dd12864.h"
20
21
22
// ## All defines
23
// @OLED display
24
#define SYSCTL_PERIPH_GPIO_OLEDDC     SYSCTL_PERIPH_GPIOF
25
#define GPIO_OLEDDC_BASE              GPIO_PORTB_BASE
26
#define GPIO_OLEDDATA_BASE        GPIO_PORTF_BASE
27
#define GPIO_OLEDDC_PIN               GPIO_PIN_6
28
#define GPIO_OLEDWR_PIN          GPIO_PIN_5
29
#define GPIO_OLEDEN_PIN                GPIO_PIN_4
30
#define GPIO_OLEDRS_PIN          GPIO_PIN_3
31
#define GPIO_OLEDCS_PIN          GPIO_PIN_2
32
#define GPIO_OLEDMODE          GPIO_PIN_0 | GPIO_PIN_1
33
#define OLED_DATAPORT          GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7
34
// @others
35
#define mainHEARTBEAT_TASK_LED      2
36
#define mainBUTTEN_DOWN          GPIO_PIN_4
37
#define mainHEARTBEAT_PERIOD      ( ( portTickType ) 500 / portTICK_RATE_MS  )
38
39
// Flag to indicate if SSI port is enabled for display usage.
40
static volatile tBoolean g_bSSIEnabled = false;
41
42
43
//-----------------------------------------------------------
44
45
int main(void) {
46
47
  // Set the clocking to run directly from the crystal.
48
  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN
49
      | SYSCTL_XTAL_8MHZ);
50
51
  initOLEDDisplay();
52
53
  return 0; //should never reach this line
54
}
55
56
57
// initialize the OLED dsplay
58
void initOLEDDisplay() {
59
60
61
// Enable the SSI0 and GPIO port blocks as they are needed by this driver.
62
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
63
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
64
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIO_OLEDDC);
65
66
67
  GPIODirModeSet  ( GPIO_OLEDDATA_BASE, OLED_DATAPORT, GPIO_DIR_MODE_OUT );
68
    GPIOPadConfigSet( GPIO_OLEDDATA_BASE, OLED_DATAPORT, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD );
69
70
71
// Configure the GPIO port pin used as a D/Cn signal for OLED device,
72
// and the port pin used to enable power to the OLED panel.
73
    GPIOPinTypeGPIOOutput  (GPIO_OLEDDC_BASE, GPIO_OLEDRS_PIN | GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN | GPIO_OLEDMODE);
74
    GPIOPadConfigSet    (GPIO_OLEDDC_BASE, GPIO_OLEDRS_PIN | GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN | GPIO_OLEDMODE,
75
               GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
76
// Set Mode to parallel 8080
77
     GPIOPinWrite      (GPIO_OLEDDC_BASE, GPIO_OLEDMODE, GPIO_OLEDMODE);
78
//     GPIOPinWrite      (GPIO_OLEDDC_BASE, GPIO_OLEDRS_PIN | GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN | GPIO_OLEDMODE,
79
//               GPIO_OLEDRS_PIN | GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN | GPIO_OLEDMODE);
80
81
82
// Set the 15V
83
    GPIOPinTypeGPIOOutput  (GPIO_PORTH_BASE, GPIO_PIN_3);
84
    GPIOPadConfigSet    (GPIO_PORTH_BASE, GPIO_PIN_3,
85
               GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
86
    GPIOPinWrite      (GPIO_PORTH_BASE, GPIO_PIN_3, GPIO_PIN_3);
87
88
// Reset
89
    GPIOPinWrite      (GPIO_OLEDDC_BASE, GPIO_OLEDRS_PIN, 0);
90
    SysCtlDelay(30);
91
    GPIOPinWrite      (GPIO_OLEDDC_BASE, GPIO_OLEDRS_PIN, GPIO_OLEDRS_PIN);
92
93
  sendCommand(0x00);                         /* Set Lower Column Address */
94
  sendCommand(0x10);                         /* Set Higher Column Address */
95
96
  sendCommand(0x40);                         /* Set Display Start Line */
97
98
  sendCommand(0x81);                         /* Set Contrast Control */
99
  sendCommand(0x30);                         /* 0 ~ 127 */
100
101
  sendCommand(0xA0);                         /* [A0]:column address 0 is */
102
  sendCommand(0xC8);                         /* oben / unten */
103
104
  sendCommand(0xA4);                         /* A4=ON */
105
106
  sendCommand(0xA6);                        /* Normal Display*/
107
108
  sendCommand(0xA8);                         /* Set Multiplex Ratio */
109
  sendCommand(0x3f);
110
111
  sendCommand(0xAD);                         /* Set DC-DC */
112
  sendCommand(0x8E);                         /* 8B=ON, 8A=Off */
113
114
  sendCommand(0xAF);                        /* AF=ON , AE=OFF*/
115
116
  sendCommand(0xD3);                         /* Set Display Offset */
117
  sendCommand(0x00);                         /* No offset */
118
119
  sendCommand(0xD5);                         /* Set Clock Divide */
120
  sendCommand(0x61);                         /* Set to 80Hz */
121
122
  sendCommand(0xD8);                         /* Set Area Color On or Off */
123
  sendCommand(0x00);                         /* Mono Mode */
124
125
  sendCommand(0xDA);                         /* Set Pins Hardware */
126
  sendCommand(0x12);
127
128
  sendCommand(0xDB);                         /* Set VCOMH */
129
  sendCommand(0x00);
130
131
  sendCommand(0xD9);                         /* Set VP */
132
  sendCommand(0x22);                         /* P1=2 , P2=2 */
133
134
135
136
}
137
138
139
140
141
// Commandroutine
142
void sendCommand(const unsigned char command){
143
    // Set the command/control bit to enable data mode.
144
    GPIOPinWrite  (GPIO_OLEDDC_BASE, GPIO_OLEDDC_PIN | GPIO_OLEDCS_PIN | GPIO_OLEDWR_PIN | GPIO_OLEDEN_PIN , GPIO_OLEDEN_PIN);
145
146
    GPIOPinWrite  (GPIO_OLEDDATA_BASE, OLED_DATAPORT, command);
147
    GPIOPinWrite  (GPIO_OLEDDC_BASE, GPIO_OLEDWR_PIN, GPIO_OLEDWR_PIN);
148
149
}
150
151
152
// Dataroutine
153
void sendData(unsigned char data) {
154
    GPIOPinWrite  (GPIO_OLEDDC_BASE, GPIO_OLEDDC_PIN | GPIO_OLEDCS_PIN | GPIO_OLEDWR_PIN | GPIO_OLEDEN_PIN , GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN);
155
156
    GPIOPinWrite  (GPIO_OLEDDATA_BASE, OLED_DATAPORT, data);
157
    GPIOPinWrite  (GPIO_OLEDDC_BASE, GPIO_OLEDWR_PIN, GPIO_OLEDWR_PIN);
158
}
159
160
// Clear the display
161
void clearDisplay() {
162
163
}
164
165
void setPixel(int x, int y){
166
167
}

von Humpawumpa (Gast)


Lesenswert?

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

von Martink11 M. (Firma: google) (martink11) Flattr this


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!!!!!

von Humpawumpa (Gast)


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
1
#include <stdlib.h>
2
#include <string.h>
3
#include <stdio.h>
4
5
#include "FreeRTOS.h"
6
#include "task.h"
7
#include "croutine.h"
8
#include "queue.h"
9
#include "semphr.h"
10
11
#include "inc/hw_memmap.h"
12
#include "inc/hw_types.h"
13
#include "inc/hw_sysctl.h"
14
#include "driverlib/sysctl.h"
15
#include "driverlib/gpio.h"
16
#include "driverlib/i2c.h"
17
18
#include "utils/ustdlib.h"
19
20
// Display Includes
21
#include "drivers/rit128x96x4.h"
22
23
24
// ## All defines
25
// @OLED display
26
#define SYSCTL_PERIPH_GPIO_OLEDDC     SYSCTL_PERIPH_GPIOA
27
#define GPIO_OLEDDC_BASE              GPIO_PORTB_BASE
28
#define GPIO_OLEDDATA_BASE        GPIO_PORTA_BASE
29
#define GPIO_OLEDDC_PIN               GPIO_PIN_6
30
#define GPIO_OLEDWR_PIN          GPIO_PIN_5
31
#define GPIO_OLEDEN_PIN                GPIO_PIN_4
32
#define GPIO_OLEDRS_PIN          GPIO_PIN_3
33
#define GPIO_OLEDCS_PIN          GPIO_PIN_2
34
#define GPIO_OLEDMODE          GPIO_PIN_0 | GPIO_PIN_1
35
#define OLED_DATAPORT          GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7
36
// @others
37
#define mainHEARTBEAT_TASK_LED      2
38
#define mainBUTTEN_DOWN          GPIO_PIN_4
39
#define mainHEARTBEAT_PERIOD      ( ( portTickType ) 500 / portTICK_RATE_MS  )
40
41
// Flag to indicate if SSI port is enabled for display usage.
42
static volatile tBoolean g_bSSIEnabled = false;
43
44
45
//-----------------------------------------------------------
46
47
int main(void) {
48
49
  // Set the clocking to run directly from the crystal.
50
  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN
51
      | SYSCTL_XTAL_8MHZ);
52
53
//  initOLEDDisplay();
54
  /*
55
  // Set the 15V
56
      GPIOPinTypeGPIOOutput  (GPIO_PORTH_BASE, GPIO_PIN_3);
57
      GPIOPadConfigSet    (GPIO_PORTH_BASE, GPIO_PIN_3,
58
                 GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
59
      GPIOPinWrite      (GPIO_PORTH_BASE, GPIO_PIN_3, GPIO_PIN_3);*/
60
    // Initialize the OLED display.
61
    RIT128x96x4Init(1000000);
62
    RIT128x96x4StringDraw("oops?", 30, 24, 15);
63
    i2croutine();
64
    RIT128x96x4StringDraw("i did it again", 30, 44, 15);
65
  return 0; //should never reach this line
66
}
67
68
69
void i2croutine() {
70
71
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
72
73
  GPIODirModeSet  ( GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_OUT );
74
    GPIOPadConfigSet( GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD );
75
    GPIOPinWrite  ( GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_PIN_0 );
76
    SysCtlDelay(30*100);
77
    GPIOPinWrite  ( GPIO_PORTB_BASE, GPIO_PIN_1, GPIO_PIN_1 );
78
    SysCtlDelay(30*10);
79
  SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
80
  GPIOPinTypeI2C(GPIO_PORTB_BASE,GPIO_PIN_2 | GPIO_PIN_3);
81
82
  I2CMasterEnable(I2C0_MASTER_BASE);
83
  I2CMasterInitExpClk(I2C0_MASTER_BASE, SysCtlClockGet(), false);
84
85
  I2CMasterSlaveAddrSet(I2C0_MASTER_BASE, 0x3C, false);
86
  I2CMasterDataPut(I2C0_MASTER_BASE,0x80);
87
  I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
88
  while(I2CMasterBusy(I2C0_MASTER_BASE)){}
89
  I2CMasterDataPut(I2C0_MASTER_BASE, 0xAE);
90
  I2CMasterControl(I2C0_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
91
  while(I2CMasterBusy(I2C0_MASTER_BASE)){}
92
93
94
95
96
  char error[10];
97
  unsigned long mongobilli = I2CMasterErr(I2C0_MASTER_BASE);
98
  switch (mongobilli){
99
  case I2C_MASTER_ERR_NONE:
100
    usprintf(error,"none-nigga");
101
    break;
102
  case I2C_MASTER_ERR_ADDR_ACK:
103
    usprintf(error,"adr_akk");
104
    break;
105
  case I2C_MASTER_ERR_DATA_ACK:
106
    usprintf(error,"data_ack");
107
    break;
108
  case I2C_MASTER_ERR_ARB_LOST:
109
    usprintf(error,"arb_lost");
110
    break;
111
  default:
112
    usprintf(error,"error %x",mongobilli);
113
    break;
114
}
115
    RIT128x96x4StringDraw(error, 10,10,10);
116
117
118
}

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

von Erwin U. (Firma: privat) (eunger)


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.

von Andi (Gast)


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

von u8glib (Gast)


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

von Andi (Gast)


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

von Denis (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.