📄 iic.c
字号:
#include "linux/capability.h"
#include "linux/smp_lock.h"
#include "linux/module.h"
#include "asm/hardware.h"
#include "asm/io.h"
#define uchar unsigned char
uchar g8563_Store[4]; /*时间交换区,全局变量声明*/
uchar c8563_Store[4]={0x00,0x59,0x07,0x01}; /*写入时间初值:星期一 07:59:00*/
#define rSDA ((inl(GPIO_PGDR)>>1)&0x01)
/******************************************
** function name : wSCL(int dat)
** input parameter: scl bit data
** output parameter: null
** description : null
******************************************/
void wSCL(int dat)
{
int rdat,wdat;
rdat = inl(GPIO_PGDR);
if(dat) rdat = ((dat&0x01)| rdat);
else rdat = ((dat|0x02) & rdat);
outl(rdat,GPIO_PGDR);
}
/******************************************
** function name : wSDA(int dat)
** input parameter: sda bit data
** output parameter: null
** description : internal function
******************************************/
void wSDA(int dat)
{
int rdat,wdat;
rdat = inl(GPIO_PGDR);
if(dat) rdat = (((dat<<1)&0x02)| rdat);
else rdat = (((dat<<1)|0x01) & rdat);
outl(rdat,GPIO_PGDR);
}
/******************************************
** function name : Delay()
** input parameter: time parameter
** output parameter: null
** description : null
******************************************/
void Delay()
{
int i;
for(i=0;i<2000;i++); /*根据晶振频率制定延时时间*/
}
/********************************************
* internal function : start
* description :
* 0: both of them are high when bus is not busy,
* 1: clock is high is defined as the start conditon,
* then a high to low transfer in data line start bus;
********************************************/
void Start()
{
wSDA(1); //data line 1
wSCL(1); //clk line 1
Delay();
wSDA(0); //data line high to low transfer
Delay();
wSCL(0);
Delay();
}
/********************************************
* internal function: stop
* description:
* 0: data line remain high,while a data line low to
* high transfer will stop bus
*******************************************/
void Stop()
{
wSDA(0);
Delay();
wSCL(1);
Delay();
wSDA(1);
Delay();
}
/********************************************
内部函数,输出ACK ,每个字节传输完成,输出ack=0,结束读书据,ack=1;
********************************************/
void WriteACK(uchar ack)
{
wSDA(ack);
Delay();
wSCL(1);
Delay();
wSCL(0);
}
/***************************************************************
* Internal function:
* Description:
* A slave receiver which is addressed must generate
* an acknowledge after the reception of each byte.
* Also a master receiver must generate an acknowledge after
* the reception of each byte that has been clocked out of
* the slave transmitter.
* 0 : write data line 1 first;
* 1 : write clk line 1 then;
* 2: read ack data
********************************************/
void WaitACK()
{ int errtime=100;
wSCL(0);
wSDA(1); // write data line 1 first
outl(0x01,GPIO_PGDDR); // change the pin direction,data pin is input
Delay(); /*读ACK */
wSCL(1); // write clock line 1
while(rSDA) // read ack signal
{
errtime--;
if(!errtime) {
printk("erro happend!\n");
Stop();
break;
}
}
outl(0x03,GPIO_PGDDR);
wSCL(0);
Delay();
}
/********************************************
* Internal function:
* One data bit is transfered during each
* pulse pulse
* write data fist,then write clk line
********************************************/
void writebyte(uchar wdata)
{
uchar i;
for(i=0;i<8;i++)
{
if(wdata&0x80) wSDA(1);
else wSDA(0);
wdata<<=1;
wSCL(1);
Delay();
wSCL(0);
}
WaitACK(); //I2C器件或通讯出错,将会退出I2C通讯
}
/********************************************
内部函数. 输入数据
出口:B
每一个时钟信号的跳变传输一个数据位;,必须在时钟信号为高时保持数据的稳定
********************************************/
uchar Readbyte()
{
uchar i,bytedata;
wSDA(1); //数据信号先置位
outl(0x01,GPIO_PGDDR);
for(i=0;i<8;i++)
{
wSCL(1);
bytedata<<=1;
bytedata|=rSDA;
wSCL(0);
Delay();
}
outl(0x03,GPIO_PGDDR);
return(bytedata);
}
/********************************************
输出数据->pcf8563
********************************************/
void writeData(uchar address,uchar mdata)
{
Start();
writebyte(0xa2); /*write command,wait ack*/
writebyte(address); /*write dara ,wait ack */
writebyte(mdata); /*写数据*/
Stop();
}
/********************************************
输入数据<-pcf8563
********************************************/
uchar ReadData(uchar address) /*单字节*/
{
uchar rdata;
Start(); //启动总线
writebyte(0xa2); /*写命令,写从器件的地址*/
writebyte(address); /*写字地址*/
Start();
writebyte(0xa3); /*发送读命令*/
rdata=Readbyte(); //读取一个字节
WriteACK(1); //读完数据,写1,传输完数据,写0
Stop(); //停止总线活动
return(rdata);
}
void ReadData1(uchar address,uchar count,uchar * buff) /*多字节*/
{
uchar i;
Start();
writebyte(0xa2); /*写命令*/
writebyte(address); /*写地址*/
Start();
writebyte(0xa3); /*读命令*/
for(i=0;i<count;i++)
{
buff[i]=Readbyte();
if(i<count-1) WriteACK(0);
}
WriteACK(1);
Stop();
}
/********************************************
内部函数,读入时间到内部缓冲区
********************************************/
void P8563_Read(char *timebuf)
{ uchar time[7];
ReadData1(0x02,0x07,time);
timebuf[0]=time[0]&0x7f; /*秒*/
timebuf[1]=time[1]&0x7f; /*分*/
timebuf[2]=time[2]&0x3f; /*小时*/
timebuf[3]=time[4]&0x07; /*星期*/
timebuf[4]=time[3]&0x3f; /*分*/
timebuf[5]=time[5]&0x1f; /*小时*/
timebuf[6]=time[6]&0xff; /*星期*/
}
/********************************************
读入时间到内部缓冲区----外部调用
********************************************/
void P8563_gettime(char *timebuf)
{
P8563_Read(timebuf);
if(g8563_Store[0]==0)
P8563_Read(timebuf); /*如果为秒=0,为防止时间变化,再读一次*/
}
/********************************************
写时间修改值
********************************************/
void P8563_settime(const char *buf,int count)
{
uchar i;
//char time[4];
for(i=2;i<=count+2;i++)
{
writeData(i,buf[i-2]);
} //minutes ,seconds,hour setting
//writeData(6,g8563_Store[3]); //写星期
}
/********************************************
P8563的初始化-----外部调用
********************************************/
void P8563_init()
{
uchar i;
char time;
writeData(0x0,0x00); //写控制寄存器
//writeData(0xa,0x8); /*hour alarm */
//writeData(0x9,0x1); //minites alarm enable
//writeData(0x0e,0x12); //counter down timer
//writeData(0x0f,0x1);
writeData(0x1,0x0c); /*alarm inactive */
writeData(0xd,0xf0); //设置输出的频率信号值
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -