|
|
View previous topic :: View next topic |
Author |
Message |
Ramona1805
Joined: 05 May 2010 Posts: 13
|
PIC18F458 18F4685 I2C to EA eDip320-8 Display doesn't work |
Posted: Wed May 05, 2010 12:46 am |
|
|
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
|
|
Posted: Wed May 05, 2010 1:30 am |
|
|
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
|
|
Posted: Wed May 05, 2010 5:11 am |
|
|
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
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
|
|
Posted: Wed May 05, 2010 12:53 pm |
|
|
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
|
|
Posted: Thu May 06, 2010 7:23 am |
|
|
Thank you very much!!!!!
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 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
|
separate Code into multiple c-Files |
Posted: Wed May 12, 2010 3:24 am |
|
|
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
|
|
Posted: Wed May 12, 2010 11:48 am |
|
|
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
|
|
Posted: Tue May 18, 2010 12:00 am |
|
|
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
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
|
|
Posted: Tue May 18, 2010 1:49 pm |
|
|
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. |
|
|
Ramona1805
Joined: 05 May 2010 Posts: 13
|
|
Posted: Tue May 18, 2010 11:14 pm |
|
|
Hi PCM Programmer,
thanks for fast reply..
the fish PUFFER is the german word for buffer 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
|
|
Posted: Wed May 19, 2010 12:21 am |
|
|
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
|
|
Posted: Mon Jun 28, 2010 1:05 am |
|
|
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. |
|
|
|
|
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
|