如果你要使用PIC单片机I2C从模式只要使用下面的代码:
将void i2c_salve_interrupt_tx();void i2c_salve_interrupt_rx();放到中断程序中,如下:
void interrupt isr(void)
{
if(SSP1IE && SSP1IF)
{
i2c_salve_interrupt_tx();
i2c_salve_interrupt_rx();
SSP1IF=0;
}
}
将初始化函数init_i2c_slave();放到主函数中
void main()
{
init_i2c_slave();
}
头文件 :i2c_salve.h
#ifndef _I2C_SALVE_H
#define _I2C_SALVE_H
void init_i2c_slave();
void i2c_salve_interrupt_tx();
void i2c_salve_interrupt_rx();
#endif
代码:i2c_salve.c
#include<pic.h>;
#define input 1
#define RX_BUF_LEN 29
#define while_delay 6000
unsigned char i2c_address,word_address,Register[29];
unsigned char RANDOM_READ,i2c_counter;
extern unsigned char A_readflag;
/*I2C SALVE */
void init_i2c_slave()
{
TRISB6 = input;
TRISB4 = input;
SSP1CONbits.SSPM0 = 0;
SSP1CONbits.SSPM1 = 1;
SSP1CONbits.SSPM2 = 1;
SSP1CONbits.SSPM3 = 0;// I2C slave mode ,7bit address
SSP1CONbits.CKP = 1; // enable clock
SSP1ADD =0xA0; //slave address is 0xa0
SSP1CONbits.SSPEN=1;//enable I2c
SSPSTAT=0;
PIE1bits.SSP1IE = 1;//Enabe interrupt MSSP
INTCONbits.PEIE = 1;
INTCONbits.GIE = 1;
}
/*I2C salve mode interrupt */
void i2c_salve_interrupt_tx()//master read
{
unsigned char Temp;
unsigned int timercounter;
Temp=SSP1STAT;
Temp &= 0x2D;
if(SSP1STATbits.R_nW ==1)//Read operation.
{
A_readflag=0;
SSP1IF = 0;
i2c_address = SSP1BUF;
i2c_counter = word_address;
while(i2c_counter < RX_BUF_LEN)
{
SSP1BUF=Register[i2c_counter];//send data
SSP1CONbits.CKP=1;// enable colck
timercounter=while_delay;
while(PIR1bits.SSP1IF == 0)
{
timercounter--;
if(timercounter==0)
{
return;
}
}//waiting for ~ACK
SSP1IF = 0;
if(SSP1CON2bits.ACKSTAT == 1)
{
return ; //NOACK
}
else
{
i2c_counter++;//ACK
}
}
SSP1IF = 0;
}
}
void i2c_salve_interrupt_rx()//master writer
{
unsigned char rx_status;
unsigned char Temp;
unsigned int timercounter;
rx_status=false;
Temp=SSP1STAT;
Temp &= 0x2D;
if(Temp==0x09)//Write operation,last byte was an address,buffer is full
{
SSP1IF = 0;
i2c_address = SSP1BUF;
timercounter=while_delay;
while(PIR1bits.SSP1IF == 0)
{
timercounter--;
if(timercounter==0)
{
return ;
}
}//waiting for send ~ACK
SSP1IF = 0;
word_address = SSP1BUF;
return ;
}
if(Temp==0x29)//Write operation,last byte was data,buffer is full
{
SSP1IF=0;
Register[word_address]=SSP1BUF;
word_address++;
if(word_address>=RX_BUF_LEN)
{
word_address=0;
}
}
}
|