Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ST7036i and mikroc STUCK

Status
Not open for further replies.
Hi,

If I had to debug it I'd use a scope to see the signals.
With it you exactly see the signals on the bus...you are able to detect software problems as well as hardware problems.

Hardware problems still may be:
* Missing or wrong value external pullup (soldering error?)
* wrong timing, maybe caused by too high external capacitance... or too early starting communication after reset/power up
* wrong signal levels (check whether they meet both microcontroller as well as display specifications)
* power supply issues ( level, ringing, slowly rising, overshot...missing capacitors...)

I recommend to use the hardware periferal instead of bit banging
And I recommend to use reliable library (the microC one should be) instead of building your own.
Don't trust random internet code.

Klaus
 

OK...i thank you all for your replies. i bought an oscilloscope (SIGLENT SDS 1102 CML+), low end model. i sceen caputred results of i2c communication. I changed my code and im using mikroc i2c library. It looks like i am getting ack on every byte but i cannot seem to send data, i have tried and read so much. i feel like its something simple im missing. i wrote a function called 'show', 'hello' and 'output_count'. i have written many variations of them. by the way, the oscilloscope was LONG overdue.
Code:
bit oldstate_00;
bit oldstate_01;
sbit white at PORTE.B0;
sbit green at PORTE.B2;

char count;
char temporary = 0;
const char text1[] = "I did it";

void blink(char i){         // for debug, blink led x times
     char j;
     for (j=0;j<i;j++){
        white = ~white;
        Delay_ms(50);
        }
     if (white == 1){
        white = 0;}
     }
    
void rotary(){              // basic rotary encoder function for turning left and right
     char temp;
     temp = PORTC & 0b00000011;
     if (temp == 1){
        count++;
        Delay_ms(77);
        }
     if (temp == 2){
        count--;
        Delay_ms(77);
        }
     }
    
void min_max(char limit){       // set max count so i dont have to turn so far
     if (count >= 250){
        count = 0;}
     if (count >= limit){
        if (count <= 249){
           count = limit;
           }
        }
     }

void init_LCD(){      // this wont work, only works when this code is in void main... not as a function
     I2C1_Start();                  // I2C start signal
     I2C1_Wr(0x78);                 // address 0X78
     I2C1_Wr(0x00);                 // control byte
     I2C1_Wr(0x38);                 // function set
     I2C1_Wr(0x39);                 // function set
     I2C1_Wr(0x14);                 // bias
     I2C1_Wr(0x78);                 // contrast set
     I2C1_Wr(0x5E);                 // power/icon/contrast control
     I2C1_Wr(0x6D);                 // follower control
     I2C1_Wr(0x0C);                 // display on
     I2C1_Wr(0x01);                 // clear display
     I2C1_Wr(0x06);                 // entry mode set
     I2C1_Stop();                   // I2C stop signal
     }

void Show(unsigned char *text){     // attemping to print to lcd
     int n;
     int result;
     result = strlen(text);
     I2C1_Start();
     I2C1_Wr(0x78);
     I2C1_Wr(0x40);
     I2C1_Repeated_Start();
     for(n=0;n < result + 1;n++){
        I2C1_Wr(*text);
        ++text;
        }
     I2C_Stop();
     }

void hello(){                         // attemping to print to lcd
     I2C1_Start();
     I2C1_Wr(0x78);
     I2C1_Wr(0x40);
     I2C1_Repeated_Start();
     I2C1_Wr(count + 48);
     I2C1_Stop();
     }

void output_count(){                 // attemping to print to lcd
     if (temporary != count){
        temporary = count;

        I2C1_Start();
        I2C1_Wr(0x78);
        I2C1_Wr(0xC0);
        I2C1_Wr(count + 48);
        I2C1_Stop();

        UART1_Write(0x0D);
        UART1_Write(0x0A);
        UART1_Write(count+48);
        UART1_Write(0x0D);
        UART1_Write(0x0A); }
     }

