PIC单片机之I2C从模式Word格式文档下载.docx
《PIC单片机之I2C从模式Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《PIC单片机之I2C从模式Word格式文档下载.docx(26页珍藏版)》请在冰豆网上搜索。
![PIC单片机之I2C从模式Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2022-10/9/ae7417ec-8423-4147-b9ac-b231eed3aee9/ae7417ec-8423-4147-b9ac-b231eed3aee91.gif)
输入7位地址和一位的写状态位,
第二个字节:
然后写入EEPROM数据地址,
第三个字节:
输入7位地址和一位的读状态位,
第四~N个字节:
读出的EEPROM的数据。
我们来讲解下程序的基本思路:
我们使能了MSSP中断,即是I2C接收中
断,当PIC单片机接收到一个数据后就会产生中断。
那是接收到设备地址,
还是接收到数据,由SSP1STAT寄存器的状态位来判断。
需要判断的状态位分别是:
数据和地址:
用来判断接收到是地址还是数据
启动位:
用来判断是否接收到启动位
读写:
用来判断是写状态还是读状态。
缓存满:
用来判断缓冲区是否满
我们以随机地址读取为例:
讲讲程序执行的过程
1,从单片机接收到启示位和设备地址中断:
我们判断SSP1STAT的状态
位为(写状态,地址,缓存满,接收到启示位)然后读取缓存中的设备地址,
接着在读取需要读/写的数据地址。
2,单片机再次接收到设备地址:
我们判断是SSP1STAT的状态为(读状态)
然后从设备就输出数据
我们以写字节数据为例:
2,单片机判断SSP1STAT的状态位为(写状态,数据,缓存满)那幺单片机
就接收输入的数据。
初始化设置:
1,设置I2C通信的两引脚为CLKSCL为输入,
TRISB6=input;
TRISB4=input;
2,将MSSP设置为I2C从模式,七位从地址
SSP1CONbits.SSPM0=0;
SSP1CONbits.SSPM1=1;
SSP1CONbits.SSPM2=1;
SSP1CONbits.SSPM3=0;
//I2Cslavemode,7bitaddress
3,使能CLK时钟
SSP1CONbits.CKP=1;
//enableclock
4,设置从设备地址为0xA0
SSP1ADD=0xA0;
//slaveaddressis0xa0
5,开启I2C
SSP1CONbits.SSPEN=1;
//enableI2c
6,清楚状态标志
SSPSTAT=0;
7,使能I2C中断
PIE1bits.SSP1IE=1;
//EnabeinterruptMSSP
INTCONbits.PEIE=1;
INTCONbits.GIE=1;
如果你要使用PIC单片机I2C从模式只要使用下面的代码:
将voidi2c_salve_interrupt_tx();
voidi2c_salve_interrupt_rx();
放到中断程序
中,如下:
voidinterruptisr(void)
{
if(SSP1IE&
amp;
&
SSP1IF)
i2c_salve_interrupt_tx();
i2c_salve_interrupt_rx();
SSP1IF=0;
}
将初始化函数init_i2c_slave();
放到主函数中
voidmain()
init_i2c_slave();
头文件:
i2c_salve.h
#ifndef_I2C_SALVE_H
#define_I2C_SALVE_H
voidinit_i2c_slave();
voidi2c_salve_interrupt_tx();
voidi2c_salve_interrupt_rx();
#endif
代码:
i2c_salve.c
#include
;
#defineinput1
#defineRX_BUF_LEN29
#definewhile_delay6000
unsignedchari2c_address,word_address,Register[29];
unsignedcharRANDOM_READ,i2c_counter;
externunsignedcharA_readflag;
/*I2CSALVE*/
voidinit_i2c_slave()
/*I2Csalvemodeinterrupt*/
voidi2c_salve_interrupt_tx()//masterread
unsignedcharTemp;
unsignedinttimercounter;
Temp=SSP1STAT;
Temp&
=0x2D;
if(SSP1STATbits.R_nW==1)//Readoperation.
A_readflag=0;
SSP1IF=0;
i2c_address=SSP1BUF;
i2c_counter=word_address;
while(i2c_counter{
SSP1BUF=Register[i2c_counter];
//senddata
SSP1CONbits.CKP=1;
//enablecolck
timercounter=while_delay;
while(PIR1bits.SSP1IF==0)
timercounter--;
if(timercounter==0)
return;
}//waitingfor~ACK
if(SSP1CON2bits.ACKSTAT==1)
return;
//NOACK
else
i2c_counter++;
//ACK
voidi2c_salve_interrupt_rx()//masterwriter
unsignedcharrx_status;
rx_status=false;
if(Temp==0x09)//Writeoperation,lastbytewasanaddress,bufferisfull
}//waitingforsend~ACK
word_address=SSP1BUF;