void init_iic()
{
time.second=57;
time.minute=2;
time.hour=12;
time.day=1;
time.week=3;
time.month=3;
time.year=17;//默认时间
TRISCbits.TRISC3=1; //iic主模式配置为输入
TRISCbits.TRISC4=1;
SSP1STAT=0x00;
SSP1CON1=0x38; //使能iic主模式
SSP1CON2=0x00;
SSP1ADD=0x19;//波特率设置 400K HZ
}
void IIC_write_n(unsigned char addr,unsigned char length,unsigned char *pbuf)//写
{
unsigned char send_da;
unsigned char i=0;
SSP1IF=0; //MSSP 中断标志位 0 表示没有等待你相应的中断
// SEN=1;//启动位 启动使能位仅在IIC主模式 //在SDA和SCL线上建立和发送一个启动信号时序
SSP1CON2bits.SEN=1;
while(!SSP1IF);
SSP1IF=0;
SSP1BUF=0xA2;//写控制位 //发送外设IIC器件地址和写信号
while(!SSP1IF);
SSP1IF=0; //软件清零 不会自动清零
SSP1BUF=addr;//起始地址
while(!SSP1IF);
SSP1IF=0;
for(i=0;i
{
send_da=*(pbuf++);
SSP1BUF=send_da;
while(!SSP1IF);
SSP1IF=0;
}
SSP1CON2bits.PEN=1;
//PEN=1;//停止位 //在SDA和SCL线上建立和发送一个停止信号时序
while(!SSP1IF); //如果收到停止信号同样会置位
SSP1IF=0;
}
void IIC_write(unsigned char addr,unsigned char data)//写
{
SSP1IF=0; //MSSP 中断标志位 0 表示没有等待你相应的中断
SSP1CON2bits.SEN=1;
// SEN=1;//启动位 启动使能位仅在IIC主模式 //在SDA和SCL线上建立和发送一个启动信号时序
while(!SSP1IF);
SSP1IF=0;
SSP1BUF=0xA2;//写控制位 //发送外设IIC器件地址和写信号
while(!SSP1IF);
SSP1IF=0; //软件清零 不会自动清零
SSP1BUF=addr;//写地址 //发送要读外设IIC器件数据的地址
while(!SSP1IF);
SSP1IF=0;
SSP1BUF=data;//写数据 //发送要读外设IIC器件要存储的数据或命令
while(!SSP1IF);
SSP1IF=0;
SSP1CON2bits.PEN=1;
//PEN=1;//停止位 //在SDA和SCL线上建立和发送一个停止信号时序
while(!SSP1IF); //如果收到停止信号同样会置位
SSP1IF=0;
}
unsigned char IIC_read_n(unsigned char addr,unsigned char length,unsigned char *pbuf)//读
{ //unsigned char data;
//unsigned int receive_da;
unsigned char i=0;
SSP1IF=0;
SSP1CON2bits.SEN=1;
//SEN=1;//开始位
while(!SSP1IF);
SSP1IF=0;
SSP1BUF=0xA2;//控制位写
while(!SSP1IF);
SSP1IF=0;
SSP1BUF=addr;//写地址
while(!SSP1IF);
SSP1IF=0;
SSP1CON2bits.RSEN=1;
// RSEN=1;//重新开始位
while(!SSP1IF);
SSP1IF=0;
SSP1BUF=0xA3;//控制位读
while(!SSP1IF);
SSP1IF=0;
// RCEN=1;//使能接收 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
// while(!SSPIF);
for(i=0;i
{
SSP1CON2bits.RCEN=1;//使能接收
while(!SSP1IF);
*pbuf =SSP1BUF;
//SSPBUF=send_da;
while(!SSP1IF);
SSP1IF=0;
SSP1CON2bits.ACKDT=0;
// ACKDT=0;
SSP1CON2bits.ACKEN=1;
// ACKEN=1;//使能应答位
while(!SSP1IF);
SSP1IF=0;
pbuf++;
}
SSP1CON2bits.RCEN=0;
// RCEN=0;
SSP1CON2bits.PEN=1;
// PEN=1;//停止位
while(!SSP1IF);
SSP1IF=0;
return *pbuf;
}
//unsigned char IIC_read(unsigned char addr)//读
//{ unsigned char data;
//
//SSP1IF=0;
//SSP1CON2bits.SEN=1;
////SEN=1;//开始位
//while(!SSP1IF);
//SSP1IF=0;
//SSP1BUF=0xA2;//控制位写
//while(!SSP1IF);
//SSP1IF=0;
//SSP1BUF=addr;//写地址
//while(!SSP1IF);
//SSP1IF=0;
//SSP1CON2bits.RSEN=1;
// // RSEN=1;//重新开始位
// while(!SSP1IF);
// SSP1IF=0;
// SSP1BUF=0xA3;//控制位读
// while(!SSP1IF);
// SSP1IF=0;
// SSP1CON2bits.RCEN=1;
// // RCEN=1;//使能接收
// while(!SSP1IF);
// data=SSP1BUF;//读数据
// while(!SSP1IF);
// SSP1IF=0;
// SSP1CON2bits.ACKDT=0;
// // ACKDT=0;
// //ACKEN=1;//使能应答位
// SSP1CON2bits.ACKEN=1;
// while(!SSP1IF);
// SSP1IF=0;
// SSP1CON2bits.RCEN=0;
// // RCEN=0;
// SSP1CON2bits.PEN=1;
// // PEN=1;//停止位
// while(!SSP1IF);
// SSP1IF=0;
// return(data);
//}
unsigned char BCD2Val(unsigned char x) //BCD转十进制
{
unsigned char tmp = 0;
tmp = ((unsigned char)(x & (unsigned char)0xF0) >> (unsigned char)0x04) * 10;
return (tmp + (x & (unsigned char)0x0F));
}
unsigned char Val2BCD(unsigned char x) //十进制转BCD码子程序
{
unsigned char bcdhigh = 0;
while (x >= 10)
{
bcdhigh++;
x -= 10;
}
return ((unsigned char)(bcdhigh << 4) | x);
}
unsigned char P8563_Read_Time() //PCF8563读取时间子程序
{
unsigned char temp[7];
IIC_read_n(0x02,0x07,temp);
time.second=BCD2Val(temp[0]&0x7f);
time.minute=BCD2Val(temp[1]&0x7f);
time.hour=BCD2Val(temp[2]&0x3f);
time.day=BCD2Val(temp[3]&0x3f);
time.week=BCD2Val(temp[4]&0x07);
time.month=BCD2Val(temp[5]&0x1f);
time.year=BCD2Val(temp[6]);
return 0;
}
void P8563_Set_Time() //PCF8563设置时间子程序
{
unsigned char temp[7];
unsigned char i;
for(i=0;i<7;i++)
{
temp[i]=Val2BCD(((unsigned char *)(&time))[i]);
}
IIC_write_n(0x02,7,temp);
}