I2C 24CXX驱动程序真正实用 全.docx
- 文档编号:4480216
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:19
- 大小:19.06KB
I2C 24CXX驱动程序真正实用 全.docx
《I2C 24CXX驱动程序真正实用 全.docx》由会员分享,可在线阅读,更多相关《I2C 24CXX驱动程序真正实用 全.docx(19页珍藏版)》请在冰豆网上搜索。
I2C24CXX驱动程序真正实用全
#ifndef_24cXX_H
#define_24cXX_H
/*Includes----------------------------------------------------------------*/
#include"stm32f10x.h"
#include"value.h"
//#include"stdbool.h"
/*Define------------------------------------------------------------------*/
/*EEPROMAddressesdefines*/
//注:
3264的字地址是16位2个字节如果使用32或64请简单修改驱动即可
#defineWC24cXX0x00//器件地址写
#defineRC24cXX0x01//器件地址读
#defineUSE_24C08//使用24C08
#ifdefUSE_24C02
#defineMAXSIZE24cXX256//总容量Bytes//级联时请修改本参数和硬件驱动
#defineBLOCK_SIZE256//块容量Bytes
#defineI2C_PAGESIZE8//8个字节每页
#endif
#ifdefUSE_24C04
#defineMAXSIZE24cXX512//总容量Bytes//级联时请修改本参数和硬件驱动
#defineBLOCK_SIZE256//块容量Bytes
#defineI2C_PAGESIZE16//16个字节每页
#endif
#ifdefUSE_24C08
#defineMAXSIZE24cXX1024//总容量Bytes//级联时请修改本参数和硬件驱动
#defineBLOCK_SIZE256//块容量Bytes
#defineI2C_PAGESIZE16//16个字节每页
/*userdefine*/
#defineYBCV_ADDR_00x0000//定义仪表控制数据结构体的EEPROM存储地址0
#defineYBCV_ADDR_10x0200//定义仪表控制数据结构体的EEPROM存储地址1
#defineEEPROM_VERIFYYB_CTRL_VALE_SIZE//EEPROM仪表通道修正参数存储地址
#endif
#ifdefUSE_24C16
#defineMAXSIZE24cXX2048//总容量Bytes
#defineI2C_PAGESIZE16//16个字节每页
#endif
#ifdefUSE_24C32
#defineMAXSIZE24cXX4096//总容量Bytes//级联时请修改本参数和硬件驱动
#defineBLOCK_SIZE4096//块容量Bytes
#defineI2C_PAGESIZE32//16个字节每页
#endif
#ifdefUSE_24C64
#defineMAXSIZE24cXX8192//总容量Bytes//级联时请修改本参数和硬件驱动
#defineBLOCK_SIZE8192//块容量Bytes
#defineI2C_PAGESIZE32//16个字节每页
#endif
#defineI2CInitI2C_GPIO_Config
#defineSCL(a)if(a)\
GPIO_SetBits(GPIOB,GPIO_Pin_10);\
else\
GPIO_ResetBits(GPIOB,GPIO_Pin_10)
#defineSDA(a)if(a)\
GPIO_SetBits(GPIOB,GPIO_Pin_11);\
else\
GPIO_ResetBits(GPIOB,GPIO_Pin_11)
#defineSCLOGPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)
#defineSDAOGPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)
/*Private------------------------------------------------------------------*/
/*Public-------------------------------------------------------------------*/
/*uintidataucSendBuffer[8]={0x01,0x02,0x04,0x08,
0x10,0x20,0x40,0x80};
uintidataucReceData;
uintidataucReceiveBuffer[8];
//从器件中读出的多字节数据暂存区*/
/*FunctionDeclaration-----------------------------------------------------*/
externboolI2C2_Init(void);//I2C初始化
//externboolI2C_ByteWrite(u8*pBuffer,u8WriteAddr);//向24cXX中写入1个字节
externboolI2C_PageWrite(u8*pBuffer,u8BlockCode,u16WriteAddr,u8n);//24cXX页写(不超过一页)
externboolI2C_BlockWrite(u8*pBlock,u8BlockCode,u16WriteAddr,u16n);//24cXX数据块写(不超过BLOCK_SIZE个字节)
externboolI2C_BufferWrite(u8*pBuffer,u16WriteAddr,u16n);//24cXX数据写(不超过MAXSIZE24cXX个字节)
externboolI2C_BufferRead(u8*pBuffer,u16ReadAddr,u16n);//从24cXX中读出N字节数据(不超过MAXSIZE24cXX个字节)
//externvoidI2C_EE_WaitEepromStandbyState(void);//等待24CXX内部写周期结束
#endif/*_24cXX_H*/
/********************(C)COPYRIGHT2015XXXXX**********************************
*文件名:
24cXX.c
*描述:
本函数是xx项目的24cXX的读写函数
*平台:
Keil4MDK\stm323.5.0库
*库版本:
基于野火相关资料及程序上优化修改
*作者:
天涯月下红颜醉
*时间:
2015.4.19
**********************************************************************************/
/*Includes------------------------------------------------------------------*/
#include"24cXX.h"
#include"value.h"
#include"systick.h"
#include
/*
*函数名:
I2C2_Init
*描述:
I2C2初始化
*输入:
无
*输出:
无
*调用:
内部调用
*/
boolI2C2_Init(void)
{
bools=true;
GPIO_InitTypeDefGPIO_InitStructure;
/*使能与I2CGPIO有关的时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
/*PB10-I2C2_SCL、PB11-I2C2_SDA*/
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;//普通开漏输出
GPIO_Init(GPIOB,&GPIO_InitStructure);
SDA
(1);
SCL
(1);
Delay_nop();
Delay_nop();
if(!
SDAO)s=false;
if(!
SCLO)s=false;
SDA(0);
Delay_nop();
Delay_nop();
if(SDAO)s=false;
SCL(0);
Delay_nop();
SDA(0);
SCL(0);
Delay_nop();
Delay_nop();
if(SDAO)s=false;
if(SCLO)s=false;
SCL
(1);
Delay_nop();
Delay_nop();
SDA
(1);
returns;
}
/********开启24cXX的I2C总线********/
staticboolI2CStart(void)
{
SDA
(1);
SCL
(1);
Delay_nop();
Delay_nop();
if(!
SDAO)returnfalse;//SDA线为低电平则总线忙,退出
SDA(0);
Delay_nop();
Delay_nop();
if(SDAO)returnfalse;//SDA线为高电平则总线出错,退出
SCL(0);
Delay_nop();
returntrue;
}
/********关闭24cXX的I2C总线*******/
staticvoidI2CStop(void)
{
SDA(0);
SCL(0);
Delay_nop();
Delay_nop();
SCL
(1);
Delay_nop();
Delay_nop();
SDA
(1);
}
/*********发送ACK*********/
staticvoidI2CAck(void)
{
SDA(0);
SCL(0);
Delay_nop();
//Delay_nop();
SCL
(1);
Delay_nop();
//Delay_nop();
SCL(0);
}
/*********发送NOACK*********/
staticvoidI2CNoAck(void)
{
SDA
(1);
SCL(0);
Delay_nop();
//Delay_nop();
SCL
(1);
Delay_nop();
//Delay_nop();
SCL(0);
}
/*********读取ACK信号*********/
staticboolI2CWaitAck(void)//返回为:
1=有ACK,0=无ACK
{
SCL(0);
SDA
(1);//设置SDA为输入
Delay_nop();
//Delay_nop();
SCL
(1);
Delay_nop();
//Delay_nop();
if(SDAO)
{
SCL(0);
returnfalse;
}
SCL(0);
returntrue;
}
/************MCU向24cXX发送一个字节数据*************/
staticvoidI2CSendByte(u8demand)//数据从高位到低位//
{
u8i=8;
while(i--)
{
SCL(0);
Delay_nop();
SDA((bool)(demand&0x80));
demand<<=1;
Delay_nop();
//Delay_nop();
SCL
(1);
Delay_nop();
//Delay_nop();
}
SCL(0);
}
/*********MCU从24cXX读入一字节数据*********/
staticu8I2CReceiveByte(void)//数据从高位到低位//
{
u8i=8;
u8ddata=0;
SDA
(1);//设置SDA为输入
while(i--)
{
ddata<<=1;//数据从高位开始读取
SCL(0);
Delay_nop();
//Delay_nop();
SCL
(1);
Delay_nop();//从高位开始ddata|=SDA;ddata<<=1
//Delay_nop();
if(SDAO)
{
ddata|=0x01;
}
}
SCL(0);
returnddata;
}
/*
*函数名:
I2C_EE_WaitEepromStandbyState
*描述:
WaitforEEPROMStandbystate
*输入:
无
*输出:
无
*返回:
无
*调用:
*/
staticvoidI2C_EE_WaitEepromStandbyState(u8BlockCode)
{
inti=50;
do
{
Delay_us(100);
I2CStart();
I2CSendByte(BlockCode|WC24cXX);//发送器件地址写
}while(I2CWaitAck()==0&&i-->0);
I2CStop();
}
/****************向24cXX中写入1个字节****************/
/*staticboolI2C_ByteWrite(u8*pBuffer,u8WriteAddr)
{
I2CStart();//启动I2C
I2CSendByte(WC24cXX);//发送器件地址写
if(I2CWaitAck()==0)
returnfalse;
I2CSendByte(WriteAddr);
if(I2CWaitAck()==0)
returnfalse;
I2CSendByte(*pBuffer);
if(I2CWaitAck()==0)
returnfalse;
I2CStop();
returntrue;
}*/
/*
*函数名:
I2C_PageWrite
*描述:
在EEPROM的一个写循环中可以写多个字节,但一次写入的字节数
*不能超过EEPROM页的大小。
AT24C08每页有16个字节。
*输入:
-pBuffer缓冲区指针
*-BlockCode起始器件地址
*-WriteAddr接收数据的EEPROM的地址
*-n要写入EEPROM的字节数
*返回:
0:
失败1:
成功
*调用:
外部调用
*/
boolI2C_PageWrite(u8*pBuffer,u8BlockCode,u16WriteAddr,u8n)
{
u16i;
if(n>I2C_PAGESIZE-WriteAddr%I2C_PAGESIZE)//paracheck
returnfalse;
if(n==0)
returntrue;
if(I2CStart()==false)
{
Delay_us(100);
if(I2CStart()==false)
returnfalse;
};//启动I2C
I2CSendByte(BlockCode|WC24cXX);//发送器件地址写
if(I2CWaitAck()==0)
returnfalse;
#ifdefined(USE_24C32)
I2CSendByte((u8)(WriteAddr>>8));
#elifdefined(USE_24C64)
I2CSendByte((u8)(WriteAddr>>8));
#endif
I2CSendByte((u8)WriteAddr);
if(I2CWaitAck()==0)
returnfalse;
for(i=0;i { I2CSendByte(pBuffer[i]); if(I2CWaitAck()==0) returnfalse; } I2CStop(); I2C_EE_WaitEepromStandbyState(BlockCode); returntrue; } /* *函数名: I2C_BlockWrite *描述: 将块缓冲区中的数据写到I2CEEPROM中 *输入: -pBuffer块缓冲区指针 *-BlockCode起始器件地址 *-WriteAddr接收数据的EEPROM的地址 *-n要写入EEPROM的字节数 *返回: 0: 失败1: 成功 *调用: 外部调用 */ boolI2C_BlockWrite(u8*pBlock,u8BlockCode,u16WriteAddr,u16n) { u16ByteOf1st=0,ByteOfOther=0;//第一页的字节数最后一页的字节数 u8NumOfMPage=0;//需要写满数据的页数 if(n>BLOCK_SIZE-WriteAddr%BLOCK_SIZE)//paracheck returnfalse; if(n==0) returntrue; ByteOf1st=I2C_PAGESIZE-WriteAddr%I2C_PAGESIZE; if(n>ByteOf1st) { NumOfMPage=(n-ByteOf1st)/I2C_PAGESIZE; ByteOfOther=(n-ByteOf1st)%I2C_PAGESIZE; } else { ByteOf1st=n; NumOfMPage=0; ByteOfOther=0; } if(I2C_PageWrite(pBlock,BlockCode,WriteAddr,ByteOf1st)==false) { returnfalse; } WriteAddr+=ByteOf1st; pBlock+=ByteOf1st; while(NumOfMPage--) { if(I2C_PageWrite(pBlock,BlockCode,WriteAddr,I2C_PAGESIZE)==false) { returnfalse; } WriteAddr+=I2C_PAGESIZE; pBlock+=I2C_PAGESIZE; } if(I2C_PageWrite(pBlock,BlockCode,WriteAddr,ByteOfOther)==false) { returnfalse; } returntrue; } /* *函数名: I2C_BufferWrite *描述: 将缓冲区中的数据写到I2CEEPROM中 *输入: -pBuffer缓冲区指针 *-WriteAddr接收数据的EEPROM的地址 *-n要写入EEPROM的字节数 *返回: 0: 失败1: 成功 *调用: 外部调用 */ boolI2C_BufferWrite(u8*pBuffer,u16WriteAddr,u16n) { u16ByteOf1st=0,ByteOfOther=0;//第一块的字节数最后一块的字节数 u8NumOfMBlock=0;//需要写满数据的块 constu16ReadAddr=WriteAddr;//读地址 u8*pstr=pBuffer; u8BlockCode=0;//起始器件地址 u8*pReadBuff=NULL; u16i=0; if(n+WriteAddr>MAXSIZE24cXX||n+WriteAddr==0)//paracheck returnfalse; ByteOf1st=BLOCK_SIZE-WriteAddr%BLOCK_SIZE; if(n>ByteOf1st) { NumOfMBlock=(n-ByteOf1st)/BLOCK_SIZE; ByteOfOther=(n-ByteOf1st)%BLOCK_SIZE; } else { ByteOf1st=n; NumOfMBlock=0; ByteOfOther=0; } __close_interrupt();//关总中断 BlockCode=(u8)((WriteAddr/BLOCK_SIZE<<1)|0xA0); if(I2C_BlockWrite(pstr,BlockCode,WriteAddr,ByteOf1st)=
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- I2C 24CXX驱动程序真正实用 24 CXX 驱动程序 真正 实用
![提示](https://static.bdocx.com/images/bang_tan.gif)