(primera vez en el foro, sigo probando cómo mostrar el código)
código arduino uno, maestro I2C:
void Preparar_I2C();
volatile byte dato_envio = 0x01;
byte aux = 0x00;
#define num_0 0x40
#define num_1 0x79
#define num_2 0x24
#define num_3 0x30
#define num_4 0x19
#define num_5 0x12
#define num_6 0x02
#define num_7 0x78
#define num_8 0x00
#define num_9 0x18
void setup() {
Preparar_I2C();
pinMode(8,INPUT);
DDRD = 0xFF; //configuro puertos 0-7
PORTD = num_0; //asigno valor a esos puertos
}
void loop() {
if (digitalRead(8)==HIGH && aux==0x00 ){
TWCR = 0xE5; //START I2C
aux = 0x10;
PORTD = num_1;
}
//PORTD = TWSR >> 3;
}
ISR(TWI_vect) {
byte Estado = TWSR & 0xFC; //enmascaro
//SOLO CASO TRANSMISION DE DATOS
switch (Estado){
case 0x08: //START
TWDR = 0x1E; //cargar ADDRESS + W/R (W=0)
TWCR &= 0xDF; //Limpio START bit
PORTD = num_2;
break;
case 0x10: //REPEATED START
TWDR = 0x1E;
TWCR &= 0xDF;
PORTD = num_3;
break;
case 0x18: //SLA+W llegó
TWDR = dato_envio; //DATO A ENVIAR
PORTD = num_4;
break;
case 0x20: //SLA+W no llegó
TWCR |= 0x10; //genero STOP
PORTD = num_5;
break;
case 0x28: //Dato llegó
TWCR |= 0x10;
PORTD = num_6;
break;
case 0x30: //Dato no llegó
TWCR |= 0x10;
PORTD = num_7;
break;
case 0x38: //Arbitraje perdido SLA+W o Dato
TWCR |= 0x10;
PORTD = num_8;
break;
default:
TWCR |= 0x10;
PORTD = num_9;
break;
}
TWCR |= 0x80; //Seteo Int Flag
}
void Preparar_I2C() {
SREG |= 0x80; //Me aseguro (Ya estaba predeterminadamente)
TWCR = 0x45; //habilito I2C, ACK e INT
//SCL = 100Khz (máximo 400Khz)
TWBR = 0x48; //72
TWSR = 0x00;
}
Código pic18f4550 assember, esclavo:
list p=18f4550 ;modelo de microcontrolador
#include<p18f4550.inc> ;Libreria de modelo de registros
CONFIG FOSC = XTPLL_XT ; Oscilator + PLL enabled
CONFIG PLLDIV = 1
CONFIG CPUDIV = OSC4_PLL6 ; OSC = 16Mhz
CONFIG PWRT = ON ; Power-up Timer Enable bit (PWRT enabled)
CONFIG BOR = OFF ; Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
CONFIG WDT = OFF ; Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
CONFIG PBADEN = OFF ; PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
CONFIG LVP = OFF ; Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
CONFIG CCP2MX = ON ; CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
CONFIG MCLRE = ON ; MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
dato_leido EQU 0x60
dato_escrito1 EQU 0x61
dato_escrito2 EQU 0x62
org 0x0000 ;Vector de RESET
goto configuro
org 0x008
goto Interrupt
org 0x0020
configuro:
movlw 0x03 ;SDA y SCL como INPUT
movwf TRISB ;pin2 -> indicador de pic corriendo
bcf TRISD,0 ;muestra el dato recibido por arduino
bcf TRISD,1
movlw 0x01
movwf dato_escrito1
movlw 0x02
movwf dato_escrito2 ;revelará si D/A indica el byte actual leido o el anterior
movlw 0xC0
movwf INTCON ;General Interrupt y Peripherical
movlw 0x08
movwf PIE1 ;habilitar I2C interrupt
bcf PIR1,3 ;limpio flag
movlw 0x80
movwf SSPCON2 ;habilitar general call y SEN = 0
movlw 0x1E
movwf SSPADD ;asigno ADDRESS como esclavo
movlw 0x36
movwf SSPCON1 ;habilitar I2C y modo esclavo (sin INT en S y P)
bsf LATB,2
clrf LATD
main:
movf dato_leido,0
movwf LATD
goto main
Interrupt:
bcf LATB,2 ;indica si hubo interrupción
btfsc SSPSTAT,2 ;Chekeo R/W (R=0)
goto Estado_T
goto Estado_R
Estado_T:
btfsc SSPSTAT,5
movf dato_escrito2,0 ;si D/A=1 -> cargar dato2
btfss SSPSTAT,5
movf dato_escrito1,0 ;si D/A=0 -> cargar dato1
movwf SSPBUF
bsf SSPCON1,4 ;CKP=1 -> continuar SCL
bcf PIR1,3 ;bajar flag
retfie
Estado_R:
movf SSPBUF,0
btfsc SSPSTAT,5 ;chekeo D/A (0: anterior byte fue direccion)
movwf dato_leido ;dato recibido y guardado en registro
clrf SSPBUF ;limpiar SSPBUF y bajar flag
bcf PIR1,3
retfie
end