?? i2c.c
字號:
//PCF8583的宏定義
#define TDATA_H 0x0008 //FLOATS DATA LINE (IOPF3=1)
#define TDATA_L 0xFFF7 //DRIVES DATA LINE LOW(IOPF3=0)
#define TCLOCK_H 0x0004 //FLOATS CLOCK LINE (IOPF2=1)
#define TCLOCK_L 0xFFFB //DRIVES CLOCK LINE LOW(IOPF2=0)
#define TDATACLOCK_H 0x000C //FLOATS CLOCK AND DATA LINE(IOPF2 IOPF3=11)
#define TDATACLOCK_L 0xFFF3 //DRIVE CLOCK AND DATA LINE LOW(IOPF2,IOPF3=00)
#define TDATA_INPUT 0xF7FF //PFDATDIR.11=0
#define TDATA_OUTPUT 0x0800 //PFDATDIR.11=1
#define TSHIFTNUM 5
#define TNUMBER 6 //讀寫PCF8583的參數個數
/****************************************/
void delay(int x)
{ int count;
for(count=0;count<x;count++)
;
}
/*;======== I2C發送一字節子程序 ====================
; 描述:通過SDA線向EEPROM器件發送一個字節
;=================================================*/
void pcf_transmit(unsigned int pcfdata)
{ unsigned int i;
*PFDATDIR=*PFDATDIR&TCLOCK_L; /*SCL=0*/
delay(72);
*PFDATDIR=*PFDATDIR|TDATA_OUTPUT; /*SDA output*/
for(i=0;i<8;i++)
{
if(pcfdata&0x0080)
*PFDATDIR=*PFDATDIR|TDATA_H; /*SDA=1*/
else
*PFDATDIR=*PFDATDIR&TDATA_L; /*SDA=0*/
delay(72); //64
*PFDATDIR=*PFDATDIR|TCLOCK_H; /*SCL=1*/
delay(72);
*PFDATDIR=*PFDATDIR&TCLOCK_L; /*SCL=0*/
delay(24); //8添加的!!!!!!!!!!!
pcfdata=pcfdata<<1;
}
}
/*;======== I2C接收一字節子程序 ====================
; 描述:通過SDA線從EEPROM器件讀入一個字節
;=================================================*/
unsigned int pcf_receive()
{ unsigned int i,temp;
unsigned int pcfdata=0x0000;
*PFDATDIR=*PFDATDIR&TDATA_INPUT;/*SDA INPUT*/
*PFDATDIR=*PFDATDIR&TDATACLOCK_L; //SCL=0,?????
delay(72);
for(i=0;i<8;i++)
{
pcfdata=pcfdata<<1;
*PFDATDIR=*PFDATDIR|TCLOCK_H; /*SCL=1*/
delay(72);
temp=*PFDATDIR&TDATA_H;
if(temp==0)
pcfdata=pcfdata&0XFFFE;/*如果數據位為0,則R_DATA最低位清0*/
else
pcfdata=pcfdata|0x0001;
//pcfdata=(pcfdata+((*PFDATDIR&TDATA_H)>>TSHIFTNUM))<<1; /*input DATA need change(>>)*/
*PFDATDIR=*PFDATDIR&TCLOCK_L; /*SCL=0*/
delay(72);
}
*PFDATDIR=*PFDATDIR|TDATA_OUTPUT; /*SDA output*/
delay(24); //添加的!!!!!!!!!!!
//pcfdata=pcfdata>>1;
return(pcfdata);
}
/*;======== I2C 啟動子程序 =========================
; 描述:啟動I2C總線
;=================================================*/
void pcf_start()
{
*PFDATDIR=*PFDATDIR|TDATACLOCK_H; /*SDA=1,SCL=1*/
delay(72);
*PFDATDIR=*PFDATDIR&TDATA_L; /*SDA=0*/
delay(72);
*PFDATDIR=*PFDATDIR&TCLOCK_L; /*SCL=0*/
delay(24); //添加的!!!!!!!!!!!
}
/*;======== I2C 結束子程序 =========================
; 描述:結束 I2C 總線
;=================================================*/
void pcf_stop()
{
*PFDATDIR=*PFDATDIR&TDATA_L; //SDA=0
delay(24); //16*/
*PFDATDIR=*PFDATDIR|TCLOCK_H; /*SCL=1*/
delay(24); //8添加的!!!!!!!!!!!
*PFDATDIR=*PFDATDIR|TDATA_H; /*SDA=1*/
delay(24);
}
/*;======== I2C 從機應答子程序 =====================
; 描述:從機發應答信號
;=================================================*/
unsigned int pcf_slave_ack()
{ unsigned int k;
*PFDATDIR=*PFDATDIR|TDATA_H; /* SDA=1*/
delay(24); //8
*PFDATDIR=*PFDATDIR&TDATA_INPUT; /* SDA設為輸入*/
delay(24);
*PFDATDIR=*PFDATDIR|TCLOCK_H; /*SCL=1*/
delay(24);
if(*PFDATDIR&TDATA_H)
k=1; //失敗
else
k=0;
*PFDATDIR=(*PFDATDIR|TDATA_OUTPUT)&TDATACLOCK_L;/*SDA設為輸出,SDA=0,SCL=0*/
delay(24); //后來加的!!!!
return(k);
}
/*;======== I2C 主機不發應答子程序 =====================
; 描述:主機不發應答信號
;=================================================*/
void pcf_no_ack()
{
*PFDATDIR=*PFDATDIR|TCLOCK_H; /*SCL=1 */
delay(24); //8
*PFDATDIR=*PFDATDIR&TCLOCK_L; /*Scl=0 */
delay(24); //添加的!!!!!!!!!!!
}
/*;======== I2C 主機應答子程序 =====================
; 描述:主機發應答信號
;=================================================*/
void pcf_master_ack()
{
*PFDATDIR=*PFDATDIR&TCLOCK_L; //SCL=0
*PFDATDIR=*PFDATDIR&TDATA_L; /*SDA=0 */
*PFDATDIR=*PFDATDIR|TCLOCK_H; //SCL=1
delay(24); //8添加的!!!!!!!!!!!
*PFDATDIR=*PFDATDIR&TCLOCK_L; /*Scl=0 */
}
/*;======== 向I2C 寫1個字節子程序 =====================
; 描述:入口為要寫入數據的地址ADDR,數據DATA
; 出口為0表示操作成功;為1表示操作失敗
;=================================================*/
unsigned int byte_wr(unsigned int addr,unsigned int data)
{ unsigned int k;
pcf_start();
pcf_transmit(0x0A0); //送寫控制字
k=pcf_slave_ack(); //從機應答
if(k==0)
{ pcf_transmit(addr); //送地址
k=pcf_slave_ack();
}
if(k==0)
{ pcf_transmit(data);
k=pcf_slave_ack();
}
if(k==0)
pcf_stop();
return(k);
}
/*;======== 從I2C 讀1個字節子程序 =====================
; 描述:入口為要讀數據的地址ADDR,
; 出口為數據DATA
;=================================================*/
unsigned int byte_rd(unsigned int addr)
{ unsigned int data=0,k;
pcf_start(); //啟動I2C總線
pcf_transmit(0x0A0); //送寫控制字
k=pcf_slave_ack(); //從機應答
if(k==0)
pcf_transmit(addr); //送地址
k=pcf_slave_ack();
if(k==0)
{ pcf_start();
pcf_transmit(0x0A1); //送讀控制字
}
k=pcf_slave_ack();
if(k==0)
{ data=pcf_receive();
pcf_no_ack();
pcf_stop();
}
if(k==0)
return(data);
else
return(0x0FFFF);
}
/*;======== 連續頁寫子程序 ===========================
; 描述:向EEPROM寫入1~TNUMBER個字,最多為TNUMBER個字(由EEPROM器件決定)
; 入口:要寫的起始地址ADDR,要寫數據的數組首址ARRAY
; 出口:返回0或1。為0表示操作成功;為1表示操作失敗
;=================================================*/
unsigned int pcf_wr(unsigned int addr,unsigned int *array)
{ unsigned int k,i; /*page write subroutine*/
//delay(7500);
pcf_start();
pcf_transmit(0x0A0); //送寫控制字
k=pcf_slave_ack();
if(k==0)
{ pcf_transmit(addr);
}
k=pcf_slave_ack();
if(k==0)
{ for(i=0;i<TNUMBER;i++)
{
/*pcf_transmit((*array>>8)&0xff); //送高8位
k=pcf_slave_ack();
if(k==1)
break;
array++;*/
pcf_transmit(*array); //送低8位
k=pcf_slave_ack();
if(k==1)
break;
array++;
}
}
pcf_stop();
return(k);
}
/*;======== 頁讀子程序 ===========================
; 描述:從EEPROM讀出1~TNUMBER個字,最多為TNUMBER個字(由EEPROM器件決定)
; 入口:要讀的起始地址ADDR,讀出數據存放數組的首址ARRAY
; 出口:返回0或1。為0表示操作成功;為1表示操作失敗
;=================================================*/
unsigned int pcf_rd(unsigned int addr,unsigned int *array)
{
unsigned int k,i,temp;
pcf_start();
pcf_transmit(0x0A0);
k=pcf_slave_ack();
if(k==0)
pcf_transmit(addr);
k=pcf_slave_ack();
if(k==0)
{ pcf_start();
pcf_transmit(0x0A1);
}
k=pcf_slave_ack();
if(k==0)
{ for(i=0;i<(TNUMBER-1);i++)
{
temp=pcf_receive();
/**array=temp;*/
*array=temp&0x00ff;
pcf_master_ack();
array++;
}
temp=pcf_receive();
/**array|=(temp&0x00ff); */
*array=temp&0x00ff;
pcf_no_ack();
pcf_stop();
}
return(k);
}
/**********從8583中讀時間子程序------------------**********/
void time_read()
{
pcf_rd(0x02,&pcf_data[0]);
time[0]=year_base+((pcf_data[3]&0x00c0)>>6);//year
time[1]=((pcf_data[4]&0x001f)<<8)|(pcf_data[3]&0x003f); //month,date
time[2]=((pcf_data[4]&0x00e0)<<3)|pcf_data[2]; //week.hour
time[3]=(pcf_data[1]<<8)|pcf_data[0]; //minute,second
}
/***********----------------*********/
void time_write()
{
pcf_data[0]=0x0; //ms
pcf_data[1]=chtime[3]&0x00ff; //second
pcf_data[2]=(chtime[3]&0xff00)>>8; //minute
pcf_data[3]=chtime[2]&0x00ff; //hour;
pcf_data[4]=((chtime[0]&0x03)<<6)|(chtime[1]&0x003f); //year/date
pcf_data[5]=((chtime[2]&0x0700)>>3)|((chtime[1]&0x1f00)>>8); //week/month
pcf_wr(0x01,&pcf_data[0]);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -