⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iic.c

📁 在EP9315下实现的基于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 + -