void main() {
     // setting up 18f4523 for use
     INTCON = 0b11100000; INTCON2.B7 = 1; IPEN_bit = 0;
     PIE1 = 0b00001000; SSPIE_bit = 1;

     TRISA = 0; PORTA = 0; LATA = 0; TRISB = 0; PORTB = 0; LATB = 0;
     TRISC = 0b0111111; PORTC = 0; LATC = 0;
     TRISD = 0b00000001; PORTD = 0; LATD = 0;
     TRISE = 0b00000010; PORTE = 0; LATE = 0;
     TMR0ON_bit = 0; TMR1ON_bit = 0; TMR2ON_bit = 0; TMR3ON_bit = 0;
     CCP1CON = 0; CCP2CON = 0;

     TXEN_bit = 0; SPEN_bit = 0; CREN_bit = 0;
     ADON_bit = 0; ADCON0 = 0; ADCON1 = 0x0F;
     CMCON = 0x07; CVREN_bit = 0; CVROE_bit = 0;
     HLVDEN_bit = 0;
    
     /* should be taken care of by hardware i2c
     SSPSTAT = 0;
     SSPEN_bit = 1; SSPCON1 = 0b00101000; //SSPCON1.B3 = 1; SSPCON1.B2 = 0; SSPCON1.B1 = 0; SSPCON1.B0 = 0;
     BRG16_bit = 0x18;SSPADD = 0x63;           */

     // initial variable declaration
     white = 0; green = 0; oldstate_00 = 0; oldstate_01 = 0;
     count = 0; count_temp = 0; i = 1; temporary = count;

     blink(10); green = 1;
    
     UART1_Init(115200);
     Delay_ms(100);
     I2C1_Init(100000);         // initialize I2C communication
     Delay_ms(500);
    
     /*init_LCD();*/  // THIS DOESNT WORK HERE FOR SOME REASON
     I2C1_Start();              // I2C start signal
     I2C1_Wr(0x78);                  // address 0X78
     I2C1_Wr(0x00);                  // control byte
     I2C1_Wr(0x38); //Delay_us(250);   // function set
     I2C1_Wr(0x39); //Delay_ms(2);   // function set
     I2C1_Wr(0x14);                 // bias
     I2C1_Wr(0x78);                 // contrast set
     I2C1_Wr(0x5E); //Delay_ms(2);   // power/icon/contrast control
     I2C1_Wr(0x6D);                 // follower control
     I2C1_Wr(0x0C);                 // display on
     I2C1_Wr(0x01);                 // clear display
     I2C1_Wr(0x06); //Delay_ms(2);   // entry mode set
     I2C1_Stop();                   // I2C stop signal

     Delay_ms(100);

     blink(7); green = 0;

     do{

        rotary();

        min_max(9);

        output_count();
        
        if (Button(&PORTE,1,1,1)){               // The lonely button
           oldstate_00 = 1;
           white = 1;}
        if (oldstate_00 && Button(&PORTE,1,1,0)){
           oldstate_00 = 0;
           white = 0;
           show("i did it");
           }

        if (Button(&PORTD,0,1,0)){               // rotary encoder button
           oldstate_01 = 1;
           white = 1;}
        if (oldstate_01 && Button(&PORTD,0,1,1)){
           oldstate_01 = 0;
           white = 0;
           UART1_Write(count + 48);
           UART1_Write(0x0D); UART1_Write(0x0A);
           hello();
           }

        }while(1);
}



full.jpg
zoom_1.jpg
zoom_2.jpg
zoom_3.jpg
zoom_4.jpg
 

Attachments

  • 18F4523 i2c.pdf
    26 KB · Views: 96

Hi,

It looks like i am getting ack on every byte but i cannot seem to send data, i have tried and read so much. i feel like its something simple im missing. i
Yes, it seems you missed one of the most basic rules for I2C: Never drive the signals HIGH. Neither SCL nor SDA.
I2C signals need to be driven LOW or OPEN. Never HIGH.
When OPEN, the external pull up will make the signal HIGH, as long as no other slave drives it LOW.

Focus on the ninth clock (ACK) where the voltage level is in intermediate state. This tells me the slave drives LOW to indicate a valid ACK, but the master drives actively HIGH. This causes short circuit condition on the bus...and thus the intermediate voltage level.

Klaus
 

if im using mikroc i2c library, how am i driving signal high, it is pulled high, the purple signal is the clock, yellow data, it does read the correct binary that is sent for lcd initialization. i didnt get why the 9th pulse is not zero volts though. i did not see a detail in the data sheet to drive signal high.
--- Updated ---

i will read the datasheet again. the other possibility is a level shift circuit (2 fet's, 2n7000) my scope is probing the 3.3v side of that circuit, same results from the 5v side.
 
Last edited:

Hello,

...What confuses me is that, why does the init_lcd not work as a function but seems to initialize the lcd while that code is place direcrly in main?

where is defined the device adress ?
slave=0x00 ?

must be assigned into the beginning of main ()
 

I see an initial low state of I2C lines in your waveforms which should never happen. SCL and SDA should be high before and after I2C setup. First low state is expected during start condition.
 

The scope is setup for single shot capture, when i disable the single shot the two lines are high, when i enable single shot they dissapear. It is set to trigger when the signal goes low. You just dont see them but they are high.
--- Updated ---

I will look into this and verify, just in case and then i will post pics of the findings. Thank you.
 
Last edited:

the lines are high, scope is set to single shot capture mode. so when the lines go low, it records. i verified this. 1st pic, lines are high at boot up of pic. 2nd pic, turned on single capture mode, lines are still high. 3rd pic, captured I2C lcd initialization bytes, and end with SDA and SCL lines high. this seems to be working correctly. The 9th byte (ack) is floating at about 1.2v, the scope is connected to the 3.3v side of the I2C level shifter (the 2 2n7000 fets in the schematic).
 

Attachments

  • after boot_run mode.jpg
    after boot_run mode.jpg
    41.2 KB · Views: 101
  • switched to single mode.jpg
    switched to single mode.jpg
    38.5 KB · Views: 99
  • initialization_ending with high lines.jpg
    initialization_ending with high lines.jpg
    66.5 KB · Views: 93
  • 18F4523 i2c.pdf
    26 KB · Views: 54

Still don't understand how initialization can start with SCL and SDA low.
 

they are both high, in the first pic they are shown high, they remain this way. then i switch to single shot and they disappear (pic 2) until triggered. when the sda and scl go low from the start command, the scope begins capturing (pic 3). the signals are seen at the beginning of pic 3 as being low, but that is just case they switched to low from the start command and caused the scope capture to begin which is seen as the lines already low. i dont think they are low until the start command.
 

Hello,



where is defined the device adress ?
slave=0x00 ?

must be assigned into the beginning of main ()

This is in void main at the start of the lcd initialization.

I2C1_Start(); // I2C start signal
I2C1_Wr(0x78); // address 0X78 - (lcd address)
I2C1_Wr(0x00); // control byte
 

Besides mysterious start at low level there's an illegal logic level of about 1.3V in SDA trace. It suggests a hardware problem, e.g. not correctly working level converter.
 

it does not start at low level, AFTER it goes low, it gets captured by the scope, that is what you see. I will look into level converter, I am sure the 1.3v ahould be 0v. But if 1.3 is low enough logic level, wouldnt it still be interpreted as a zero logic. Also, if the ack is not correct (i.e. no ack) i thought the library would not continue transmision of bytes. That you for your time.
--- Updated ---

Thank you for your time
 

Hi,
AFTER it goes low, it gets captured by the scope,
After it goes low .... thats the point ... then it IS low....both I2C signals .... then starts the communication....

I agree with FvM that this is an unusual I2C condition.

******
But if 1.3 is low enough logic level,
1.3V is not a valid
* TTL LOW level
* CMOS LOW level
* LOW level according I2C specification
* LOW level according PIC 18F4523 specification

Klaus
 

it does not start at low level, AFTER it goes low, it gets captured by the scope, that is what you see. I will look into level converter, I am sure the 1.3v ahould be 0v. But if 1.3 is low enough logic level, wouldnt it still be interpreted as a zero logic. Also, if the ack is not correct (i.e. no ack) i thought the library would not continue transmision of bytes. That you for your time.
Are you saying that your oscilloscope is displaying captured data differently than any oscilloscope on the market, hence the shown waveform isn't real? Hard to believe.

As for the 1.3V, it's no legal CMOS low level (> 0.3 Vdd) but may be typically read as low. I2C library does not stop on NAK with your code unless you explicitly test for ACK.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top