|
|
View previous topic :: View next topic |
Author |
Message |
andretrilegal
Joined: 07 Jan 2012 Posts: 12
|
I2C + 18F4550 + 2 slave 16F877A + DS1307 changing date,time. |
Posted: Sat Jan 07, 2012 1:37 pm |
|
|
Hi guys!
I have a very strange problem!!!
I'm working with one 18f4550 and two slaves 16f877a and works as a charm!!!!
The master (18f4550), asks all analog port values from both, and works ok, but when I put the ds1307 everything keeps running normally, but the date, day, time, dow, keep changing all the time!!!
It's driven me nuts!!!!! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sat Jan 07, 2012 4:07 pm |
|
|
ah...do you have a battery attached to the DS1307 ? |
|
|
andretrilegal
Joined: 07 Jan 2012 Posts: 12
|
|
Posted: Sat Jan 07, 2012 8:16 pm |
|
|
Of course!!!
I've already tested the 18f4550 and ds1307 togheter and works fine!!!
I send you my code.
Master:
Code: |
#include <18F4550.h> // Definicao dos registros do Microcontrolador
#use delay(clock=48000000)
#fuses NOMCLR,HSPLL,WDT,PROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN,BROWNOUT
#use rs232(stream=PC, baud=57600, xmit=PIN_C6, rcv=PIN_C7,enable = PIN_C2, Restart_WDT, ERRORS)
#include "ds1307.c"
#include "slavea.c"
#include "241025.c"
#use i2c(MULTI_MASTER,fast=48000000,Slow,sda=PIN_C1,scl=PIN_C0,FORCE_HW)
BYTE sec;
BYTE min;
BYTE hrs;
BYTE day;
BYTE month;
BYTE yr;
BYTE dow;
//slavea
BYTE Adado0;
BYTE Adado1;
BYTE Adado2;
BYTE Adado3;
BYTE Adado4;
BYTE Adado5;
BYTE Adado6;
BYTE Adado7;
BYTE Adigital;
//DADOS SEMANAIS
BYTE C0P0dow[7]={1,2,3,4,5,6,7};
BYTE C0P0hr[12]={20,12,0,14,18,0,20,22,0,23,24,0};
BYTE EP[3];
int8 C0L[3];
int i;
int w;
#int_RTCC
void RTCC_isr(void){
output_toggle(PIN_A1);
return;
}
void main()
{
set_tris_b(0x00); // Nibble bajo salidas, el alto entradas.
output_b(0x00); // Inicializamos las salidas a 0.
set_tris_c(0b00111000); // RC0,RC1,RC2,RC6,RC7,como salidas. Las demás
set_tris_d(0x00);
output_d(0x00); // RC4,RC5, como entradas.
setup_adc_ports(AN0_TO_AN2); // Configura canales usados por el ADC.
setup_adc(ADC_CLOCK_DIV_64); // Asigna la velocidad: relog\64.
// Configuramos el ADCON2.
SETUP_TIMER_0(RTCC_INTERNAL|RTCC_DIV_64);
enable_interrupts(INT_ssp);
enable_interrupts(INT_RDA);
enable_interrupts(INT_RTCC); //ativa interrupção timer0
enable_interrupts(GLOBAL);
C0L[0]=8;
C0L[1]=0;
C0L[2]=25;
init_ext_eeprom();
for (i=0;i<3;i++)
{
WRITE_EXT_EEPROM(i,*((int8*)&C0L[i]) ) ;
}
// delay_ms(1000);
for (i=0;i<3;i++)
{
EP[i]=READ_EXT_EEPROM(i);
}
// Set date for -> 15 June 2005 Tuesday
// Set time for -> 15:20:55
ds1307_set_date_time(7,1,11,4,14,43,0);
delay_ms(1000);
while(1)
{
slave_A(Adado0,Adado1,Adado2,Adado3,Adado4,Adado5,Adado6,Adado7,Adigital);
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
delay_ms(10);
printf("\f\%02d/\%02d/\%02d \%02d\r\n",day,month,yr,dow);
printf("\%02d:\%02d:\%02d\n\r", hrs,min,sec);
printf("%U-%U-%U-%U-%U-%U-%U-%U-%U \n\r",Adado0,Adado1,Adado2,Adado3,Adado4,Adado5,Adado6,Adado7,Adigital);
}
}
|
Slave:
Code: |
#include <16F877.h>
#device adc=10
#fuses HS,NOWDT,PROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#bit SSPOV=0x14.6
#bit BF=0x94.0
#use fast_io(b)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xE0,FORCE_HW)
int32 buffer[8] = {1,12,43,44,99,34,13,15};
int32 value,value1,value2,value3,value4,value5,value6,value7;
BYTE address, dep[0x40];
int16 index;
#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;
state = i2c_isr_state();
if(state < 0x80) // Master is sending data
{
incoming = i2c_read();
if(state == 1) //First received byte is address
address = incoming;
if(state == 2) //Second received byte is data
dep[address] = incoming;
}
if(state >= 0x80) // Master is requesting data from slave
{
if (dep[address]==50)
{
i2c_write(input_b());
}
if (dep[address]==30)
{
index = state & 7; // Lower 3 bits of state = the index
i2c_write(buffer[index]);
}
}
}
//======================================
void main ()
{
setup_adc_ports( ALL_ANALOG );
SET_TRIS_B(255);
setup_adc(adc_clock_internal);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
PORT_B_PULLUPS(0b11111111);
while(1)
{
set_adc_channel(0);
delay_ms(50);
value = read_adc ();
buffer[0] = value;
set_adc_channel(1);
delay_ms(50);
value1 = read_adc ();
buffer[1] = value1;
set_adc_channel(2);
delay_ms(50);
value2 = read_adc ();
buffer[2] = value2;
set_adc_channel(3);
delay_ms(50);
value3 = read_adc ();
buffer[3] = value3;
set_adc_channel(4);
delay_ms(50);
value4 = read_adc ();
buffer[4] = value4;
set_adc_channel(5);
delay_ms(50);
value5 = read_adc ();
buffer[5] = value5;
set_adc_channel(6);
delay_ms(50);
value6 = read_adc ();
buffer[6] = value6;
set_adc_channel(7);
delay_ms(50);
value7 = read_adc ();
buffer[7] = value7;
//(value7*49+1)/100;
BF=0; //Bandera de Buffer lleno
SSPOV=0; //Overflow en el buffer
delay_ms(50);
if (buffer[0]==255 && buffer[1]==255 && buffer[2]==255 && buffer[3]==255 && buffer[4]==255 && buffer[5]==255 && buffer[6]==255 && buffer[7]==255 )
{
reset_cpu();
}
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sat Jan 07, 2012 8:39 pm |
|
|
Heck, it's usually the silly things that you get nailed on !
Like I don't see a ds1307_init(); line in main before you set the date and time ??
Or are my eyes tired...
Also I never use the set_tris_() commands... TOO easy to make an input and output, I let the compiler handle those details ... |
|
|
andretrilegal
Joined: 07 Jan 2012 Posts: 12
|
NOPE |
Posted: Sat Jan 07, 2012 9:45 pm |
|
|
Same problem here!!!
The output is:
Quote: |
20/17/32 01
08:06:60
|
and the analog datas
Quote: |
124-24-91-120-50-79-87-76-255 (here is ok) from the slave
|
I'm thinking that maybe, because the analog datas are unpredictable,
they are changing the register direct on ds1307!!!
Let me try to explain,
The slaves are sending a sequence like above, ok! then if this sequence is something like:
1. 0xD0 (Ops this is the ds1307 address)
2. 0x00 (ops he is selecting something on ds1307 strait)
3. 0x any number at all > (change the values on the ds1307!!!
But this is the 10000000000 dollars question:
How can I prevent slave to send a similar code on the bus that mistakes the ds1307 ???
I'm fckt!!!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Sun Jan 08, 2012 2:42 am |
|
|
Some comments:
Why have you got multi-master selected?. You have a master, and multiple slaves only.
"fast=48000000". Er. Much too high a speed. The DS1307, only supports 100K max. You won't be generating 48M, _but_ you will be above the frequency that the 1307 can handle.
Obvious next thing is that adding more devices on the bus, will increase the bus capacitance. You may well need smaller pull-ups. Something like 1K2.
I'd suspect the bus speed is the primary problem.
Best Wishes |
|
|
andretrilegal
Joined: 07 Jan 2012 Posts: 12
|
Ttelmah |
Posted: Sun Jan 08, 2012 8:44 am |
|
|
Thanks for yours replays guys, in fact when i run 18f4550 and ds1307 alone there is no such problem.
Even when i use stressing the bus without no delays for testing, there's no problem.
Everything works fine and i've leaved the both in a circuit testing for longer then 01 week, no problems at all.
I'm using a 1.2k pullups resistors already, and i've try to change with "slow" option either, but get the same results.
About the multi_master selected, i've try to modify this too but doesn't affect the results... same problem... again.
:( |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sun Jan 08, 2012 9:04 am |
|
|
Does it 'crash' with just one slave or do you need both to make it fail ?
Maybe test only with slave #1, then only slave #2... ?? |
|
|
andretrilegal
Joined: 07 Jan 2012 Posts: 12
|
temtronic |
Posted: Sun Jan 08, 2012 9:17 am |
|
|
doesn't matter if i put one or two slaves the results are the same.
even if i try long delays before each call
ex.
Code: |
//call all analog data + digital input from slaveA
delay_ms(500);
slave_A(Adado0,Adado1,Adado2,Adado3,Adado4,Adado5,Adado6,Adado7,
Adigital);
delay_ms(500);
//update
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
printf("\f\%02d/\%02d/\%02d \%02d\r\n",day,month,yr,dow);
printf("\%02d:\%02d:\%02d\n\r", hrs,min,sec);
//print the slaveA Values
printf("%U-%U-%U-%U-%U-%U-%U-%U-%U \n\r",Adado0,Adado1,Adado2,Adado3,Adado4,Adado5,Adado6,Adado7,Adigital);
|
With my own hardware there's no problem, the problem begins if i try to use any slave with ds1307.
But there's a catch...
If I try to ask the slave just the digital inputs everything works fine, with the master + two slaves+ eeprom+ ds1307.
The problem seems to be the analog values.... they change to fast when there's no sensor in the portA.
There's no way to prevent what kind a value is comming from!!!
If any value is like the ds1307 address, that is it game over again, they can change any value on the ds1307. And keep changing. |
|
|
andretrilegal
Joined: 07 Jan 2012 Posts: 12
|
temtronic |
Posted: Sun Jan 08, 2012 9:18 am |
|
|
the whole system never crashs, the ds1307 just keep changing values!!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Sun Jan 08, 2012 9:34 am |
|
|
Next comment.
Get rid of enabling INT_SSP on the master device. This will cause all sorts of strange behaviour.
Also INT_RDA is enabled, but no INT_RDA driver is shown. You _must_ have driver for every interrupt you enable. Otherwise you will get random jumps to odd places in the code if the interrupt triggers....
What voltage is your battery?. Have seen odd behaviour, in the past when using NiCd rechargeable batteries on the DS_1307, if the battery is slightly _high_ in voltage. It really must be below 3.5v.
Best Wishes |
|
|
andretrilegal
Joined: 07 Jan 2012 Posts: 12
|
Thanks Ttelmah |
Posted: Sun Jan 08, 2012 9:41 am |
|
|
I'm trying right now the code without INT_RDA, and about the battery, i'm using CR2032 LITHIUM 3V.
Ops.: Same problem again!
the output is:
30/10/03 04
14:17:12
//and the right analog values
20-45-165-24-65-48-12-120-255 |
|
|
andretrilegal
Joined: 07 Jan 2012 Posts: 12
|
Ttelmah |
Posted: Sun Jan 08, 2012 9:46 am |
|
|
Trying disable INT_SSP...
NOPE....
Same way!!! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sun Jan 08, 2012 10:09 am |
|
|
Well it is a head scratcher !!
Can you just ask for one ADC value from the slave?
Or what happens if you just have the slave send all zeros for the adc data? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Sun Jan 08, 2012 10:12 am |
|
|
You are using the 1307.c from the code library?.
You need to define your I2C line _before_ loading this, and remove the I2C setup from this. Have you done this?.
Same applies to 241025.c
Otherwise you have three I2C setup lines loaded.....
Best Wishes |
|
|
|
|
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
|