fbpx

Expresate

Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:

PIC 16F876A i2c (ma...
 
Avisos
Vaciar todo

PIC 16F876A i2c (maestro y esclavo en el mismo PIC)

7 Respuestas
3 Usuarios
0 Reactions
3,589 Visitas
xyvy
Respuestas: 50
 XyVy
Topic starter
(@xyvy)
Trusted Member
Registrado: hace 16 años

Hola chicos, estoy usando un PIC 16F876A para realizar comunicaciones como esclavo de un PC usando i2c, y todo funciona correctamente.

Por otro lado tengo otro pequeño programa que usa un PIC 16F876A como maestro para comunicarse con una controladora de motores la MD22 y todo va bien, mediante un interruptor, arranco y paro un motor a mi voluntad.

Ahora estoy intentado juntar todo eso, aprovechando el i2c por hardware para el modo esclavo del PIC contra el PC (maestro), y usando otras dos patillas para simular por software i2c como maestro para comunicarme con la controladora MD22 (esclavo).

Bueno el programa surge nada más poner el #use i2c(MASTER, ....) a partir de ese momento la parte del esclavo deja de funcionar.

Os pongo el programa completo y me decías porqué, aparece con comentarios las funciones del maestro, porque solo con poner el #use i2c(Master...) deja de funcionar el circuito.

#include <16F876A>

#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected

#use delay(clock=4000000)

#byte port_b=0x06

//#use i2c(MASTER, FAST, sda=PIN_A0, scl=PIN_A1, address=0xB0, force_sw, stream=i2cM)
#use i2c(SLAVE, FAST, sda=PIN_C4, scl=PIN_C3, address = 0x08, force_hw, stream = i2cS)

// Comandos soportados por el PIC 16F876 en nuestro software
#define INIT 0x01
#define CONSULTA_MOTOR1 0x02
#define CONSULTA_MOTOR2 0x03
#define MUEVE_MOTOR1 0x04
#define MUEVE_MOTOR2 0x05
#define INTERRUPTOR1 0x06
#define INTERRUPTOR2 0x07
#define INTERRUPTOR3 0x08
#define INTERRUPTOR4 0x09
#define STOP_MOTOR1 0x0A
#define STOP_MOTOR2 0x0B

// definimos los datos para usar i2c
char data;
char cuenta;
BYTE state;
BYTE comando;
BYTE dato;

/*
void inicializa()
{
output_high(PIN_B2);
i2c_start(i2cM);
i2c_write(i2cM, 0xB0); // Dirección del dispositivo
i2c_write(i2cM, 0x00); // Registro de Modo
i2c_write(i2cM, 0x01); // Motor1 detenido
i2c_stop(i2cM);
output_low(PIN_B2);
}

void MueveMotor1(char dato)
{
output_high(PIN_B2);
i2c_start(i2cM);
i2c_write(i2cM, 0xB0); // Dirección del dispositivo
i2c_write(i2cM, 0x01); // Registro de modo
i2c_write(i2cM, dato); // Registro Velocidad motor 1
i2c_stop(i2cM);
output_low(PIN_B2);
}

void MueveMotor2(char dato)
{
output_high(PIN_B2);
i2c_start(i2cM);
i2c_write(i2cM, 0xB0); // Dirección del dispositivo
i2c_write(i2cM, 0x02); // Velocidad de los motores
i2c_write(i2cM, dato); // Velocidad del motor2
i2c_stop(i2cM);
output_low(PIN_B2);
}

void StopMotor1()
{
output_high(PIN_B2);
i2c_start(i2cM);
i2c_write(i2cM, 0xB0); // Dirección del dispositivo
i2c_write(i2cM, 0x01); // Registro de Modo
i2c_write(i2cM, 128);
i2c_stop(i2cM);
output_low(PIN_B2);
}

void StopMotor2()
{
output_high(PIN_B2);
i2c_start(i2cM);
i2c_write(i2cM, 0xB0); // Dirección del dispositivo
i2c_write(i2cM, 0x02); // Velocidad de los motores
i2c_write(i2cM, 128); // velocidad del motor1
i2c_stop(i2cM);
output_low(PIN_B2);
}

*/

#INT_SSP
void ssp_interupt ()
{
state = i2c_isr_state();

if(state<0x80) //master is sending data
{
if(state == 0)
{

} else if (state == 1) //first received byte
{
output_high(PIN_B2);
comando = i2c_read(i2cS);
} if (state==2) { // 2º byte recibido
dato=i2c_read(i2cS);
}
}else if (state == 0x80) { //master is requesting data
output_high(PIN_B1);
if (input(PIN_B4)) {
i2c_write(i2cS, 1);
} else {
i2c_write(i2cS, 0);
}
i2c_write(i2cS, cuenta); //send requested data
cuenta++;
}
}

void main()
{
char data;
int pulsado=0;
char sw=0;
int activo;
cuenta=0;
port_b=0;

enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

sw=0;
pulsado=0;
while (1) {
/*
activo=input(PIN_B4);
if (activo && (sw==0) && (!pulsado)) {
output_low(PIN_B2);
MueveMotor1(255);
StopMotor2();
pulsado=1;
sw=1;
} else if (activo && (sw==1) && (!pulsado)) {
output_high(PIN_B2);
MueveMotor2(255);
StopMotor1();
pulsado=1;
sw=0;
}

delay_ms(50);
if (!input(PIN_B4)) {
output_low(PIN_B2);
pulsado=0;
}
delay_ms(50); */
}

}

Se acepta cualquier sugerencia, porque por más que le doy vueltas no encuentro la solución.

Gracias de antemano.

Responder
6 respuestas
dragonet80
Respuestas: 1328
(@dragonet80)
Ardero
Registrado: hace 17 años

XyVy, es bastante posible que el CCS no te admita las dos opciones en un mismo PIC. O que ese PIC no tenga opción de multimaster (un bus donde funcionan varios masters). Ahora mismo no sabría decirte, pero quizá te interesaría usar un sólo master (el del PIC seguramente, ya que es el que controlará al MD22) y los demás en modo esclavo.

Responder
xyvy
Respuestas: 50
 XyVy
Topic starter
(@xyvy)
Trusted Member
Registrado: hace 16 años

Quizás no me expliqué correcatmente del todo, el PIC tiene que funcionar en sobre un bus i2c como maestro del MD22 (que hace de esclavo) y sobre otro bus i2c distinto como esclavo de otro dispositivo (el PC como maestro). En principio no hay multimaster. Uso las patillas C3 y C4 (creo recordar) para el PIC en modo esclavo por hardware, y las patillas A0 y A1 para hacer de modo master por software, pero repito sobre buses i2c independientes.

Entiendo que puede ser complicado, he leido un post acerca del tema en el foro de CCS y también posteé allí pero aún nadie ha contestado.

Gracias de todos modos por tu tiempo, crees que puede ser alguna otra cosa?

Ciao y gracias.

Responder
dragonet80
Respuestas: 1328
(@dragonet80)
Ardero
Registrado: hace 17 años

Espérate a ver si te contestan en el foro de CCS o a ver si alguien de por aquí lo ha probado. Yo nunca había probado esto de tener dos buses simultáneos, así que no puedo ayudarte más, ya que las sentencias parecen bien definidas.

Responder
Lorth
Respuestas: 188
(@lorth)
Estimable Member
Registrado: hace 17 años

Yo con i2c, tube problemas al hacerlo por SW por problemas con los tiempos entre tramas, el esclavo no podia seguirlo, lo sulucione con esperas.

¿Porque fuerzas el puerto a low cuando acabas la transmision con el MD22 ese?

Responder
Página 1 / 2
Compartir: