//**************************************************
//*****************定义头文件**********************
//**************************************************
#include<pic.h>
//**************************************************
//******************定义配置位*********************
//**************************************************
__CONFIG(0x1871);
//FLASH代码保护,RB6和RB7为普通IO口,数据代码保护RB3为数字
//IO口,低电压复位使能,上电延时开,看门狗关,4M晶体XT振荡器
//**************************************************
//******************定义常量***********************
//**************************************************
#define uchar unsigned char
#define uint unsigned int
#define SDA RC4
#define SCL RC3
//**************************************************
//****************定义写入EEPROM数据****************
//**************************************************
uchar display[8]={0X81,0X42,0X24,0X18,0X24,0X42,0X81,0X00};
//**************************************************
//**************定义读取EEPROM数据变量*************
//**************************************************
uchar data[8];
//***********************************************
//函 数 名:delayms(uchar time);
//入口参数:time
//出口参数:无
//函数作用:延时
//说 明:
//***********************************************
void delayms(uchar time)
{
uint i;
while(time--)
{
for(i=93;i>0;i--){;}
}
}
//***********************************************
//函 数 名:iic_init(void);
//入口参数:无
//出口参数:无
//函数作用:iic初始化
//说 明:
//***********************************************
void iic_init(void)
{
TRISA=0X00; //设置RA口为输出口
PORTA=0X00; //RA口输出低电平
ADCON1=0X07; //设置RA口和RE口为普通IO口
TRISC3=1;
TRISC4=1;
TRISD=0X00;
SSPCON=0x28; //设置控制寄存器
SSPCON2=0X00;
// SSPSTAT=0X80;
SSPADD=9; //用于产生100K信号 SCL=Fosc/[4*(SSPADD+1)]=4000000/4*(9+1)=100KHZ
// SSPADD=39; //用于产生100K信号 SCL=Fosc/[4*(SSPADD+1)]=16000000/4*(39+1)=100KHZ
CKE=1; //SSPSTAT寄存器BIT6的设置
SMP=1; //SSPSTAT寄存器BIT7的设置
SSPIE=0;
}
//***********************************************
//函 数 名:iic_start(void);
//入口参数:无
//出口参数:无
//函数作用:产生启动信号
//说 明:
//***********************************************
void iic_start(void)
{
SEN=1;
while(SSPIF==0){;}
SSPIF=0;
}
//***********************************************
//函 数 名:iic_restart(void);
//入口参数:无
//出口参数:无
//函数作用:产生重启信号
//说 明:
//***********************************************
void iic_restart(void)
{
RSEN=1;
while(SSPIF==0){;}
SSPIF=0;
}
//***********************************************
//函 数 名:iic_stop(void);
//入口参数:无
//出口参数:无
//函数作用:产生停止信号
//说 明:
//***********************************************
void iic_stop(void)
{
PEN=1;
while(SSPIF==0){;}
SSPIF=0;
}
//***********************************************
//函 数 名:iic_waitACK(void);
//入口参数:无
//出口参数:无
//函数作用:等待ACK应答信号
//说 明:
//***********************************************
void iic_waitACK(void)
{
uchar temp=0;
while(ACKSTAT)
{
temp++;
if(temp==255){break;}
}
}
//***********************************************
//函 数 名:iic_writebyte(uchar data);
//入口参数:data
//出口参数:无
//函数作用:写一个字节函数
//说 明:
//***********************************************
void iic_writebyte(uchar data)
{
SSPBUF=data;
while(SSPIF==0){;}
SSPIF=0;
}
//***********************************************
//函 数 名:iic_writedata(uchar addr,uchar *ptt);
//入口参数:addr,*ptt
//出口参数:无
//函数作用:按地址向EEPROM写数据块
//说 明:
//***********************************************
void iic_writedata(uchar addr,uchar *ptt)
{
uchar i;
iic_start(); //产生启动信号
iic_writebyte(0xA0); //I2C写指令和IC地址
iic_waitACK(); //调用等待ACK应答信号
iic_writebyte(addr); //写EEPROM地址
iic_waitACK(); //调用等待ACK应答信号
for(i=0;i<8;i++) //写8个数据
{
iic_writebyte(ptt[i]);
iic_waitACK(); //调用等待ACK应答信号
}
iic_stop(); //产生停止信号
}
//***********************************************
//函 数 名:iic_readbyte(void);
//入口参数:无
//出口参数:SSPBUF
//函数作用:从EEPROM读取一个字节数据
//说 明:
//***********************************************
uchar iic_readbyte(void)
{
RCEN=1;
while(SSPIF==0){;}
SSPIF=0;
return SSPBUF;
}
//***********************************************
//函 数 名:iic_readdata(uchar addr);
//入口参数:addr
//出口参数:data[8]
//函数作用:按地址从EEPROM读取数据块
//说 明:
//***********************************************
void iic_readdata(uchar addr)
{
uchar i;
iic_start(); //产生启动信号
iic_writebyte(0xA0); //I2C写指令和IC地址
iic_waitACK(); //调用等待ACK应答信号
iic_writebyte(addr); //读EEPROM数据的地址
iic_waitACK(); //调用等待ACK应答信号
iic_restart(); //产生重起信号
iic_writebyte(0xA1); //I2C读指令和IC地址
iic_waitACK(); //调用等待ACK应答信号
for(i=0;i<8;i++) //读取8个byte
{
data[i]=iic_readbyte();
if(i!=7) //最后一个数据不应答
{
ACKDT=0;
ACKEN=1;
while(SSPIF==0){;}
SSPIF=0;
}
else
{
ACKDT=1 ;
ACKEN=1;
while(SSPIF==0){;}
SSPIF=0;
}
}
iic_stop(); //产生停止信号
}
//***********************************************
//函 数 名:main(void);
//入口参数:无
//出口参数:无
//函数作用:MAIN函数
//说 明:
//***********************************************
void main(void)
{
uchar i;
iic_init(); //调用初始化程序
iic_writedata(0x00,display); //调用写数据函数,写EEPROM地址,要写的数据
delayms(250);
// iic_readdata(0x00); //调用读数据函数,读EEPROM数据地址
while(1)
{
iic_readdata(0x00);
for(i=0;i<8;i++)
{
PORTD=data[i]; //输出指示
delayms(250);
}
}
}
上程序选用4MHZ晶振时能正常工作,而选用16MHZ时就不能正常工作,改用16MHZ时只需修改:SSPADD=39; //用于产生100K信号 SCL=Fosc/[4*(SSPADD+1)]=16000000/4*(39+1)=100KHZ,在规格书上没有看到其他要修改的,请大侠指导,谢谢!
|
配置位需要改成16M