📄 pcf8583.c
字号:
#include "typedef.h"
#include "f2407regs_c.h"
#include "global.h"
extern uchar pcdata[Len];
extern uchar deviceAddr;
void Pcf8583IoInit();
void Pcf8583DelayI2c();
void Pcf8583Start();
void Pcf8583sendByte(uchar byte);
uchar Pcf8583Ack();
void Pcf8583Stop();
uchar WriteByte(uchar addr,uchar data);
uchar Receive();
void HostNoAck();
void HostAck();
uchar ReadByte(uchar addr);
uchar ContinusWrite(uchar addr,uchar *ptr,uchar n);
uchar ContinusRead(uchar addr,uchar *ptr,uchar n);
void setCalendar(void);
void getCalendar(void);
#define sda_1 MCRC &= 0xEFFF;PFDATDIR |= 0x1010
#define sda_0 MCRC &= 0xEFFF;PFDATDIR |= 0x1000;PFDATDIR &= 0xffef
#define scl_1 MCRA &= 0xbfff;PBDATDIR |= 0x4040
#define scl_0 MCRA &= 0xbfff;PBDATDIR |= 0x4000;PBDATDIR &= 0xffbf
#define sda_in MCRC &= 0xEFFF;PFDATDIR &= 0xefff;PFDATDIR |= 0x0010
/*
io口初始化,配置SCL,SDA
*/
void Pcf8583IoInit()
{
sda_1;
scl_1;
WriteByte(0x00,0x00); //count
}
/*
延时函数
*/
void Pcf8583DelayI2c()
{
int i;
for(i=0x7d;i--;) i=i; //unused action
}
/*
启动信号
*/
void Pcf8583Start()
{
sda_1;
scl_1;
Pcf8583DelayI2c();
sda_0;
Pcf8583DelayI2c();
scl_0;
Pcf8583DelayI2c();
}
/*
发送一字节
*/
void Pcf8583sendByte(uchar byte)
{
uchar flag,sz;
scl_0; //scl = 0;
Pcf8583DelayI2c();
for(flag=0x80;flag!=0x00;flag=flag/2)
{
sz=byte&flag; //clear unused bits
if(sz==0) {sda_0;} //if relatived bit is 0,sda = 0
else {sda_1;} //if relatived bit is 1,sda = 1
Pcf8583DelayI2c();
scl_1; //scl = 1
Pcf8583DelayI2c();
scl_0; //scl = 0
Pcf8583DelayI2c();
}
}
/*
从器件应答 1:failed; 0:successful
*/
uchar Pcf8583Ack()
{
uchar sz, k=0;
sda_1; //sda = 1
Pcf8583DelayI2c();
sda_in; //config sda as input port
Pcf8583DelayI2c();
scl_1; //scl = 1
Pcf8583DelayI2c();
sz = PFDATDIR&0x10; //test data bit
if(sz==0x10) k = 1; // if data bit is 1,k=1,failed
else k = 0; // if data bit is 0,k=0;successed
sda_0; scl_0; // scl = sda = 0
return(k);
}
/*
停止信号
*/
void Pcf8583Stop()
{
sda_0; //sda = 0
Pcf8583DelayI2c();
scl_1; //scl = 1
Pcf8583DelayI2c();
sda_1; //sda = 1
}
/*
写字节,包括启动时序
*/
uchar WriteByte(uchar addr,uchar data)
{
uchar k;
Pcf8583Start(); //start i2c bus
Pcf8583sendByte(0xa0); //send control byte
k = Pcf8583Ack();
if(k==0)Pcf8583sendByte(addr); //send out addr
else
{
sda_1;scl_1;
return(k);
}
k = Pcf8583Ack();
if(k==0)Pcf8583sendByte(data); //send out data
else
{
sda_1; scl_1;
return(k);
}
k = Pcf8583Ack();
if(k==0) Pcf8583Stop(); // stop
else {sda_1;scl_1;}
return(k);
}
/*
接收过程
*/
uchar Receive()
{
uchar data=0,sz,i;
sda_in; //config sda as input port
scl_0; //scl = 0
Pcf8583DelayI2c();
for(i=0;i<8;i++)
{
data = data<<1; // shift 1 bit to left
scl_1; //scl = 1
Pcf8583DelayI2c();
sz = PFDATDIR&0x10; //get related data bit
if(sz==0) data &= 0xfffe; // if data bit is 0, clr lsb of the data
else data |= 0x01; // if data bit is 1, set lsb of the data
scl_0; // scl = 0;
Pcf8583DelayI2c();
}
sda_1; // config sda as output
return(data);
}
/*
主器件不应答
*/
void HostNoAck()
{
scl_1; //scl =1
Pcf8583DelayI2c();
scl_0; //scl = 0
}
/*
主器件应答
*/
void HostAck()
{
scl_0; //scl = 0
sda_0; //sda = 0
scl_1; //scl = 1
Pcf8583DelayI2c();
scl_0; //scl = 0
}
/*
接受一字节,正确返回该字节,错误返回0xffff
*/
uchar ReadByte(uchar addr)
{
uchar k,data;
Pcf8583Start();
Pcf8583sendByte(0xa0); //send control byte
k = Pcf8583Ack();
if(k==0) Pcf8583sendByte(addr); //send addr
else
{
sda_1; scl_1;
return(0xffff);
}
k = Pcf8583Ack();
if(k==0)
{
Pcf8583Start();
Pcf8583sendByte(0xa1);
}
else
{
sda_1;scl_1;
return(0xffff);
}
k = Pcf8583Ack();
if(k==0)
{
data = Receive();
HostNoAck();
Pcf8583Stop();
return(data);
}
else
{
sda_1;scl_1;
return(0xffff);
}
}
#ifdef PROMATIC
/*
连续读内存,内存首地址为addr,存放数据首地址为ptr,数据长度为n
*/
uchar ContinusWrite(uchar addr,uchar *ptr,uchar n)
{
uchar k;
Pcf8583Start();
Pcf8583sendByte(0xa0); //send control byte
k = Pcf8583Ack();
if(k==0) Pcf8583sendByte(addr); //send addr
k = Pcf8583Ack();
if(k==0)
{
for(;n>0;n--,ptr++)
{
Pcf8583sendByte(*ptr); //send data
k = Pcf8583Ack();
if(k==1)break;
}
}
Pcf8583Stop(); //stop
return(k);
}
/*
连续写内存,内存首地址为addr,存放数据首地址为ptr,数据长度为n
*/
uchar ContinusRead(uchar addr,uchar *ptr,uchar n)
{
uchar k,data;
Pcf8583Start();
Pcf8583sendByte(0xa0); //send control byte
k = Pcf8583Ack();
if(k==0) Pcf8583sendByte(addr); //send addr
k = Pcf8583Ack();
if(k==0)
{
Pcf8583Start();
Pcf8583sendByte(0xa1); //send control byte
}
k = Pcf8583Ack();
if(k==0)
{
for(;n>1;n--,ptr++)
{
*ptr = Receive();
HostAck();
}
}
data = Receive();
*ptr = data;
HostNoAck();
Pcf8583Stop(); //stop
return(k);
}
#endif
/*
0x0d 0x00 0x85 0x01 0x10 0x26 0x08 0x48 0x56 0x6 0x05 0xaa 0xbb
长度0 地址1 命令2 年3 月4 日5 时6 分7 秒8 星期9 年头0a 校验1 校验2
void setCalendar(void); 设置时钟
void getCalendar(void); 读取时钟
*/
void setCalendar( )
{
uchar status,flag=0;
uchar year,month,day,hour,minute,second,weekday,year_header;
uchar addr02=0,addr03=0,addr04=0,addr05=0,addr06=0;/*addr in the pcf8583*/
uint pcf8583_flag = 0;
year = pcdata[3];
month = pcdata[4];
day = pcdata[5];
hour = pcdata[6];
minute = pcdata[7];
second = pcdata[8];
weekday = pcdata[9];
year_header = pcdata[0x0a];
if(year>0x3) flag = 1;
if((month>0x12) || (month == 0)) flag = 1;
if((day>0x31 ) || (day == 0)) flag = 1;
if(hour>0x24) flag = 1;
if(minute>0x59) flag = 1;
if(second>0x59) flag = 1;
if((weekday>0x7) || (weekday == 0)) flag = 1;
if(flag){;}
else
{
status = OK;
addr02 = second;
addr03 = minute;
//////////////hours//////////////////
if( ((hour&0xff) >> 4) == 0 ) addr04 |= 0;
else if( ((hour&0xff) >> 4) == 1 )addr04 |= 0x10;
else if( ((hour&0xff) >> 4) == 2 )addr04 |= 0x20;
addr04 |= hour&0x0f;
/////////////////////////////////////////
/////year , day//////////////////////////
addr05 = (year&0xff) << 6;
if( ((day&0xff) >> 4) == 0) addr05 |= 0;
else if( ((day&0xff) >> 4) == 1) addr05 |= 0x10;
else if( ((day&0xff) >> 4) == 2) addr05 |= 0x20;
else if( ((day&0xff) >> 4) == 3) addr05 |= 0x30;
addr05 |= day&0x0f;
/////////////////////////////////////////
/////weekday,month///////////////////////
addr06 |= (weekday&0xff) << 5;
if((month&0x10) == 0x10 ) addr06 |= 0x10;
addr06 |= month&0x0f;
/////////////////////////////////////////
pcf8583_flag = WriteByte(0x02,addr02);
if(pcf8583_flag)flag = 1; /*read i2c error*/
pcf8583_flag = WriteByte(0x03,addr03);
if(pcf8583_flag)flag = 1;
pcf8583_flag = WriteByte(0x04,addr04);
if(pcf8583_flag)flag = 1;
pcf8583_flag = WriteByte(0x05,addr05);
if(pcf8583_flag)flag = 1;
pcf8583_flag = WriteByte(0x06,addr06);
if(pcf8583_flag)flag = 1;
pcf8583_flag = WriteByte(0x64,year_header);
if(pcf8583_flag)flag = 1;
pcdata[0] = 6;
pcdata[1] = deviceAddr;
pcdata[2] = WR_RTC_CMD;
pcdata[3] = status;
}
if(flag)
{
status = PARA_OV;
pcdata[0] = 6;
pcdata[1] = deviceAddr;
pcdata[2] = WR_RTC_CMD;
pcdata[3] = status;
}
}
void getCalendar()
{
uchar year,month,day,hour,minute,second,weekday,year_header;
uchar addr02=0,addr03=0,addr04=0,addr05=0,addr06=0;/*addr in the pcf8583*/
uint pcf8583_flag = 0;
addr02 = ReadByte(0x02);
if(addr02 == 0xffff)pcf8583_flag = 1; /*read i2c error*/
addr03 = ReadByte(0x03);
if(addr03 == 0xffff) pcf8583_flag = 1;
addr04 = ReadByte(0x04);
if(addr04 == 0xffff)pcf8583_flag = 1;
addr05 = ReadByte(0x05);
if(addr05 == 0xffff) pcf8583_flag = 1;
addr06 = ReadByte(0x06);
if(addr06 == 0xffff)pcf8583_flag = 1;
year_header = ReadByte(0x64);
if(addr06 == 0xffff) pcf8583_flag = 1;
year = addr05 >> 6;
month = addr06&0x1f;
day = addr05&0x3f;
hour = addr04&0x3f;
minute = addr03;
second = addr02;
weekday = addr06>>5;
pcdata[0] = 14;
pcdata[1] = deviceAddr;
pcdata[2] = RD_RTC_CMD;
if(pcf8583_flag)pcdata[3] = PARA_OV; //0x11
else pcdata[3] = OK; //0x00
pcdata[4] = year;
pcdata[5] = month;
pcdata[6] = day;
pcdata[7] = hour;
pcdata[8] = minute;
pcdata[9] = second;
pcdata[10] = weekday;
pcdata[11] = year_header;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -