This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430g2553 I2C Oled Display problems

Other Parts Discussed in Thread: MSP430G2553

I say at the beginning, that i'm the beginner :)

I'm trying to write a simple code to control Adfruit Oled 128x64 I2C display. I have problems from the bigining. 

My code was based on those examples:

MSP430 I2C example

Arduino Example

There is olso example for SPI, but it's to complicated fo me to make it wor for I2C.

MSP430 Oled SSd1306 128x64 SPI

And This is begining of my code:

#include <msp430G2553.h>
#include "stdint.h"
#include "ascii_char.h"

#define OLED_CONTROL_BYTE_CMD_SINGLE	0x80
#define OLED_CONTROL_BYTE_CMD_STREAM	0x00
#define OLED_CONTROL_BYTE_DATA_STREAM	0x40

// Fundamental commands (pg.28)
#define OLED_CMD_SET_CONTRAST			0x81	// follow with 0x7F
#define OLED_CMD_DISPLAY_RAM			0xA4
#define OLED_CMD_DISPLAY_ALLON			0xA5
#define OLED_CMD_DISPLAY_NORMAL			0xA6
#define OLED_CMD_DISPLAY_INVERTED 		0xA7
#define OLED_CMD_DISPLAY_OFF			0xAE
#define OLED_CMD_DISPLAY_ON				0xAF

// Addressing Command Table (pg.30)
#define OLED_CMD_SET_MEMORY_ADDR_MODE	0x20	// follow with 0x00 = HORZ mode = Behave like a KS108 graphic LCD
#define OLED_CMD_SET_COLUMN_RANGE		0x21	// can be used only in HORZ/VERT mode - follow with 0x00 + 0x7F = COL127
#define OLED_CMD_SET_PAGE_RANGE			0x22	// can be used only in HORZ/VERT mode - follow with 0x00 + 0x07 = PAGE7

// Hardware Config (pg.31)
#define OLED_CMD_SET_DISPLAY_START_LINE	0x40
#define OLED_CMD_SET_SEGMENT_REMAP		0xA1
#define OLED_CMD_SET_MUX_RATIO			0xA8	// follow with 0x3F = 64 MUX
#define OLED_CMD_SET_COM_SCAN_MODE		0xC8
#define OLED_CMD_SET_DISPLAY_OFFSET		0xD3	// follow with 0x00
#define OLED_CMD_SET_COM_PIN_MAP		0xDA	// follow with 0x12

// Timing and Driving Scheme (pg.32)
#define OLED_CMD_SET_DISPLAY_CLK_DIV	0xD5	// follow with 0x80
#define OLED_CMD_SET_PRECHARGE			0xD9	// follow with 0x22
#define OLED_CMD_SET_VCOMH_DESELCT		0xDB	// follow with 0x30

// Charge Pump (pg.62)
#define OLED_CMD_SET_CHARGE_PUMP		0x8D	// follow with 0x14

// NOP
#define OLED_CMD_NOP 					0xE3

unsigned char *PTXData;
unsigned char TXByteCtr;

uint16_t i;
uint8_t j,c,s,b;

//const unsigned char init_cmd_array[] = { 0x00,0xAE,0xA8,0x3F,0xD3,0x00,0x40,0xA1,0xC8,0xDA,0x12,0x81,0x7F,0xA4,0xA6,0xD5,0x80,0x8D,0x14,0xD9,0x22,0xDB,0x30,0x20,0x00,0xAF};
const unsigned char init_cmd_array[] = {

    OLED_CONTROL_BYTE_CMD_STREAM,

	// Follow instructions on pg.64 of the dataSheet for software configuration of the SSD1306
	// Turn the Display OFF
	OLED_CMD_DISPLAY_OFF,
	// Set mux ration tp select max number of rows - 64
	OLED_CMD_SET_MUX_RATIO,
	0x3F,
	// Set the display offset to 0
	OLED_CMD_SET_DISPLAY_OFFSET,
	0x00,
	// Display start line to 0
	OLED_CMD_SET_DISPLAY_START_LINE,

	// Mirror the x-axis. In case you set it up such that the pins are north.
	// Wire.write(0xA0); - in case pins are south - default
	OLED_CMD_SET_SEGMENT_REMAP,

	// Mirror the y-axis. In case you set it up such that the pins are north.
	// Wire.write(0xC0); - in case pins are south - default
	OLED_CMD_SET_COM_SCAN_MODE,

	// Default - alternate COM pin map
	OLED_CMD_SET_COM_PIN_MAP,
	0x12,
	// set contrast
	OLED_CMD_SET_CONTRAST,
	0x7F,
	// Set display to enable rendering from GDDRAM (Graphic Display Data RAM)
	OLED_CMD_DISPLAY_RAM,
	// Normal mode!
	OLED_CMD_DISPLAY_NORMAL,
	// Default oscillator clock
	OLED_CMD_SET_DISPLAY_CLK_DIV,
	0x80,
	// Enable the charge pump
	OLED_CMD_SET_CHARGE_PUMP,
	0x14,
	// Set precharge cycles to high cap type
	OLED_CMD_SET_PRECHARGE,
	0x22,
	// Set the V_COMH deselect volatage to max
	OLED_CMD_SET_VCOMH_DESELCT,
	0x30,
	// Horizonatal addressing mode - same as the KS108 GLCD
	OLED_CMD_SET_MEMORY_ADDR_MODE,
	0x00,
	// Turn the Display ON
	OLED_CMD_DISPLAY_ON

};

const unsigned char WriteInit[] = { 0x00, 0x21, 0x00, 0x7F, 0x22, 0x00, 0x07 };

//const unsigned char TX[] = {0x00,0x7E,0x42,0x42,0x42,0x42,0x7E,0x00,0x00,0x7E,0x42,0x42,0x42,0x42,0x7E,0x00};
const unsigned char TX[] = {0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81,0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81};

const unsigned char TEST[]= {"This is test "};

unsigned char buffer[100];
unsigned int value;

int strlen(const unsigned char * str)
{
    const unsigned char *len;
    for (len = str; *len; ++len);
    return(len - str);
}

int WriteString(const unsigned char* character) {

	unsigned int size = strlen(character);

	for (s = 0; s < size; s++) {
		for (c = 0; c < 5; c++) {
			buffer[b] = ascii_table[(unsigned int) *character][c];
			b++;
		}
		*character++;
		if (b == size) {
			b = 0;
			character = 0;
		}
	}

	return size;
}

void WriteOLED(const unsigned char* data, unsigned char size) {

	PTXData = (unsigned char*)data;
	TXByteCtr = size;

	while (UCB0CTL1 & UCTXSTP);
	UCB0CTL1 |= UCTR + UCTXSTT;
}

void OLEDInit() {

	WriteOLED(init_cmd_array, sizeof(init_cmd_array));

	__delay_cycles(160000);

}

int main(void) {
	WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

	BCSCTL1=CALBC1_16MHZ;
	DCOCTL=CALDCO_16MHZ;

	P1DIR |= BIT0;

	P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0
	P1SEL2 |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0

	UCB0CTL1 |= UCSWRST;                      // Enable SW reset
	UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
	UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset
	UCB0BR0 = 12;
	UCB0BR1 = 0;
	UCB0I2CSA = 0x3C;                         // Slave Address
	UCB0CTL1 &= ~UCSWRST;                    // Clear SW reset, resume operation
	IE2 |= UCB0TXIE;                          // Enable TX interrupt

	__enable_interrupt();

	OLEDInit();

	value = (WriteString(TEST)*5);


	while (1) {

		WriteOLED(WriteInit, sizeof(WriteInit));


		for (i = 0; i < 1024; i++) {
			WriteOLED((unsigned char*)OLED_CONTROL_BYTE_DATA_STREAM,1);
			for (j = 0; j < 16; j++) { //j=1 for text
				WriteOLED((unsigned char*)0x81,1);
				WriteOLED((unsigned char*)0x02,1);
				WriteOLED(TX, sizeof(TX)); //Test array
				//WriteOLED(buffer, value); //Text
				i++;
			}
			i--;
		}
		__delay_cycles(160000);
	}
}

#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void) {

	  if (TXByteCtr)                            // Check TX byte counter
	  {
	    UCB0TXBUF = *PTXData++;                 // Load TX buffer
	    TXByteCtr--;                            // Decrement TX byte counter
	  }
	  else
	  {
	    UCB0CTL1 |= UCTXSTP;                    // I2C stop condition
	    IFG2 &= ~UCB0TXIFG;                     // Clear USCI_B0 TX int flag
	  }

	P1OUT ^= BIT0;
}
"ascii_char.h" is from the third exaple.

This is how it looks like:



So in the first place I want to ask You, why I have to set:

BCSCTL1=CALBC1_16MHZ;
DCOCTL=CALDCO_16MHZ;

and

	UCB0BR0 = 12;

to make this work.

Which is different than in the first example, to make this work, may someone explain me this?

My second question is...

I have to use

__enable_interrupt();

becouse it also doesn't work with:

    __bis_SR_register(CPUOFF + GIE); 

and

   __bic_SR_register_on_exit(CPUOFF); 

Could You explain me that too?

And my last question is...

For example if I want to send some big array to Oled, for exaple with 1024 bytes, the same like

here...

How should I do this? Any ideas? This is MSP430G2553 microcontroller, so I can't put so big array to it memory I guess. 

I will appreciate any help and explanations. Greetings from Poland.

**Attention** This is a public forum