#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
// CONFIG1
#pragma config "FOSC = INTRC_NOCLKOUT" // Oscillator Selection bits (INTRC_NOCLKOUT oscillator: Internal Oscillator with No Clock Output on Pins)
#pragma config "WDTE = OFF" // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config "PWRTE = OFF" // Power-up Timer Enable bit (PWRT disabled)
#pragma config "MCLRE = ON" // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config "CP = OFF" // Code Protection bit (Program memory code protection is disabled)
#pragma config "CPD = OFF" // Data Code Protection bit (Data memory code protection is disabled)
#pragma config "BOREN = ON" // Brown Out Reset Selection bits (BOR disabled)
#pragma config "IESO = OFF" // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config "FCMEN = OFF" // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config "LVP = OFF" // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config "BOR4V = BOR40V" // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config "WRT = OFF" // Flash Program Memory Self Write Enable bits (Write protection off)
#define _XTAL_FREQ 8000000
#define baud_rate 9600
unsigned char datain;
unsigned char rxbuffer[20];
unsigned char txbuffer[20];
unsigned char rxbufferindex =0,txbufferindex=0;
unsigned char rxbufferlen=1,txbufferlen=1;
unsigned char read_count=0,datain=0,write_data=0;
//Delay functions
void delay_us(unsigned int);
void delay_ms(unsigned int);
void delay1ms(void);
char UART_Init(long);
void UART_Write(unsigned char);
char UART_TX_Empty(void);
void UART_Write_Text(const char *);
char UART_Data_Ready(void);
char UART_Read(void);
unsigned char * UART_Read_Text(void);
unsigned char getch(void);
unsigned char getche(void);
void I2C_init(void);
void I2C_slave(void);
void I2C_write(void);
void I2C_read(void);
void I2C_exit(void);
void main()
{
const char *msg1="/r/nWaiting for Data from Master";
const char *t1="/r/nWaiting for Data from Masterhdhhd";
OSCCONbits.IRCF = 0x07; // Configure Internal OSC for 8MHz Clock
while(!OSCCONbits.HTS); // Wait Until Internal Osc is Stable
UART_Init(baud_rate);
delay_ms(500);
UART_Write_Text(msg1);
I2C_init();
while(1)
{
if(PIR1bits.SSPIF == 0)
{
UART_Write_Text(t1);
I2C_slave();
}
SSPCONbits.SSPOV =0;
SSPCONbits.WCOL = 0;
write_data = 0;
}
}
void I2C_init()
{
TRISCbits.TRISC3 = 1; //direction register SCL as input pin
TRISCbits.TRISC4 = 1; //direction register SDA as input pin
SSPADD = 0X01; //your device address
SSPCON = 0X36; //SSPEN =1 and set i2c to slave mode with 7 bit address
SSPSTAT =0;
PIE1bits.SSPIE = 1;
PIR1bits.SSPIF = 0;
rxbufferindex = 0;
txbufferindex = 0;
}
void I2C_slave()
{
const char *msg2="/r/nchecking for appropriate flag";
const char *msg3="/r/nwriting text receive from master";
const char *msg4="/r/nmaster is reading from slave";
const char *msg5="/r/nbuffer full";
UART_Write_Text(msg2);
SSPIF =1;
if(SSPSTATbits.R_W == 1)
{
UART_Write_Text(msg4);
I2C_read();
}
if(SSPSTATbits.BF == 1)
{
UART_Write_Text(msg5);
I2C_exit();
}
if(SSPSTATbits.D_A == 1)
{
UART_Write_Text(msg3);
I2C_write();
}
if(SSPBUF != 0x01)
{
I2C_exit();
}
read_count = 0;
I2C_exit();
}
void I2C_exit()
{
return;
}
//Delay routines
void delay_us(unsigned int i)
{
for (;i!=0x00;i--);
}
void delay_ms(unsigned int i)
{
for(;i!=0x00;i--)
delay1ms();
}
void delay1ms(void)
{
unsigned int j = 130;
for (;j!=0x00;j--);
}
void I2C_write()
{
datain = SSPBUF;
UART_Write(datain);
rxbuffer[rxbufferindex] = datain;
rxbufferindex = rxbufferindex +1;
if(rxbufferindex == rxbufferlen)
{
write_data = 1;
rxbufferindex = 0;
}
I2C_exit();
}
void I2C_read()
{
if(SSPSTATbits.D_A == 0)
{
txbufferindex = 0;
}
while(SSPSTATbits.BF)
{
while(SSPCONbits.WCOL)
{
SSPCONbits.WCOL = 0;
SSPBUF = txbuffer[txbufferindex];
}
SSPCONbits.CKP = 1;
txbufferindex = txbufferindex + 1;
if(txbufferindex = txbufferlen)
{
txbufferindex = 0;
}
}
I2C_exit();
}
char UART_Init(long baudrate)
{
unsigned int x;
x = (_XTAL_FREQ - baudrate*64)/(baudrate*64); //SPBRG for Low Baud Rate
if(x>255) //If High Baud Rate required
{
x = (_XTAL_FREQ - baudrate*16)/(baudrate*16); //SPBRG for High Baud Rate
BRGH = 1; //Setting High Baud Rate
SPBRG = x; //Writing SPBRG register
SYNC = 0; //Selecting Asynchronous Mode
SPEN = 1; //Enables Serial Port
// TRISC7 = 1; //Not Needed Or Recommended
// TRISC6 = 1; //Not Needed Or Recommended
CREN = 1; //Enables Continuous Reception
TXEN = 1; //Enables Transmission
}
if(x<256)
{
BRGH = 0; //Setting High Baud Rate
SPBRG = x; //Writing SPBRG register
SYNC = 0; //Selecting Asynchronous Mode
SPEN = 1; //Enables Serial Port
// TRISC7 = 1; //Not Needed Or Recommended
// TRISC6 = 1; //Not Needed Or Recommended
CREN = 1; //Enables Continuous Reception
TXEN = 1; //Enables Transmission
return 1;
}
return 0;
}
void UART_Write(unsigned char data)
{
while(!PIR1bits.TXIF);
while(!TRMT); //Waiting for Previous Data to Transmit completly
TXREG = data; //Writing data to Transmit Register, Starts transmission
}
char UART_TX_Empty()
{
return TRMT; //Returns Transmit Shift Status bit
}
void UART_Write_Text(const char *text)
{
int i;
for(i=0;text[i]!='\0';i++)
UART_Write(text[i]);
}
//recive part
char UART_Data_Ready()
{
return RCIF;
}
char UART_Read()
{
while(!RCIF); //Waits for Reception to complete
return RCREG; //Returns the 8 bit data
}
unsigned char * UART_Read_Text()
{
unsigned const char *a="Keyed in \r\n";
unsigned static char string[20];
unsigned char x, i = 0;
//receive the characters until ENTER is pressed (ASCII for ENTER = 13)
while((x = UART_Read()) != 13)
{
//and store the received characters into the array string[] one-by-one
string[i++] = x;
}
//insert NULL to terminate the string
string[i] = '\0';
UART_Write_Text(a);
//return the received string
return(string);
}
void putch(unsigned char byte)
{
/* output one byte */
while(!TXIF) /* set when register is empty */
continue;
TXREG = byte;
}
unsigned char getch()
{
/* retrieve one byte */
while(!RCIF) /* set when register is not empty */
continue;
return RCREG;
}
unsigned char getche(void)
{
unsigned char c;
putch(c = getch());
return c;
}