my single pic i2c master and 5 slaves are working fine.
http://youtu.be/SEOJJxSO-wU
PIC 2 PIC Master/Slave Communication using I2C... Enjoy
-
- Posts: 69
- Joined: 28 Jan 2012 06:50
- Location: Pakistan
- Contact:
Re: PIC 2 PIC Master/Slave Communication using I2C... Enjoy
programmer5 wrote:my single pic i2c master and 5 slaves are working fine.
http://youtu.be/SEOJJxSO-wU
Could you please share the code..?
Regards.
Vishal
http://microcontrollerprojects00.blogspot.com/
ARM, PIC , AVR, 8051 Projects/Tutorials (MikroC)
If you get, give. If you learn, teach.
ARM, PIC , AVR, 8051 Projects/Tutorials (MikroC)
If you get, give. If you learn, teach.
Re: PIC 2 PIC Master/Slave Communication using I2C... Enjoy
Hello!
I'm also trying to use I2C master-slave comm between two PIC16F1823 microcontrollers, but i never get interrupt. Can you please check my codes, and help me out?
Thanks a lot!
The Slave is:
The I2C lines are pulled up with 10k resistors. I have no idea...
I'm also trying to use I2C master-slave comm between two PIC16F1823 microcontrollers, but i never get interrupt. Can you please check my codes, and help me out?
Thanks a lot!
Code: Select all
/***********************
*TÁJÉKOZÓDÁSI STRATÉGIA*
* ÉS IRÁNYÍTÓ ESZKÖZ *
* FEJLESZTÉSE *
*LÁTÁSSÉRÜLTEK SZÁMÁRA *
* PIC16f1823 @ 32MHz *
* 2013 Erdélyi Viktor *
* MASTER *
***********************/
// Slave address
const Slave = 0x69;
// 8 bit variables
typedef unsigned char uint8;
// flags
bit oldstate;
bit echoold;
// Variables
uint8 Dist1; //Distance and azimuth variables
uint8 Pot1;
uint8 Pot2;
uint8 Dist2;
uint8 Pitch;
// denominate I/O bits
sbit Echo at RC2_bit;
sbit Echo_d at TRISC2_bit;
sbit Trig at RA2_bit;
sbit Trig_d at TRISA2_bit;
void Tone1() {
Sound_Play(500, 20); // Frequency = 659Hz, duration = 1000ms
//Sound_Play(Pitch, 20); // Uncomment to modulate pitch
}
void hardinit(void) {
ANSELA = 0; // Configure AN pins as digital
ANSELC = 0;
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
APFCON = 0b10000100;
Echo_d = 1; // Init I/O ports
Trig_d = 0;
Trig = 0;
UART1_Init(9600); // Initialize UART module at 9600 bps
Delay_ms(100); // Wait for UART module to stabilize
Sound_Init(&PORTC, 4); // Init sound
PWM1_Init(25000); // Initialize PWM1 module at 25KHz
PWM1_Start(); // Start PWM1
oldstate = 0; // Init flags
echoold = 0;
Dist1 = 0; // Initialize variables
Dist2 = 250;
Pot1 = 0;
Pot2 = 0;
Pitch = 400;
}
void send(unsigned short send_data){ // Sub for triggering slave
I2C1_Init(100000);
I2C1_Start();
I2C1_Wr(Slave);
I2C1_Wr(0xFF);
I2C1_Stop();
}
unsigned short read(){ // Sub for data request
unsigned short read_data;
I2C1_Init(100000);
I2C1_Start();
I2C1_Wr(Slave + 1);
Dist2 = I2C1_Rd(0);
Pot1 = I2C1_Rd(0);
Pot2 = I2C1_Rd(0);
delay_ms(100);
I2C1_Stop();
return read_data;
}
void distM(void) { // Subroitune for distance measuring
Dist2 = 255;
echoold = 0;
oldstate = 0;
Trig = 1;
oldstate = 1;
delay_us(11);
Trig = 0;
if (oldstate == 1){
while (echoold == 0){
if (Echo == 1){
echoold = 1;
while (Echo == 1) {
delay_us(100); // 17 mm precision
Dist2 --;
//Pitch = Dist2*5+400; // +17 mm => +5 Hz (uncomment to modulate Pitch)
}
}
}
}
}
void main() {
hardinit();
while(1) {
send; // Send trigger to slave
distM(); // Measuring distance
PWM1_Set_Duty(dist2); // Set volume
Tone1();
//read; // Request data from slave
//UART1_Write(Dist1); // Data transmission to PC
UART1_Write(Dist2);
//UART1_Write(Pot1);
//UART1_Write(Pot2);
}
}
Code: Select all
/***********************
*TÁJÉKOZÓDÁSI STRATÉGIA*
* ÉS IRÁNYÍTÓ ESZKÖZ *
* FEJLESZTÉSE *
*LÁTÁSSÉRÜLTEK SZÁMÁRA *
* PIC16f1823 @ 32MHz *
* 2013 Erdélyi Viktor *
* SLAVE *
***********************/
// Set I2C parameters
const Slave = 0x69; // Set I2C device address
const Delay_Time = 250; // Port check delay
unsigned short j; // just dummy for buffer read
unsigned short rxbuffer;
unsigned short tx_data;
// 8 bit variables
typedef unsigned char uint8;
typedef unsigned int uint16;
// flags
bit oldstate;
bit echoold;
// Variables
uint8 Dist1; //Distance and azimuth variables
uint8 Pot1;
uint8 Pot2;
uint8 Pitch;
uint16 ADC0;
uint16 ADC1;
// denominate I/O bits
sbit Echo at RC2_bit;
sbit Echo_d at TRISC2_bit;
sbit Trig at RA2_bit;
sbit Trig_d at TRISA2_bit;
sbit LED at RC3_bit;
sbit LED_d at TRISC3_bit;
void Tone1() {
Sound_Play(500, 20); // Frequency = 500Hz, duration = 20ms
//Sound_Play(Pitch, 20); // Uncomment to modulate pitch
}
void hardinit(void) {
ANSELA = 0b00000011; // Configure AN pins as digital, expect AN0 and AN1
ANSELC = 0;
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
SSPCON = 0x36; // Set to I2C slave with 7-bit address
PIE1.SSP1IF = 1; // enable SSP interrupts
SSPADD = Slave;
INTCON = 0xC0; // enable INTCON.GIE
APFCON = 0b10000100;
Echo_d = 1; // Init I/O ports
Trig_d = 0;
Trig = 0;
Sound_Init(&PORTC, 4); // Init sound
PWM1_Init(25000); // Initialize PWM1 module at 25KHz
PWM1_Start(); // Start PWM1
ADC_Init(); // ADC init
oldstate = 0; // Init flags
echoold = 0;
Dist1 = 0; // Initialize variables
Pot1 = 0;
Pot2 = 0;
Pitch = 400;
LED_d = 0;
LED = 0;
}
void interrupt(){ // I2C slave interrupt handler
if (PIR1.SSP1IF == 1){ // I2C Interrupt
PIR1.SSP1IF = 0; // reset SSP interrupt flag
LED=1; // Just to see interrupt
//transmit data to master
if (SSPSTAT.b2 == 1){ // Read request from master
SSPBUF = tx_data; // Get data to send
SSPCON.CKP = 1; // Release SCL line
j = SSPBUF; // That's it
return;
}
if (SSPSTAT.BF == 0){ // all done,
j = SSPBUF; // Nothing in buffer so exit
return;
}
//recieve data from master
if (SSPSTAT.b5 == 1){ // Data [not address]
rxbuffer = SSPBUF; // get data
j = SSPBUF; // read buffer to clear flag [address]
return;
}
}
j = SSPBUF; // read buffer to clear flag [address]
}
void adcread(void){ // Reading ADC values, converting into 8 bit format
ADC0 = ADC_Read(0); // reading 10-bit value from ADC
ADC1= ADC_Read(1);
Pot1 = ADC0 >> 2; // writeing significant 8 bit to variable
Pot2 = ADC1 >> 2;
}
void distM(void) { // Subroitune for distance measuring
Dist1 = 255;
echoold = 0;
oldstate = 0;
Trig = 1;
oldstate = 1;
delay_us(11);
Trig = 0;
if (oldstate == 1){
while (echoold == 0){
if (Echo == 1){
echoold = 1;
while (Echo == 1) {
delay_us(100); // 17 mm precision
Dist1 --;
//Pitch = Dist2*5+400; // +17 mm => +5 Hz (uncomment to modulate Pitch)
}
}
}
}
}
void main() {
hardinit();
while(1) {
if (rxbuffer == 0xFF){
adcread(); // Reading ADC channels
distM(); // Measuring distance
PWM1_Set_Duty(Dist1); // Set volume
Tone1(); // Play Tone
}
}
}
-
- Posts: 1
- Joined: 20 Jan 2014 22:56
Re: PIC 2 PIC Master/Slave Communication using I2C.
Hi everyone... well I do some changes for the MASTER and SLAVE codes, and it works very well in my simulations and in my PROTOBOARD. For de master I used a PIC18F4550 and for the slave I used a PIC 16F877A. I hope this can help to all of you.
Here is te MASTER CODE:
And here is the SLAVE CODE:
Here is the link for the simulations and codes.
https://www.dropbox.com/s/if8kfvh84wgoe ... 0Slave.rar
Here is te MASTER CODE:
Code: Select all
//1.============================================================================
// PRÁCTICA: Comunicación I2C Master_Slave.c
// AUTORES: Francisco Ortiz O.
// FECHA: 02-Mayo-2014
// DESCRIPCIÓN: El siguiente programa realiza la comunicación I2C entre dos
// microcontroladores. Esta parte del código configura al micro_
// controlador PIC18F4550 como MAESTRO, el cual se comunicará con
// un microcontrolador PIC16F877A que se encuentra configurado
// como ESCLAVO. Enviamos el estado de un potenciómetro conectado
// en el canal analógico A0 del MAESTRO, y al presionar el pul_
// sante conectado en RA1 enviado las letras "UPS" secuencialmente.
//==============================================================================
//2. ARCHIVOS DE CABECERA
//==============================================================================
// 3.===========================================================================
// DECLARACIÓN DE VARIABLES GLOBALES.
//==============================================================================
unsigned int lectura;
// 4.===========================================================================
// DECLARACIÓN DE PROTOTIPOS DE PROCEDIMIENTOS Y FUNCIONES.
//==============================================================================
void escribir_Pic(unsigned int address,
unsigned int send_data); // Escribe al ESCLAVO
unsigned short leer_Pic(); // Lee datos del ESCLAVO
void Init_Perifericos(); //Iniciliza el PIC
// 5.===========================================================================
// DEFINICIÓN DE PROCEDIMIENTOS Y FUNCIONES DE LAS INTERRUPCIONES.
//==============================================================================
// 6.===========================================================================
// DEFINICIÓN DEL PROCEDIMIENTO DE ATENCIÓN A LAS INTERRUPCIONES.
//==============================================================================
// 7.===========================================================================
// DEFINICIÓN DE PROCEDIMIENTOS Y FUNCIONES DEL PROGRAMA PRINCIPAL.
//==============================================================================
void escribir_Pic(unsigned int address, unsigned int send_data){
I2C1_Start(); //Inicia Bus I2C
I2C1_Wr(0xB0); //Envía dirección del ESCLAVO (dirección + W)
I2C1_Wr(address); //Envía dirección de almacenamiento en el ESCLAVO
I2C1_Wr(send_data); //Envía el dato a escribir en el ESCLAVO
I2C1_Stop(); //Detiene Bus I2C
delay_ms(50);
}
unsigned short leer_Pic(){
unsigned short read_data;
I2C1_Start(); //Inicia Bus I2C
I2C1_Wr(0xB1); //Envía dirección del ESCLAVO (dirección + R)
read_data = I2C1_Rd(0);
delay_ms(100);
I2C1_Stop(); //Detiene Bus I2C
return read_data;
}
void Init_Perifericos(){
ADCON1 = 0x0E; // RA0 como entrada analógica, RA1-RA6 Digitales
CMCON = 0b00000111; // Deshabilita comparadores
INTCON2 = 0x80; // Deshabilita pull up en el puerto B
// clears internal latches
LATA = 0xFF;
LATC = 0x00;
LATD = 0x00;
LATE = 0x00;
TRISA = 0xFF;
TRISB = 0x00;
TRISC = 0x00;
TRISD = 0x00;
TRISE = 0x00;
}
// 8.===========================================================================
// DEFINICIÓN DEL PROGRAMA PRINCIPAL.
//==============================================================================
void main(){
bit oldstate,oldstate1;
Init_Perifericos();
ADC_Init();
I2C1_Init(100000); //Inicializar Bus I2C a 100kHz
delay_ms(500);
while (1){
lectura = ADC_Read(0)/4; //Obtener una lectura de 8bits
escribir_Pic(4,lectura); //Escribimos al ESCLAVO
if (Button(&PORTA, 1, 1, 1)) { // Detect logical one
oldstate = 1; // Update flag
}
if (oldstate && Button(&PORTA, 1, 1, 0)) { // Detect one-to-zero transition
escribir_Pic(1,0x55); //Escribimos una "U" al esclavo
delay_ms(20);
escribir_Pic(2,0x50); //Escribimos una "P" al esclavo
delay_ms(20);
escribir_Pic(3,0x53); //Escribimos una "S" al esclavo
oldstate = 0; // Update flag
}
}
}
Code: Select all
//1.============================================================================
// PRÁCTICA: Comunicación I2C Master_Slave.c
// AUTORES: Francisco Ortiz O.
// FECHA: 02-Mayo-2014
// DESCRIPCIÓN: Este código se encarga de configurar al
// microcontrolador PIC16F877A como esclavo para que atienda las
// interrupciones generadas por el maestro; que es un microcon_
// trolador PIC18F4550 y atiende solo a la dirección 0xB0.
// Realizamos la lectura del estado de un potenciómetro conectado
// en el maestro y mostramos los datos en un LCD 2x16.
//==============================================================================
//2. ARCHIVOS DE CABECERA
//==============================================================================
sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// 3.===========================================================================
// DECLARACIÓN DE VARIABLES GLOBALES.
//==============================================================================
unsigned char rxbuffer,address,buff,dato, direccion;
unsigned short tx_data;
int a=0;
// 4.===========================================================================
// DECLARACIÓN DE PROTOTIPOS DE PROCEDIMIENTOS Y FUNCIONES.
//==============================================================================
void initPerifericos();
unsigned short BcdToShort( unsigned short bcd );
unsigned short ShortToBcd( unsigned short valor);
// 5.===========================================================================
// DEFINICIÓN DE PROCEDIMIENTOS Y FUNCIONES DE LAS INTERRUPCIONES.
//==============================================================================
// 6.===========================================================================
// DEFINICIÓN DEL PROCEDIMIENTO DE ATENCIÓN A LAS INTERRUPCIONES.
//==============================================================================
void interrupt(){
if (PIR1.SSPIF){ //Comprueba si la interrupción es por I2C
PIR1.SSPIF = 0; //Apagamos la bandera SSP
if(!SSPSTAT.R_W & SSPSTAT.D_A & SSPSTAT.BF ){
a++;
PORTB=2;
if (a==1){
address=SSPBUF; //Guardamos la dirección de almacenamiento
} //del dato recibido.
if (a==2){
rxbuffer=SSPBUF; //Guardamos el dato recibido
a=0;
}
PIR1.SSPIF = 0; //Apagamos la bandera SSP
}
if( !SSPSTAT.R_W & !SSPSTAT.D_A & SSPSTAT.BF ){
buff = SSPBUF;
PIR1.SSPIF = 0;
}
}
}
// 7.===========================================================================
// DEFINICIÓN DE PROCEDIMIENTOS Y FUNCIONES DEL PROGRAMA PRINCIPAL.
//==============================================================================
void initPerifericos(){
ADCON1 = 7; // Todos los puertos como digitales
CMCON = 0b00000111; // Deshabilita comparadores
TRISA = 0; // Set PORTA as output
TRISB = 0; // Set PORTB as output
//TRISC = 0b00011000; // Set SCL y SDA como ingresos
TRISC.B3 = 1; // Set SCL (PORTC,3) pin como ingreso
TRISC.B4 = 1; // Set SDA (PORTC,4) pin como ingreso
PortB=0;
//Configuracion de interrupciones
INTCON = 0b00000000;
SSPCON = 0b00111110; // Modo esclavo 7 bits de direccion.
SSPCON2 = 0x00;
SSPADD = 0xB0; //Dirección del dispositivo
SSPSTAT=0x00;
SSPCON.SSPEN = 1;
SSPSTAT.SMP = 1;
SSPSTAT.CKE = 1;
PIR1.SSPIF = 0;
PIR2.BCLIF=0;
PIE1.SSPIE = 1; // Habilita la interrupcion del modulo SSP
INTCON.PEIE = 1; // Habilita las interrupciones de los perifericos
INTCON.GIE = 1; // Habilita las interrupciones globales!
}
unsigned short BcdToShort( unsigned short bcd ){
unsigned short LV, HV;
LV = bcd&0x0F;
HV = (bcd>>4)&0x0F;
return LV + HV*10;
}
unsigned short ShortToBcd( unsigned short valor){
unsigned short HV, LV;
HV = valor/10;
LV = valor - HV*10;
return LV + HV*16;
}
// 8.===========================================================================
// DEFINICIÓN DEL PROGRAMA PRINCIPAL.
//==============================================================================
void main(){
char as[6];
initPerifericos();
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD display
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
lcd_Out(1,1,"SLAVE");
while (1){
if (address==4){ //Si la dirección es 4 es dato del pot.
intToStr(rxbuffer,as);
lcd_out(1,10,as);
delay_ms(50);
}
if (address!= 4){ //Si es diferente de 4 mostrar datos en
dato=rxbuffer; //el LCD.
direccion=address;
lcd_chr(2,direccion,dato);
}
}
}
https://www.dropbox.com/s/if8kfvh84wgoe ... 0Slave.rar
-
- Posts: 3
- Joined: 09 Jun 2014 09:19
Re:Plz show me the false.!!!
Plz show me the false.Remoeggel wrote:
It works now.
The problem was a false value in the register SSPCON.
Remo
thanks!
-
- Posts: 3
- Joined: 09 Jun 2014 09:19
Re: PIC 2 PIC Master/Slave Communication using I2C... Enjoy
Hey guys! This my I2C project, it's working very well.
My project have 1 Master and 2 slave, you can add more slave if you want.
Key A, B chose slave which you wanna send data before send something.
To TomSS and FranzOrtiz my thankful!
.
.
My project have 1 Master and 2 slave, you can add more slave if you want.
Key A, B chose slave which you wanna send data before send something.
To TomSS and FranzOrtiz my thankful!
.
.
Re: It works now!!!
@TomSSS
I have a similar problem. My slave is not sending data to master. When master requests data slave has to send 4 bytes. Please help me with the code.
I have a similar problem. My slave is not sending data to master. When master requests data slave has to send 4 bytes. Please help me with the code.
- Attachments
-
- I2C Master Slave rev2.rar
- (234.79 KiB) Downloaded 363 times
[HW:] EasyPIC v7, mikroProg PIC, AVR, STM32, PSoC, Tiva, 8051
[SW:] mikroC PRO PIC, dsPIC, PIC32, AVR, ARM, 8051
mikroBasic PRO PIC, dsPIC, PIC32, AVR, ARM, 8051
mikroPascal PRO PIC, dsPIC, PIC32, AVR, ARM, 8051
Visual GLCD, Visual TFT
[SW:] mikroC PRO PIC, dsPIC, PIC32, AVR, ARM, 8051
mikroBasic PRO PIC, dsPIC, PIC32, AVR, ARM, 8051
mikroPascal PRO PIC, dsPIC, PIC32, AVR, ARM, 8051
Visual GLCD, Visual TFT
Re: PIC 2 PIC Master/Slave Communication using I2C... Enjoy
Hellow
I am new here. Im trying to use two PIC18F13K50 as master-slave I2C communication and I have used the example code that i found here but its not working. Anyone who can help me please help.
Thanks in advance
Ntokozo
I am new here. Im trying to use two PIC18F13K50 as master-slave I2C communication and I have used the example code that i found here but its not working. Anyone who can help me please help.
Thanks in advance
Ntokozo
Re: PIC 2 PIC Master/Slave Communication using I2C... Enjoy
Please, I need to convert this program to MikroBasic Pro for Pic. The design features are the same, I just need to do the conversion, but I'm having some difficulties and would like someone to help me in this.
Thank you
Thank you
-
- Posts: 11
- Joined: 09 Nov 2015 20:29
Re: PIC 2 PIC Master/Slave Communication using I2C... Enjoy
I did the Code in Hi-tech C (MPLAB X) and it's working perfectly.
The Master continuously sends a code to the slave which is output via a 7- segment display at Port D.
In addition, the Master can read Data from the slave via a button press and Display the Read via a 7-segment display of it's own
on Port D.
I used User defined Libraries for everything, that includes i2c and delays. If you want the full Code(Master/ slave and Proteus simulation) you can find it below in a Zipped folder.
The Master continuously sends a code to the slave which is output via a 7- segment display at Port D.
In addition, the Master can read Data from the slave via a button press and Display the Read via a 7-segment display of it's own
on Port D.
I used User defined Libraries for everything, that includes i2c and delays. If you want the full Code(Master/ slave and Proteus simulation) you can find it below in a Zipped folder.
- Attachments
-
- PIC-to-PIC I2C.jpg (137.57 KiB) Viewed 11209 times
-
- i2c_Master_slave.zip
- (212.66 KiB) Downloaded 300 times
-
- Posts: 11
- Joined: 09 Nov 2015 20:29
Re: PIC 2 PIC Master/Slave Communication using I2C... Enjoy
Greetings,
I have successfully done PIC-to-PIC I2C communication.
The system has a Master and Slave. The Master continuously sends (Writes) a Binary code to be displayed by the Slave (Via Port D).
In addition the Master can request a Read from the Slave via a Button press and display that data via Port D too.
I have included the code for both Master and Slave, and the Proteus simulation in a Zip folder below.
The code is written in Hi-Tech C compiler (MPlab X). It's fully commented and intuitive but if you have any queries please feel free to ask.
I have successfully done PIC-to-PIC I2C communication.
The system has a Master and Slave. The Master continuously sends (Writes) a Binary code to be displayed by the Slave (Via Port D).
In addition the Master can request a Read from the Slave via a Button press and display that data via Port D too.
I have included the code for both Master and Slave, and the Proteus simulation in a Zip folder below.
The code is written in Hi-Tech C compiler (MPlab X). It's fully commented and intuitive but if you have any queries please feel free to ask.
- Attachments
-
- i2c_Master_slave.zip
- All code is user defined, that is - I2C, and even delays.
- (212.66 KiB) Downloaded 406 times
Re: PIC 2 PIC Master/Slave Communication using I2C... Enjoy
Hi Tom,
I have a silly question: if the slave is using portC for inputs to send data back to the master, how do you connect the master to the slave since the I2C link is already using two of the portC pins (14 and 15 on the PIC16F876A) thank you, Marc
I have a silly question: if the slave is using portC for inputs to send data back to the master, how do you connect the master to the slave since the I2C link is already using two of the portC pins (14 and 15 on the PIC16F876A) thank you, Marc