Hello, I'm new here, and I'm trying to establish an I2C communication to my OLED Display , with the US2066 IC (http://www.buy-display.com/download/ic/US2066.pdf).
I've searched in this forum for some help on the I2C USCIB0 Communication and I used as a base the code from this topic: http://forum.43oh.com/topic/3216-need-help-with-i2c-using-msp430g2553/?hl=g2553#entry31766
This is my code right now:
#include "msp430g2553.h"
static int Num_bytes_tx = 0;
static int Byte_count;
static char BuffOutput[70];
static char Slv_add;
static int RPT_flag = 0;
static unsigned char TxByteCtr;
void I2CEndTx(unsigned char prescale){
TxByteCtr = Num_bytes_tx;
_DINT();
while (UCB0CTL1 & UCTXSTP);
UCB0CTL1 |= UCSWRST; // 1- USCI Enable, 0- Release state.
P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0
P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // Setting Master mode, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = prescale; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = Slv_add; // Set slave address (write OLED)
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
IE2 |= UCB0TXIE; // Enable TX interrupt
while(UCB0CTL1 & UCTXSTP);
UCB0CTL1 |= UCTR + UCTXSTT;
}
void I2CWrite(char info){
BuffOutput[Num_bytes_tx]=info;
Num_bytes_tx++;
}
void I2CBeginTx(char add){
Slv_add = add;
Num_bytes_tx =0;
Byte_count=0;
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
BCSCTL1 = CALBC1_8MHZ;
DCOCTL = CALDCO_8MHZ;
P1DIR |= BIT4; //Reset PIN
P1SEL &= ~BIT4;
P1SEL2 &= ~BIT4;
P1OUT |= BIT4;
__delay_cycles(200);
P1OUT &= ~BIT4;
__delay_cycles(200);
P1OUT |= BIT4;
__delay_cycles(200);
I2CBeginTx(0x78);//Slave adress+Write
I2CWrite(0x80);
I2CWrite(0x2A);
I2CWrite(0x80);
I2CWrite(0x71);
I2CWrite(0xC0);
I2CWrite(0x00);
I2CWrite(0x80);
I2CWrite(0x28);
I2CWrite(0x80);
I2CWrite(0x08);
I2CWrite(0x80);
I2CWrite(0x2A);
I2CWrite(0x80);
I2CWrite(0x79);
I2CWrite(0x80);
I2CWrite(0xD5);
I2CWrite(0x80);
I2CWrite(0x70);
I2CWrite(0x80);
I2CWrite(0x78);
I2CWrite(0x80);
I2CWrite(0x08);
I2CWrite(0x80);
I2CWrite(0x06);
I2CWrite(0x80);
I2CWrite(0x72);
I2CWrite(0xC0);
I2CWrite(0x01);
I2CWrite(0x80);
I2CWrite(0x2A);
I2CWrite(0x80);
I2CWrite(0x79);
I2CWrite(0x80);
I2CWrite(0xDA);
I2CWrite(0x80);
I2CWrite(0x10);
I2CWrite(0x80);
I2CWrite(0xDC);
I2CWrite(0x80);
I2CWrite(0x00);
I2CWrite(0x80);
I2CWrite(0x81);
I2CWrite(0x80);
I2CWrite(0x8F);
I2CWrite(0x80);
I2CWrite(0xD9);
I2CWrite(0x80);
I2CWrite(0xF1);
I2CWrite(0x80);
I2CWrite(0xDB);
I2CWrite(0x80);
I2CWrite(0x30);
I2CWrite(0x80);
I2CWrite(0x78);
I2CWrite(0x80);
I2CWrite(0x28);
I2CWrite(0x80);
I2CWrite(0x01);
I2CWrite(0x80);
I2CWrite(0x80);
//__delay_cycles(1000);
I2CWrite(0x80);
I2CWrite(0x0C);
I2CEndTx(0x28); //manda o prescale e slv_add
__bis_SR_register(CPUOFF + GIE);
while(1){}
}
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
if (UCB0STAT & UCNACKIFG)
{ // send STOP if slave sends NACK
UCB0CTL1 |= UCTXSTP;
UCB0STAT &= ~UCNACKIFG;
}
else{
if(TxByteCtr){
UCB0TXBUF = BuffOutput[Byte_count];
Byte_count++;
TxByteCtr--;
// __bic_SR_register_on_exit(CPUOFF);
}
else
{
if(RPT_flag == 1)
{
RPT_flag = 0;
TxByteCtr = Num_bytes_tx;
__bic_SR_register_on_exit(CPUOFF);
}
UCB0CTL1 |= UCTXSTP; // I2C stop condition
IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX intterupt flag
__bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
}
}
I don't have an osciloscope or any type of Logic Analyzer. But I can see on the register that the NACK Flag is being setting, and only one byte is shifted to UCB0TXBUF. After it, the program just stops on my while(1) and never interrupts again.
On this code I'm just trying to initialize the Oled Display. I've cheked the hardware thousands times, and it seems ok.
Can anybody give me an opinion on what to do? What could be wrong?
Thanks for the attention.