📄 fm24c16驱动.c
字号:
/**********************************************************************************
(1) void StartIIC(void) 作者:李伟东 日期:2004.10.9
(2) 函数功能:启动IIC总线
(3) 入口参数:void
(4) 出口参数:void
(5) 修改的外部变量(全局变量) 说明
(6) 修改人 修改日期
(7) 修改内容
*********************************************************************************/
void StartIIC(void)
{
SCL = 1;//将时钟线置高
_nop_();_nop_();//稳定时间2uS
SDA = 1;//将数据线置高
_nop_();_nop_();//稳定时间2uS
SDA = 0;//将数据线置低
_nop_();_nop_();_nop_();_nop_();//启动时间4uS
SCL = 0;//将时钟线置低
_nop_();_nop_();//稳定时间2uS
}
/**********************************************************************************
(1) void StopIIC(void) 作者:李伟东 日期:2004.10.9
(2) 函数功能:停止IIC总线
(3) 入口参数:void
(4) 出口参数:void
(5) 修改的外部变量(全局变量) 说明
(6) 修改人 修改日期
(7) 修改内容
*********************************************************************************/
void StopIIC(void)
{
data unsigned char i;
SCL = 0;//将时钟线置低
_nop_();_nop_();//稳定时间2uS
SDA = 0;//将数据线置低
_nop_();_nop_();//稳定时间2uS
SCL = 1;//将时钟线置高
_nop_();_nop_();_nop_();_nop_();//启动时间4uS
SDA = 1;//将数据线置高
for(i=0;i<30;i++)
_nop_();//停止总线60uS
}
/**********************************************************************************
(1) void AckIIC(bit bAckFlag) 作者:李伟东 日期:2004.10.9
(2) 函数功能:主控器应答信号
(3) 入口参数:bAckFlag=0-ACK,bAckFlag=1-NACK.
(4) 出口参数:void
(5) 修改的外部变量(全局变量) 说明
(6) 修改人 修改日期
(7) 修改内容
*********************************************************************************/
void AckIIC(bit bAckFlag)
{
SDA = bAckFlag;
_nop_();//稳定时间1uS
SCL =1;//时钟置高
_nop_();_nop_();_nop_();//稳定时间3uS
SCL =0;//时钟置低
_nop_();//稳定时间1uS
SDA = 1;//将数据线置高
}
/**********************************************************************************
(1) unsigned char SendOneByte(unsinged char ucByte) 作者:李伟东 日期:2004.10.9
(2) 函数功能:IIC总线发送一个字节
(3) 入口参数:要写的字节ucByte.
(4) 出口参数:ACK-return 0,NACK-return 1.
(5) 修改的外部变量(全局变量) 说明
(6) 修改人 修改日期
(7) 修改内容
*********************************************************************************/
unsigned char SendOneByte(unsigned char ucSendByte)
{
unsigned char ucBitCount;
unsigned char ucReturnByte;
for(ucBitCount=0; ucBitCount<8; ucBitCount++)
{
if(ucSendByte&0x80) SDA = 1;//数据位为高
else SDA = 0;//数据位为低
do
{
_nop_();//稳定时间1uS
SCL = 1;//时钟置高
_nop_();//稳定时间1uS
}
while(!SCL);//时钟信号被钳位
//_nop_();_nop_();//稳定时间2uS
SCL = 0;//时钟置低
//_nop_();//稳定时间1uS
ucSendByte <<= 1;//发送字节左移一位
}
SDA = 1;//数据线置高,准备检测应答信号
_nop_();//稳定时间1uS
SCL = 1;//时钟置高
_nop_();_nop_();//稳定时间2uS
if(SDA) ucReturnByte = 0x01;
else ucReturnByte = 0x00;
SCL = 0;//时钟置低
_nop_();_nop_();//稳定时间2uS
return (ucReturnByte);
}
/**********************************************************************************
(1) unsigned char ReceiveOneByte(void) 作者:李伟东 日期:2004.10.9
(2) 函数功能:IIC总线接收一个字节
(3) 入口参数:void
(4) 出口参数:接收到的字节
(5) 修改的外部变量(全局变量) 说明
(6) 修改人 修改日期
(7) 修改内容
*********************************************************************************/
unsigned char ReceiveOneByte(void)
{
unsigned char ucBitCount;
unsigned char ucReceiveByte;
SDA = 1;//置数据线为输入方式
for(ucBitCount=0; ucBitCount<8; ucBitCount++)
{
SCL = 0;//时钟置低
_nop_();//稳定时间1uS
SCL = 1;//时钟置高
_nop_();//稳定时间1uS
ucReceiveByte <<= 1;//左移一位,LSB=0.
if(SDA) ucReceiveByte += 1;//如果SDA=1,LSB=1.
}
SCL = 0;//时钟置低
return(ucReceiveByte);
}
//=================================================================================
//(1) 函数名:write_eeprom 作者:李伟东 创建日期:2005.3.7
//(2)函数功能:写eeprom
//(3)入口参数:uiAddress:开始地址,uiDataLen:要写的字节个数,pucDataBuff:数据指针
//(4)出口参数:成功:return 0,失败:return 1;
//(5)影响全局说明:关中断
//(6)修改人 修改日期
//(7)修改内容
//================================================================================
unsigned char write_eeprom(unsigned int uiAddress,unsigned int uiDataLen,unsigned char * pucDataBuff)
{
unsigned char ucPageAddress;//页地址
unsigned char ucWordAddress;//字地址
unsigned int data uiCount;
unsigned char pucBuffer[64];
bit EAFlag;
if(uiDataLen==0) return 0;
EAFlag = EA;
EA = 0;
ucPageAddress = uiAddress/256;
ucWordAddress = uiAddress%256;
ucPageAddress <<= 1;
ucPageAddress |= FM24C16_WRITE;
StartIIC();//启动总线
SendOneByte(ucPageAddress);//发送页地址
SendOneByte(ucWordAddress);//发送字地址
for(uiCount=0;uiCount<uiDataLen;uiCount++)
{
SendOneByte(pucDataBuff[uiCount]);//发送数据
}
StopIIC();//停止总线
while(1)
{//写完后读出来刚写过的数据比较,看有没有写出错
if(uiDataLen>64)
{
read_eeprom(uiAddress,64,pucBuffer);
if(memcmp(pucDataBuff,pucBuffer,64))
{
EA = EAFlag;
return 1;
}
uiAddress += 64;
pucDataBuff += 64;
uiDataLen -= 64;
}
else
{
read_eeprom(uiAddress,uiDataLen,pucBuffer);
if(memcmp(pucDataBuff,pucBuffer,uiDataLen))
{
EA = EAFlag;
return 1;
}
break;
}
}
EA = EAFlag;
return 0;
}
//=================================================================================
//(1) 函数名:read_eeprom 作者:李伟东 创建日期:2005.3.7
//(2)函数功能:读eeprom
//(3)入口参数:uiAddress:开始地址,uiDataLen:要读的字节个数,pucDataBuff:数据指针
//(4)出口参数:成功:return 0,失败:return 1;
//(5)影响全局说明:关中断
//(6)修改人 修改日期
//(7)修改内容
//================================================================================
unsigned char read_eeprom(unsigned int uiAddress,unsigned int uiDataLen,unsigned char * pucDataBuff)
{
unsigned char ucPageAddress;//页地址
unsigned char ucWordAddress;//字地址
unsigned char ucSendByte;
unsigned int uiCount;
bit EAFlag;
if(uiDataLen==0) return 0;
EAFlag = EA;
EA = 0;
ucPageAddress = uiAddress/256;
ucWordAddress = uiAddress%256;
ucPageAddress <<= 1;
ucSendByte = ucPageAddress | FM24C16_WRITE;
StartIIC();//启动总线
SendOneByte(ucSendByte);//发送页地址
SendOneByte(ucWordAddress);//发送字地址
ucSendByte = ucPageAddress | FM24C16_READ;
StartIIC();//启动总线
if(SendOneByte(ucSendByte))//发送读命令
return 1;
for(uiCount=0;uiCount<uiDataLen;uiCount++)
{
*pucDataBuff = ReceiveOneByte();//接收数据
pucDataBuff ++;
if(uiCount==(uiDataLen-1))
AckIIC(1);//非应答
else AckIIC(0);//应答
}
StopIIC();//停止总线
EA = EAFlag;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -