CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

PIC18F458 18F4685 I2C to EA eDip320-8 Display doesn't work

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ramona1805



Joined: 05 May 2010
Posts: 13

View user's profile Send private message

PIC18F458 18F4685 I2C to EA eDip320-8 Display doesn't work
PostPosted: Wed May 05, 2010 12:46 am     Reply with quote

Hello everybody,

I need help because I don't know whats wrong.
I want to test an I2C-communication between PIC18f458 as Master (later on PIC18f4685) and my Display EAeDip320-8 (Slave).
But nothing happens on osciloscope.
I'm using MPLAB IDE v8.46 together with CCS-Compiler.

In order that you could help me as much as possible here are the datasheets:
PIC18F458:
http://ww1.microchip.com/downloads/en/devicedoc/41159d.pdf
I2C page 154; I2C-Master page 169 Display:
http://www.lcd-module.de/eng/pdf/grafik/edip320-8e.pdf
I2C page 7; expressions page 14

I've done the following cable system:
Quote:

Display GND (PIN1) - Voltage GND
Display VDD (PIN2) - Voltage+5V
Display GND (PIN1) - GND Pic-Board
Display I2CMODE (PIN12) - Display GND
Display SCL (PIN15) - Pic SCL (C3)
Display SDA (PIN14) - Pic SDA (C4)
Pic SCL over Pullup 12k - Pic-Board voltage 5V
Pic SDA over Pullup 12k - Pic-Board voltage 5V

Could be that this includes mistakes as well.

Here's my test code:
Code:

#include "18F458.h"

#FUSES H4, NOWDT //H4 for faster clock-speed because of IRQ-handling
#use I2C(Master, SDA=PIN_C4, SCL = PIN_C3, FAST, FORCE_HW)

#int_SSP
SSP_isr()
{   
   //empty because of testing only the communication
}

void main()
{
   enable_interrupts(global);
   enable_interrupts(INT_SSP);

   set_tris_d(0x00); //Output for LEDs
   set_tris_c(0b00011000); //SDA and SCL als INPUT (Datasheet)
   output_d(0xFF); //all LEDs off(OFF = 1, ON = 0)

   while(1)
   {
      //Sending the Command for invert the Displays
       
      i2c_start();
      output_bit(PIN_D0,~input(PIN_D0));
       
      i2c_write(0b11011110);   //sending slave-adress including 0 for writing
      output_bit(PIN_C2, ~PIR2[3]);
      output_bit(PIN_D1,~input(PIN_D1));

      i2c_write(0x11);   //Hex-Code for '#'
      output_bit(PIN_D2,~input(PIN_D2));

      i2c_write(0x02);   //Datalength
      output_bit(PIN_D3,~input(PIN_D3));

      i2c_write(0x44);   //Hex-Code for 'D'
      output_bit(PIN_D4,~input(PIN_D4));

      i2c_write(0x49);   //Hex-Code for 'I'
      output_bit(PIN_D5,~input(PIN_D5));
   
      i2c_write(0xA0);   //sum of all bytes
      output_bit(PIN_D6,~input(PIN_D6));

      i2c_stop();
      output_bit(PIN_D7,~input(PIN_D7));
   }
}

The LEDs are to show if the code is running through. But then I had to notice that the PIC does not come over the first write-command.
On oscilloscope I don't even see a clock-signal

As mentioned before I don't know how to go on. ( I'd be glad about your help.
The code-examples I've found show me that the i2c_start, write and stop commands would be enough.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 05, 2010 1:30 am     Reply with quote

1. Where is your #use delay() statement ? You need one. It must match
the oscillator speed.

2. You have this statement:
Quote:

#use I2C(Master, SDA=PIN_C4, SCL = PIN_C3, FAST, FORCE_HW)

Don't use FAST mode. The display data sheet says:
Quote:

Data transfer is possible at up to 100 kHz.
However, if pauses of at least 100 µs are
maintained between the individual bytes
during transfer, a byte can be transferred at
up to 400 kHz.

100 KHz is Slow mode. Maybe you can make it work with FAST mode
later, but initially you should use slow mode. Delete the 'FAST'
parameter from the #use i2c() statement.

Also, it's best to start by using software i2c mode. It's more likely to
work. Later, you can change to hardware i2c if you wish. Delete the
'FORCE_HW' parameter from the #use i2c().


3. Interrupts are not used with an i2c Master. Delete the following lines:
Quote:

#int_SSP
SSP_isr()
{
}

enable_interrupts(global);
enable_interrupts(INT_SSP);


4. You're using Standard i/o mode (the default i/o mode). In this mode,
the compiler automatically sets the TRIS for you. You don't have to do
it. Delete the following lines:
Quote:

set_tris_d(0x00); //Output for LEDs
set_tris_c(0b00011000); //SDA and SCL als INPUT (Datasheet)


5. The implication of your i2c slave address (0xDE) is that you have
left pins BA0 to BA2 unconnected. There is an i2c address table on
page 7 of the display data sheet that shows this. Can you confirm that
pins BA0-BA2 are left open on your board ? Make sure you didn't
connect them to ground. This would change the i2c slave address.

Also, 12K pullups are too light for FAST mode. They're probably OK for
slow mode, though normally I use 4.7K for that.

I don't have enough time to look at your command protocol yet.

6. You said:
Quote:

But then I had to notice that the PIC does not come over the first write
command. On oscilloscope I don't even see a clock-signal.

Disconnect the SDA and SCL lines on the display from the PIC. Leave
the pull-up resistors connected to the PIC. Then run this simple test
program. Do you see packets of square-wave pulses on the SCL and
SDA lines ? You should.
Code:

#include <18F458.h>
#fuses HS,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=20000000)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)

//=================================
main()
{

while(1)
  {
   i2c_write(0x55);
  }

}

Change the #use delay frequency to match the oscillator speed of your
PIC. The code above is set for a 20 MHz crystal.
Ramona1805



Joined: 05 May 2010
Posts: 13

View user's profile Send private message

PostPosted: Wed May 05, 2010 5:11 am     Reply with quote

Hi PCM programmer,

At first thank you very much for your fast answer!
I did change my code like you told me to.
And now I really see a clock and data signal Smile

But there are no real square-wave pulses like in this picture...
Its getting "slowly"(nearly 2µs) to high and then falls down again (like start of a sinewave, sorry can't take a picture).
Could this come from the 12k pullup? and would perhaps be better with 4.7k?

But also nothing happens on display, could this be because of sending byte after byte without a few waiting? How could I put a short wait-statement between the writing?

I'm sorry that I can't describe it better, but as you can see my english is not very well, especially the technical terms :(

About the slave address I'm sure that it's right because I've done no changes on BA0 to 2 and I've also read about 0xDE being right..

Thank you very much for your help again, would be nice to hear from you =)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 05, 2010 12:53 pm     Reply with quote

Quote:

Its getting "slowly"(nearly 2µs) to high and then falls down again
(like start of a sinewave, sorry can't take a picture).
Could this come from the 12k pullup?

Yes, that's the reason. Change it to 4.7K and it will look much better.
Or you could use 2.2K to get a faster rise time.

Here is a test program based on the example given in the EA e320DIP-8
data sheet, at the bottom of page 9. The i2c details are given at the
bottom of page 7 in the data sheet. Try this and see if it works.
Code:

#include <18F458.h>
#fuses HS,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)

#define eDIP320_WRITE_ADDR 0xDE
#define eDIP320_READ_ADDR  0xDF

#define DC1  0x11
#define ESC  0x1B
#define ACK  0x06

int8 eDIP320_line_test(void)
{
int8 result;

i2c_start();
i2c_write(eDIP320_WRITE_ADDR);   

// Send a Small Protocol packet
i2c_write(DC1); 
i2c_write(0x0E);  // data length (in bytes)

i2c_write(ESC);   // Clear display command
i2c_write('D');
i2c_write('L');

i2c_write(ESC);  // Draw line command
i2c_write('G');
i2c_write('D');

i2c_write(0);    // X0 = 0
i2c_write(0);

i2c_write(0);    // Y0 = 0
i2c_write(0);

i2c_write(0x3F);  // X1 = 319 (0x13F)
i2c_write(0x01);

i2c_write(0xEF);  // Y1 = 239 (0x0EF)
i2c_write(0x00);

i2c_write(0x9F);  // Checksum

i2c_stop();

delay_us(6);    // Delay before read operation

i2c_start();
i2c_write(eDIP320_READ_ADDR);
result = i2c_read(0); // Read Ack byte
i2c_stop();

if(result == ACK)
   return(TRUE);
else
   return(FALSE);
}

//===================================================

void main()
{
int8 result;

delay_ms(100);  // Power-up delay (possibly needed)   

result = eDIP320_line_test();

if(result == TRUE)
   printf("Command OK\r\n");
else
   printf("Protocol failure\r\n");

while(1);
}
Ramona1805



Joined: 05 May 2010
Posts: 13

View user's profile Send private message

PostPosted: Thu May 06, 2010 7:23 am     Reply with quote

Thank you very much!!!!! Laughing
You saved my day!!!

Everything works fine now!
After changing the pullups the signal looks better and the display receives my commands!!!

First I tested my program (with some changes, because I found some mistakes in the first posted code as well) but it didn't really work.. Don't know why.. because after your program working very well I tested mine again and it work as well Smile but no more thinking.. I'm so glad that it's functioning now!! I wouldn't have managed without you..
Ramona1805



Joined: 05 May 2010
Posts: 13

View user's profile Send private message

separate Code into multiple c-Files
PostPosted: Wed May 12, 2010 3:24 am     Reply with quote

Hello again,

I've got a new problem on i2c-communication to my display.

I wrote several functions in order to send commands to display
as you can see here:

Code:
//Display-Konstanten:
#define writeAddress   0xDE
#define readAddress    0xDF
//Befehle im Binär-Mode
#define DC1 0x11
#define DC2 0x12
#define ESC 0x1B
#define ACK 0x06
#define NUL 0x00


int sum = 0;
int length = 0;
int j = 0;

//1Byte (8bit) auf I2C schreiben
int write8(char c)
{
   i2c_write(c);
   return c;
}

//2Byte (16bit) auf I2C schreiben
//(für Koordinaten)
int write16(int16 i)
{
   int xySum = 0;
   i2c_write(MAKE8(i, 0)); //LSB
   xySum += MAKE8(i, 0);
   i2c_write(MAKE8(i, 1)); //MSB
   xySum += MAKE8(i, 1);
   return xySum;
}

int1 drawLine(int16 x1, int16 y1, int16 x2, int16 y2)
{
   sum = 0;
   
   i2c_start();
   write8(writeAddress);
   
   sum += write8(DC1);
   sum += write8(11); //length
   sum += write8(ESC);
   sum += write8('G');
   sum += write8('D');
   
   sum += write16(x1);
   sum += write16(y1);
   sum += write16(x2);
   sum += write16(y2);
   
   write8(sum);
   i2c_stop();
   
   i2c_start();
   write8(readAddress);
   if(i2c_read(0)==ACK)
   {
      i2c_stop();
      return true;
   }
   else
      return false;
}


It's no problem to use this functions if they are in main-file..
but now I want to put them into a separate c-file..
I read a lot of topics about that and followed this arguments:
- only main.c as source file
- display.c in "other files"
- #include "display.c" in main.c

But then I couldn't use the i2c_start / write / read / stop statements anymore.
According to some code snippets I should put the #include "display.c" into the display.c-file too.
But if I do so it first seems to work (i2c_write is ok now) but then I get the error too many nested #INCLUDEs
even though I only include my header file, string.h and the display.c in main.c

Don't know how to fix this problem. Would be happy if you could help me again =)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 12, 2010 11:48 am     Reply with quote

The #use i2c() statement can go at the start of the display.c file.
Example: Look in this CCS eeprom driver file:
Quote:
c:\program files\picc\drivers\24256.c


Or, you can put the #use i2c() statement in main.c, but put it above
the #include statement for the display.c file.

The key point is, the #use i2c() statement must occur before the i2c
functions are used in the program. The compiler must see it first,
before it attempts to compile any i2c functions.
Ramona1805



Joined: 05 May 2010
Posts: 13

View user's profile Send private message

PostPosted: Tue May 18, 2010 12:00 am     Reply with quote

Thank you again PCM programmer!
I'm sorry about such stupid questions :/
but the next one came up.. :(

I tried to read out the display (buffer information) as I found in some threads as well..
Here's my code:
Code:

   i2c_start();
   i2c_write(writeAddress);
   
   i2c_write(DC2);
   i2c_write(1);
   i2c_write('I');
   sum = DC2+1+'I';
   i2c_write(sum);
   i2c_stop();

   delay_us(6);

   i2c_start(); //Start-Bit
   i2c_write(readAddress);

   puffer[0]=i2c_read();   //ACK
   delay_us(6);

   puffer[1]=i2c_read(); //DC2
   delay_us(6);
   

   puffer[2]=i2c_read(); //2
   delay_us(6);

   puffer[3]=i2c_read();   //bytes ready
   delay_us(6);

   puffer[4]=i2c_read(); //bytes free
   delay_us(6);
   
   puffer[5]=i2c_read(0); //bcc

   delay_us(6);
         

   i2c_stop();
   output_d(~puffer[1]);
}
with puffer as
Code:
 char puffer[10];

most of the times the ACK comes up
but the second i2c_read(); I get a 0x00 :( but it has to be a 0x02... because there have to be two data-bytes send..

Would be glad if you could help me again.. =)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 18, 2010 1:49 pm     Reply with quote

Tell me what command you are using. The LCD sheet has a list of
commands on page 14:
http://www.lcd-module.de/eng/pdf/grafik/edip320-8e.pdf

Also, if the LCD data sheet has an example for what you are doing,
then post the page that the example is on.

Also, one more small question. You said you're trying to read a buffer.
Why then, in your code, do you name the array "puffer" ? A puffer is
a fish. Smile
Ramona1805



Joined: 05 May 2010
Posts: 13

View user's profile Send private message

PostPosted: Tue May 18, 2010 11:14 pm     Reply with quote

Hi PCM Programmer,

thanks for fast reply..
the fish PUFFER is the german word for buffer Very Happy I forgot to change it..
in order to read out the buffer-information I use the command from page 8:
"Request for buffer information" DC2 1 I bcc...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 19, 2010 12:21 am     Reply with quote

It's possible that each line in the command protocol diagram represents
a separate i2c transaction, each with it's own i2c start and stop. Try
making the changes shown below in bold and see if it works.
Quote:

i2c_start();
i2c_write(writeAddress);

i2c_write(DC2);
i2c_write(1);
i2c_write('I');
sum = DC2+1+'I';
i2c_write(sum);
i2c_stop();

delay_us(6);

i2c_start();
i2c_write(readAddress);
puffer[0]=i2c_read(0); // Do a NACK - Get the ACK
i2c_stop();


i2c_start();
i2c_write(readAddress);

delay_us(6);
puffer[1]=i2c_read(); //DC2

delay_us(6);
puffer[2]=i2c_read(); //2

delay_us(6);
puffer[3]=i2c_read(); //bytes ready

delay_us(6);
puffer[4]=i2c_read(); //bytes free

delay_us(6);
puffer[5]=i2c_read(0); //bcc

i2c_stop();
output_d(~puffer[1]);
}
Ramona1805



Joined: 05 May 2010
Posts: 13

View user's profile Send private message

PostPosted: Mon Jun 28, 2010 1:05 am     Reply with quote

I'm sorry that I didn't write earlier but I've tested your idea already.
And you were right again.
Thank you very much!
And I hope that others with same problem like me would profit from this discussion.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group