Como va gente?, soy begginer en el foro y con este compilador.
Lo que quiero resolver es una libreria de I2C que funcione en el C18 y que trabaje en modo ESCLAVO con interrupciones.
Hasta ahora usando un PCkit3 y el up que trae (18F45k20) logre el siguiente codigo. Tengo que seguir codificando pero la idea es que lo vean y me digan que cosas pueden mejorarse y si estoy haciendo las cosas bien.
Codigo:
#include <p18f45k20.h>
#include <i2c.h>
#define SLAVE_ADDR 0x04
#define I2CBUFF_SIZE 10
#define I2C1_Collision_Status SSPCON1bits.WCOL
#define I2C1_Buffer_Overflow SSPCON1bits.SSPOV
#define I2C1_Holds_Clock SSPCON1bits.CKP
#pragma config FOSC = INTIO67
#pragma config WDTEN = OFF, LVP = OFF, MCLRE = OFF
//---------------------------------------------------------------------
// Function Prototypes
//---------------------------------------------------------------------
char I2CBuffer[];
unsigned int I2CIndex =0;
void BeginI2C(void); //Set-up function, here start I2C config and Interrupts.
void CloseI2C(void);
void OnDataRequest(void); //Master requesting data
void OnDataReceive(void); //Master sending data
void StartTransmision(void); //Start Tx mm i think i don't need at the slave
void Send (unsigned char); //Sending data
void EndTransmision(void); //Stop Tx
int Available(void); //how many byte are in TWI buffer
int Receive(void); //Get the data at the buffer
void INTHandler(void); //Main Int Controler.
//---------------------------------------------------------------------
// Variables declaration
//---------------------------------------------------------------------
char I2C_RXBuffer[I2CBUFF_SIZE];
unsigned char I2C_RXBufferIndex, I2C_RXByteCount;
//---------------------------------------------------------------------
// INTERRUPT Declarations
//---------------------------------------------------------------------
#pragma code GralInt = 0X0008
void InterrupcionGral(void){ _asm goto INTHandler _endasm }
#pragma code I2cInt = 0X0018
void InterrupcionI2C(void){ _asm goto INTHandler _endasm }
#pragma code
//---------------------------------------------------------------------
// MAIN Interrupt Manager
//---------------------------------------------------------------------
#pragma interrupt INTHandler
void INTHandler(void){
if (I2C1_Intr_Status) { // Test if is a I2C Int.
DisableIntI2C ; //Clear SSP Interrupt
//State 1: I2C WRITE operation, last byte was an address byte
if (SSPSTATbits.S && !SSPSTATbits.D_A && !SSPSTATbits.R_W && SSPSTATbits.BF)
{
I2C_RXBufferIndex = SLAVE_ADDR;
I2C_RXByteCount = 0;
I2C_RXBuffer[I2C_RXBufferIndex] = ReadI2C();
I2C_RXBufferIndex++;
}
//State 2: I2C WRITE operation, last byte was a data byte
if (SSPSTATbits.S && SSPSTATbits.D_A && !SSPSTATbits.R_W && SSPSTATbits.BF)
{OnDataRequest();}
//State 3: I2C READ operation, last byte was an address byte
if (SSPSTATbits.S && !SSPSTATbits.D_A && SSPSTATbits.R_W)
{}
//State 4: I2C READ operation, last byte was a data byte
if (SSPSTATbits.S && SSPSTATbits.D_A && SSPSTATbits.R_W && !SSPSTATbits.BF)
{OnDataReceive();}
}EnableIntI2C1;// Re-Enable I2C Int
}
//---------------------------------------------------------------------
// I2C Primary functions
//---------------------------------------------------------------------
void BeginI2C(void){
SSPADD=SLAVE_ADDR;
OpenI2C(SLAVE_7,SLEW_OFF); // Setting I2C as slave
StartI2C(); //Start it
I2C_Clear_Intr_Status_Bit; //Clear int register
EnableIntI2C1; //Interrupt handler on
}
void StartTransmision(void){
while(SSPSTATbits.BF){}
SSPCON1bits.WCOL = 0;
}
void send (unsigned char TxChar){
WriteI2C(TxChar);}
void EndTransmision(void){
SSPCON1bits.CKP = 0;}
void OnDataRequest(void){ // This function is used for LET data to the master
StartTransmision ();
send('Hello World');
EndTransmision();
}
void OnDataReceive(void){ // This function is used for GET the data Tx from the master
if(I2C_RXBufferIndex == I2CBUFF_SIZE){I2C_RXBufferIndex = I2CBUFF_SIZE - 1;}
I2C_RXBuffer[I2C_RXBufferIndex] = ReadI2C()
}
void main (void){
BeginI2C();
while(1){}
}