📄 i2c.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <absacc.h>
#include <float.h>
#include <INTRINS.h>
#include"my.h"
#define uchar unsigned char
#define uint unsigned int
#define OK 0 //0 - respond
#define NOK 1 //1 - no respond
sbit SDA =P0^0;// sda p00
sbit SCL =P0^1;// scl p01
sbit WP =P0^2;// /wc p02
#define SCL_HIGH; SCL=1;\
_nop_();\
_nop_();
#define SCL_LOW; SCL=0;\
_nop_();\
_nop_();
#define SDA_HIGH; SDA=1;\
_nop_();\
_nop_();
#define SDA_LOW; SDA=0;\
_nop_();\
_nop_();
/**************************************************
串口0队列 pc
//使用w77e58 片内1k SRAM, 要定义为xdata ,
//为确保使用的是片内1k RAM, 最好和 _at_ 0x0000;联合使用
**************************************************/
extern unsigned char xdata xBuf_0[130];
extern unsigned char xdata *Seri0_ReadSendPoint;
extern unsigned char xdata *Seri0_WriteSendPoint;
extern unsigned char data Seri0_SendNum;
extern unsigned char xdata *Seri0_ReadReciPoint;
extern unsigned char xdata *Seri0_WriteReciPoint;
extern unsigned char data Seri0_ReciNum;
_Delay(unsigned char a){
unsigned int bb;
for(;a>0;a--){
bb=275;
for(;bb>0;bb--);
}
}
/**********************************************************
Function : I2CStart
Description : I2C bus start signal
Input : none
Output : none
***********************************************************/
void I2CStart(void)
{
SDA_HIGH;
SCL_HIGH;
SDA_LOW;
SCL_LOW;
}
/**********************************************************
Function : I2CStop
Description : I2C bus stop signal
Input : none
Output : none
***********************************************************/
void I2CStop(void)
{
SDA_LOW;
SCL_HIGH;
SDA_HIGH;
SCL_LOW;
}
/**********************************************************
Function : WaitAck for check ack
Description : wait I2C slave to respond ack
Input : none
Output : 0 - respond; 1 - no respond
***********************************************************/
unsigned char WaitAck(void)
{
unsigned char bAck;
SDA_HIGH;
SCL_HIGH;
if(SDA==0)
bAck=OK;
else
bAck=NOK;
SCL_LOW;
return bAck;
}
/**********************************************************
Function : SendAck
Description : send ack to I2C slave
Input : none
Output : none
***********************************************************/
void SendAck(void)
{
SDA_LOW;
SCL_HIGH;
SCL_LOW;
SDA_HIGH;
}
/**********************************************************
Function : SendNak
Description : send not ack signal to I2C slave
Input : none
Output : none
***********************************************************/
void SendNak(void)
{
SDA_HIGH;
SCL_HIGH;
SCL_LOW;
SDA_LOW;
}
/**********************************************************
Function : I2CSendByte
Description : send a byte to I2C slave
Input : data - the byte to be sent
Output : none
***********************************************************/
void I2CSendByte(unsigned char bChar)
{
unsigned char i;
for(i=0;i<8;i++)
{
bChar<<=1;
if(CY){SDA_HIGH}
else {SDA_LOW}
SCL_HIGH;
SCL_LOW;
}
}
/**********************************************************
Function : I2CReceiveByte
Description : Receive a byte from I2C slave
Input : none
Output : the byte received
***********************************************************/
unsigned char I2CReceiveByte(void)
{
unsigned char i,bChar;
bChar=0;
SDA=1; //input init
for(i=0;i<8;i++)
{
SCL_HIGH;
bChar<<=1;
if(SDA) bChar++;
SCL_LOW;
}
return bChar;
}
/**/
/*
功能:I2C芯片初始化
输入:none
输出: none
注意:
*/
void vInitI2C(void)
{
WP=0;
SCL_LOW;
SDA_LOW;
}
/*************************************************
功能: 读I2C
输入:
Sla: 芯片地址(A0:EEPROM1;A4:EEPROM2)
Address: 片内首地址
Send_Data: 数据地址
len: 长度(<=128)
输出: 0:正确; 1: 错误
注意:
unsigned char IRcvStr( unsigned char Sla,unsigned int Address ,
unsigned char *RcvData ,unsigned char len)
**************************************************/
unsigned char IRcvStr( unsigned char Sla,unsigned int Address ,
unsigned char *RcvData ,unsigned char len)
{
unsigned char i;
I2CStart();
I2CSendByte(Sla); //SEND DEVICE ADDRESS
if(WaitAck())
goto I2CReadError;
// return (1);
I2CSendByte( (uchar)(Address>>8) ); //SEND ADDRESS HIGH
if(WaitAck())
goto I2CReadError;
// return (2);
I2CSendByte( (uchar)Address ); //SEND ADDRESS LOW
if(WaitAck())
goto I2CReadError;
// return (3);
I2CStart();
Sla|=0x05; //read bit=1 Sla|=0x01
I2CSendByte(Sla); //SEND DEVICE ADDRESS
if(WaitAck())
goto I2CReadError;
// return (4);
for(i=0;i<len;i++)
{
RcvData[i]=I2CReceiveByte(); //SEND DATA
if(i==len-1)
SendNak(); //发送完最后字节,发送NAK
else
SendAck();
}
I2CStop();
return OK;
I2CReadError:
I2CStop();
return NOK;
}
/********************************************************
功能: 页写I2C
输入:
Sla: 芯片地址(A0:EEPROM1;A4:EEPROM2)
Address: 片内首地址
Send_Data: 数据源地址
len: 数据长度(<=128)
输出: 0:正确; 1: 时序错误; 2:写入的数据读出后不对
注意: 不能跨页
*********************************************************/
unsigned char ISendStr( unsigned char Sla,unsigned int Address ,
unsigned char *Send_Data ,unsigned char len )
{
unsigned char i;
WP=0;
I2CStart();
I2CSendByte(Sla); //SEND DEVICE ADDRESS
if(WaitAck())
goto ErrorI2CWrite;
I2CSendByte( (uchar)(Address>>8) ); //SEND ADDRESS HIGH
if(WaitAck())
goto ErrorI2CWrite;
I2CSendByte( (uchar)Address ); //SEND ADDRESS LOW
if(WaitAck())
goto ErrorI2CWrite;
for(i=0;i<len;i++)
{
I2CSendByte(Send_Data[i]); //SEND DATA
if(WaitAck())
goto ErrorI2CWrite;
}
I2CStop();
for(;;) //查询是否写完
{
I2CStart();
I2CSendByte(Sla);
if(!WaitAck())
break;
}
WP=0;
_Delay(10);
/*
for(i=0;i<len;i++)
{
IRcvStr(Sla, Address ,&bI2CReadData ,1); //写后读
Address++;
if( bI2CReadData!=Send_Data[i] )
goto ErrorI2CWrite;
}
*/
_Delay(100);
return OK;// return 0;
ErrorI2CWrite:
I2CStop();
WP=0;
_Delay(100);
return NOK;// return 1;
}
extern union d{
INT16U u16;
INT8U u8[2];
}m2;
#define pageaddr m2.u16
#define pageaddrH m2.u8[0]
#define pageaddrL m2.u8[1]
extern unsigned char tmp;
unsigned char Sla;
/*
(my页)=0页~2047页(0页~0x7FF页)
AT24c512 Device Select Code
-------------------------------------------------------------------------------------
| Device Type Identifier | Chip Enable Address | R/W |
| b7 b6 b5 b4 | b3 b2 b1 | b0 |
-------------------------------------------------------------------------------------
Device Select Code| 1 0 1 0 | 0 E2 E1 | R/W |
-------------------------------------------------------------------------------------
Note: 1. The most significant bit, b7, is sent first.
*/
Set_Sla(){
Sla=(pageaddrH & 0x6);
//if((Sla=0)||(Sla=2))Sla=4;
Sla|=0xA0;
pageaddr<<=7;
}
Pc2eep2pc()
{
pageaddrH=xBuf_0[0];//页号
pageaddrL=xBuf_0[1];
Set_Sla();
tmp=ISendStr( Sla, pageaddr, xBuf_0+2, 128);//写入
//xBuf_0[0]=tmp;
//读eep操作:
//if(tmp!=0){显示"Pc2eep2pc"}
for(tmp=2;tmp<130;tmp++)xBuf_0[tmp]=0;
//Set_Sla();
tmp=IRcvStr(Sla, pageaddr ,xBuf_0+2 ,128); //读出
//xBuf_0[1]=tmp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -