Hola amigos, mi proyecto es el siguiente, tengo un maestro y dos esclavos conectados por medio de I2C, un esclavo se encarga de leer unos sensores que los simulo con botones y led's, (al pulsar el botón se prende el led, así el sensor estaría "prendido") simplemente tengo que leer con el maestro y decir si están prendidos o apagados , ademas que debo leer también dos potenciometros y decir el respectivo voltaje en que están y publicar estos datos en una lcd, el otro esclavo varia con un potenciometro la velocidad de un motor dc con pwm, y desde el maestro también le puedo variar la velocidad.
En la simulación en proteus el segundo esclavo funciona a la perfección, pero al leer el buffer del primero siempre publica que están apagados los sensores así los led's estén prendidos, también al publicar el voltaje de los pot siempre me muestra el mismo valor así varié dichos potenciometros. no se si sera la interrupción en el esclavo pues solo se que se utiliza para esta comunicación.
Publico el codigo del maestro y del esclavo. Me gustaría que me ayudaran a encontrar el error, pues ya llevo dos días intentándolo y nada que funciona
--------------------maestro-----------------------
#include <16F877A.h>
#device ADC=8
#fuses HS,NOWDT,NOLVP,PUT
#use delay (clock=20000000)
#include <lcd.c>
#include <kbd_lib.c>
#use i2c (master, sda=pin_C4, scl=pin_c3)
#byte SSPCON = 0x14
void lectura(void);
void toma_adc(void);
char c;
int valor;
int a,b,e,d;
int pot1,pot2;
float cte=0.01953125, vol1,vol2;
void main(){
lcd_init();
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(all_ANALOG);
while(true){
c=kbd_getc();
toma_adc();
i2c_start();
i2c_write(0xb0); // direccion de slave
i2c_write(0x00); // posicion del buffer
i2c_write(valor); //siempre envio el dato de la conversion
i2c_stop();
delay_ms(20);
if(c==0){} //...pulsar una tecla
else if(c=='D'){ // habilita el control remoto y varia velocidad motor
lcd_putc("\fcontrol\nremoto!!");
i2c_start();
i2c_write(0xb0); // direccion de slave
i2c_write(0x01); // posicion del buffer
i2c_write(1); //bandera por la que preguntare en el esclavo
i2c_stop();
delay_ms(20);
}
else if(c=='C'){ //habilita el control local
lcd_putc("\fcontrol\nlocal!!");
i2c_start();
i2c_write(0xb0); // direccion de slave
i2c_write(0x01); // posicion del buffer
i2c_write(0); //bandera por la que preguntare en el esclavo
i2c_stop();
delay_ms(20);
}
else if(c=='B'){ //lee los sensores del esclavo
lectura();
lcd_putc("\f");
if(a==1){
lcd_gotoxy(1,1);
printf(Lcd_putc, "S1= on");
}
else{
lcd_gotoxy(1,1);
printf(Lcd_putc, "S1= off");
}
if(b==1){
lcd_gotoxy(9,1);
printf(lcd_putc, "S2= on");
}
else{
lcd_gotoxy(9,1);
printf(lcd_putc, "S2= off");
}
if(d==1){
lcd_gotoxy(1,2);
printf(lcd_putc, "S3= on");
}
else{
lcd_gotoxy(1,2);
printf(lcd_putc, "S3= off");
}
if(e==1){
lcd_gotoxy(9,2);
printf(lcd_putc, "S4= on");
}
else{
lcd_gotoxy(9,2);
printf(lcd_putc, "S4= off");
}
}
else if(c=='E'){ //lee los pot del esclavo
delay_ms(10);
i2c_start();
i2c_write(0xa0); // direccion de slave1
i2c_write(0x04);
i2c_start();
i2c_write(0xa0+1);
pot1=i2c_read(0);
i2c_stop();
delay_ms(20);
i2c_start();
i2c_write(0xa0); // direccion de slave2
i2c_write(0x05);
i2c_start();
i2c_write(0xa0+1);
pot2=i2c_read(0);
i2c_stop();
delay_ms(10);
vol1=cte*pot1; // convierto el valor de la conversion.....
vol2=cte*pot2; //.......a su correspondiente voltaje
printf(lcd_putc, "\fpot 1: %f V\npot 2: %f V",vol1,vol2);
}
}
}
void lectura(void){
//delay_ms(10);
i2c_start();
i2c_write(0xa0); // direccion de slave
i2c_write(0x00); // direccion del buffer
i2c_start();
i2c_write(0xa0+1);
a=i2c_read(0);
i2c_stop();
delay_ms(20);
i2c_start();
i2c_write(0xa0);
i2c_write(0x01); //direccion del buffer
i2c_start();
i2c_write(0xa0+1);
b=i2c_read(0);
i2c_stop();
delay_ms(20);
i2c_start();
i2c_write(0xa0);
i2c_write(0x02); //direccion del buffer
i2c_start();
i2c_write(0xa0+1);
d=i2c_read(0);
i2c_stop();
delay_ms(20);
i2c_start();
i2c_write(0xa0);
i2c_write(0x03); //direccion del buffer
i2c_start();
i2c_write(0xa0+1);
e=i2c_read(0);
i2c_stop();
delay_ms(10);
}
void toma_adc(void){
set_adc_channel(0);
delay_ms(1);
valor=read_adc();
delay_ms(1); //para que se estabilice
}
---------------esclavo sensor---------------
#include <16F877A.h>
#device ADC=8
#fuses xt,NOWDT,NOLVP,PUT
#use delay (clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0)
#byte SSPCON = 0x14
void toma_adc0(void);
void toma_adc1(void);
typedef enum {NOTHING, CONTROL_READ,ADDRESS_READ, READ_COMMAND_READ} I2C_STATE;
int con1, con2;
I2C_STATE fState;
BYTE address, buffer[0x06], recibe;
#INT_SSP
void ssp_interupt (){
if (i2c_poll() == FALSE) {
if (fState == ADDRESS_READ) { //i2c_poll() returns false on the
i2c_write (buffer[address]);//interupt receiving the second
fState = NOTHING; //command byte for random read operation
}
}
else {
recibe = i2c_read(0);
if (fState == NOTHING){
fState = CONTROL_READ;
}
else if (fState == CONTROL_READ) {
address = recibe;
fState = ADDRESS_READ;
}
else if (fState == ADDRESS_READ) {
buffer[address] = recibe;
fState = NOTHING;
}
}
}
void main (){
fState = NOTHING;
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(all_ANALOG);
while(true){
if (input(pin_D4)==1){ //pregunto por los botones
output_high(pin_B0);
buffer[0x00]=1;
}
else {
output_low(pin_B0);
buffer[0x00]=0;
}
if (input(pin_D5)==1){
output_high(pin_B1);
buffer[0x01]=1;
}
else {
output_low(pin_B1);
buffer[0x01]=0;
}
if (input(pin_D6)==1){
output_high(pin_B2);
buffer[0x02]=1;
}
else {
output_low(pin_B2);
buffer[0x02]=0;
}
if (input(pin_D7)==1){
output_high(pin_B3);
buffer[0x03]=1;
}
else {
output_low(pin_B3);
buffer[0x03]=0;
}
if (bit_test(SSPCON,6)){
bit_clear (SSPCON,6);
recibe = i2c_read(0);
}
toma_adc0();
buffer[0x04]=con1;
toma_adc1();
buffer[0x05]=con2;
}
}
void toma_adc0(void){
set_adc_channel(0);
delay_ms(1);
con1=read_adc();
delay_ms(1); //para que se estabilice
}
void toma_adc1(void){
set_adc_channel(1);
delay_ms(1);
con2=read_adc();
delay_ms(1); //para que se estabilice
}
---------------esclavo motor--------------------
#include <16f877a.h>
#device ADC=8
#fuses XT,NOWDT,NOLVP,PUT
#use delay (clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xb0)
#byte SSPCON = 0x14
void toma_adc(void);
typedef enum {NOTHING, CONTROL_READ,ADDRESS_READ, READ_COMMAND_READ} I2C_STATE;
byte valor0,valor1;
I2C_STATE fState;
BYTE address, buffer[0x02],recibe,flag;
#INT_SSP
void ssp_interupt (){
if (i2c_poll() == FALSE) {
if (fState == ADDRESS_READ) { //i2c_poll() returns false on the
i2c_write (buffer[address]);//interupt receiving the second
fState = NOTHING; //command byte for random read operation
}
}
else {
recibe = i2c_read(0);
if (fState == NOTHING){
fState = CONTROL_READ;
}
else if (fState == CONTROL_READ) {
address = recibe;
fState = ADDRESS_READ;
}
else if (fState == ADDRESS_READ) {
buffer[address] = recibe;
fState = NOTHING;
}
}
}
void main (){
fState = NOTHING;
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
setup_adc_ports(all_ANALOG); //entrada 0 como analogica
setup_adc(ADC_CLOCK_INTERNAL); //configura el conversor
setup_ccp1(ccp_pwm);
setup_timer_2(t2_div_by_1,255,1);
set_pwm1_duty(0);
while(true){
if (bit_test(SSPCON,6)){
bit_clear (SSPCON,6);
recibe = i2c_read();
}
toma_adc();
valor1=buffer[0x00];
flag=buffer[0x01];
if(flag==0){
set_pwm1_duty(valor0);
output_high(pin_B0);
output_low(pin_B1);
}
else if(flag==1){
set_pwm1_duty(valor1);
output_high(pin_B1);
output_low(pin_B0);
}
}
}
void toma_adc(void){
set_adc_channel(0);
delay_ms(1);
valor0=read_adc();
delay_ms(1); //para que se estabilice
}
pido disculpas por las molestias causadas y por el post tan largo
pero en verdad necesito ayuda!!!!
Gracias