|
|
View previous topic :: View next topic |
Author |
Message |
Nopnop
Joined: 10 Aug 2007 Posts: 7
|
I2C FORCE_HW problems |
Posted: Fri Aug 10, 2007 3:30 pm |
|
|
Hi, I am French, sorry for my English.
If I have understood the I2C parameter FORCE_HW manage the I2C bus automatically.
When I execute this code I must add a delay_ms(5) after I2C_stop() for my data is written in EEPROM 24FC1025.
Can you tell me if the delay_ms(5) after I2C_stop is obligatory.
Thanks for your answers.
vAdresse=0x0000;
While(true)
{
i2c_start();
i2c_write(0xa0); // Contrôle
i2c_write(vAdresse>>8); // Adresse
i2c_write(vAdresse); // Adresse
i2c_write(vData>>8); // Data poids faible
i2c_write(vData); // Data poids fort
i2c_stop();
} |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 10, 2007 3:36 pm |
|
|
Download the eeprom data sheet.
http://ww1.microchip.com/downloads/en/DeviceDoc/21941B.pdf
Look at the Write Cycle Time (Param No. 17 on page 3). It's 5 ms.
The CCS driver uses "Ack Polling". This may allow the wait for
the write operation to be shorter than 5 ms. Why not use the
CCS driver ? Here's the file location:
Quote: | c:\Program Files\PICC\Drivers\241025.c |
|
|
|
Nopnop
Joined: 10 Aug 2007 Posts: 7
|
|
Posted: Tue Sep 04, 2007 2:47 pm |
|
|
Hi, PCM Programmer thanks for the solution of EEPROM.
Now I have a problem between two PIC 18F452.
When I send the address and data I don’t have the good result.
I have 00 00
And 01 90
And 90 90
Normally I should have
00 00
90 01
90 02
90 03
.. ..
If anyone have an ideas
Master code
Code: |
#include <18F452.h>
#fuses NOWDT,WDT128,HS, NOPROTECT, NOOSCSEN, BROWNOUT, BORV20, NOPUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use delay(clock=20000000)
#use i2c(MASTER, SCL=PIN_C3, SDA=PIN_C4, FAST=400000, FORCE_HW)
int data;
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_wdt(WDT_OFF);
enable_interrupts(GLOBAL);
set_tris_A(0b00010000); // Paramétrage du port A
set_tris_B(0b00110000); // Paramétrage du port B
set_tris_C(0b10011001); // Paramétrage du port C
set_tris_D(0b00000000); // Paramétrage du port D
set_tris_E(0b00000000);
data=0x01;
delay_ms(2000);
while(true)
{
i2c_start();
i2c_write(0x90); // Adresse
i2c_write(data++); // Data
i2c_stop();
delay_ms(100);
}
}
|
Slave code
Code: |
#include <18F452.h>
#fuses NOWDT,WDT128,HS, NOPROTECT, NOOSCSEN, BROWNOUT, BORV20, PUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use delay(clock=20000000)
#use i2c(SLAVE, ADDRESS=0x90, SCL=PIN_C3, SDA=PIN_C4, FAST=400000, FORCE_HW)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#include <LCD_nopnop.C>
int valeur1;
int valeur2;
#INT_SSP
void SSP_INT()
{
byte incoming,state;
state=i2c_isr_state();
if(state<0x80)
{
incoming=i2c_read(1);
if(state == 1) //First received byte is address
{
valeur1=incoming;
}
if(state == 2) //Second received byte is data
{
valeur2=incoming;
}
}
if (state>=0x80)
{
i2c_write(0x45);
}
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_wdt(WDT_OFF);
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
clear_interrupt(INT_SSP);
output_A(0);
output_B(0);
output_C(0);
output_E(0);
set_tris_A(0b00000001);
set_tris_B(0b10111111);
set_tris_C(0b10111011);
set_tris_E(0b00000100);
lcd_init(); // Init ecran LCD
valeur1=0;
valeur2=0;
while(true)
{
lcd_gotoxy(1,2);
printf(LCD_PUTC,"%x",valeur1);
lcd_gotoxy(4,2);
printf(LCD_PUTC,"%x",valeur2);
}
} |
_________________ made by www.nopnop.fr |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 04, 2007 3:29 pm |
|
|
Don't try to run the slave at 400 KHz. Change the i2c Master clock
speed to 100 KHz. |
|
|
Nopnop
Joined: 10 Aug 2007 Posts: 7
|
|
Posted: Wed Sep 05, 2007 2:09 pm |
|
|
Hi I have tried your advice with SLOW or FAST=100000.
The result is
00 00
01 00
02 00
03 00
…..
It is better but I don’t know why the data is first and address second. Normally it is the opposite. _________________ made by www.nopnop.fr |
|
|
Ttelmah Guest
|
|
Posted: Wed Sep 05, 2007 2:23 pm |
|
|
The address arrives when state==0. You are not printing this. Valeur2, remains '0', from when the chip woke up. You need:
Code: |
if(state<0x80)
{
incoming=i2c_read(1);
if(state == 0) //First received byte is address
{
valeur1=incoming;
}
if(state == 1) //Second received byte is data - '1' = first data
{ //byte received.
valeur2=incoming;
}
}
|
|
|
|
Nopnop
Joined: 10 Aug 2007 Posts: 7
|
|
Posted: Thu Sep 06, 2007 2:17 pm |
|
|
Hi,
Thanks for your help
I have tried your solution but the result is
01 01
02 02
03 03
04 04
…….
Do you know why address does not appear perhaps the FORCE_HW parameter? _________________ made by www.nopnop.fr |
|
|
|
|
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
|