📄 inout.c
字号:
{
unsigned int addr;
unsigned char w_wait;
v_IntRunFlag = c_FMSet;
safeCheck();
addr = EEPROMAddr;
reStart:
GIE = 0; //关闭中断
_FMWP = 0; //使能写入
for(w_wait=0; w_wait<64; w_wait++)
{
I2CStart();
if(_TRUE == I2CByteTX(0xa0)) //发送器件地址
{
break;
}
I2CStop();
Delay1msx(1);
}
if(w_wait >= 64)
{
_FMWP = 1;
GIE = 1;
return _FALSE;
}
if(_FALSE == I2CByteTX((unsigned char)(addr/0x100)))//发送逻辑地址,高字节
{
_FMWP = 1;
GIE = 1; //中断
return _FALSE;
}
if(_FALSE == I2CByteTX((unsigned char)(addr))) //发送逻辑地址,低字节
{
_FMWP = 1;
GIE = 1; //中断
return _FALSE;
}
//发送数据
while(n--)
{
ClrWdt();
if(_FALSE == I2CByteTX(data))
{
_FMWP = 1;
GIE = 1; //中断
return _FALSE;
}
addr++; //地址标志+1,判断是否跨越边界
if((addr%c_eepage) == 0)
{
break; //结束本次写入循环,跨页处理
}
}
//停止位
I2CStop();
GIE = 1; //中断
if(n != 0xff)
{
goto reStart;
}
_FMWP = 1;
return _TRUE;
}
//从EEPROM(MC24LC256)中读取一串数放入内存中
//////////////////////////////////////////
// get string from external rom
//////////////////////////////////////////
unsigned char
getStrFM(bank2 unsigned char *dec, unsigned int EEPROMAddr, unsigned char n)
{
//_EEPROMWP = 1; //禁止写入
GIE = 0; //关闭中断
I2CStart();
if(_FALSE == I2CByteTX(0xA0)) //发送器件地址
//24LC256的器件地址是0xA0(A0,A1,A2都为0的情况)
{
GIE = 1; //中断
return _FALSE;
}
if(_FALSE == I2CByteTX((unsigned char)(EEPROMAddr/0x100))) //发送逻辑地址,高字节
{
GIE = 1; //中断
return _FALSE;
}
if(_FALSE == I2CByteTX((unsigned char)(EEPROMAddr))) //发送逻辑地址,低字节
{
GIE = 1; //中断
return _FALSE;
}
I2CStart();
if(_FALSE == I2CByteTX(0xA0 | 0b00000001)) //发送器件地址
{
GIE = 1; //中断
return _FALSE;
}
while(n--)
{
ClrWdt();
*dec++ = I2CByteRX();
if(n != 0)
{
I2CACK();
}
}
I2CNOACK();
I2CStop();
GIE = 1; //中断
return _TRUE;
}
unsigned char
getStrFMlow(unsigned char *dec, unsigned int EEPROMAddr, unsigned char n)
{
//_EEPROMWP = 1; //禁止写入
GIE = 0; //关闭中断
I2CStart();
if(_FALSE == I2CByteTX(0xA0)) //发送器件地址
//24LC256的器件地址是0xA0(A0,A1,A2都为0的情况)
{
GIE = 1; //中断
return _FALSE;
}
if(_FALSE == I2CByteTX((unsigned char)(EEPROMAddr/0x100))) //发送逻辑地址,高字节
{
GIE = 1; //中断
return _FALSE;
}
if(_FALSE == I2CByteTX((unsigned char)(EEPROMAddr))) //发送逻辑地址,低字节
{
GIE = 1; //中断
return _FALSE;
}
I2CStart();
if(_FALSE == I2CByteTX(0xA0 | 0b00000001)) //发送器件地址
{
GIE = 1; //中断
return _FALSE;
}
while(n--)
{
ClrWdt();
*dec++ = I2CByteRX();
if(n != 0)
{
I2CACK();
}
}
I2CNOACK();
I2CStop();
GIE = 1; //中断
return _TRUE;
}
///////////////////////////////////////
// 对外部EEPROM的
// I2C byte tx
// 要求入口SCL = 0
// 先发送高位 ___
// SCL__/ \__/...\_
// 程序出口SCL = 0
///////////////////////////////////////
unsigned char I2CByteTX(unsigned char byte)
{
unsigned char loop;
loop = 8;
_TRISFMSDA = 0;
while(loop--)
{
if(byte & 0b10000000) //获取高位状态
{
_FMSDA = 1;
}
else
{
_FMSDA = 0;
}
I2CDelay();
_FMSCL = 1;
I2CDelay();
_FMSCL = 0;
byte <<= 1;
//I2CDelay();
};
//等待ACK
_TRISFMSDA = 1; //输入态
_FMSCL = 1;
I2CDelay();
if(_FMSDA == 1)
{
_FMSCL = 1;
return _FALSE;
}
_FMSCL = 0;
I2CDelay();
return _TRUE;
}
///////////////////////////////////////
//I2C byte rx
///////////////////////////////////////
unsigned char I2CByteRX(void)
{
unsigned char byte;
unsigned char loop;
loop = 8;
_TRISFMSDA = 1;
do
{
byte <<= 1; //最低位被置零
_FMSCL = 1;
I2CDelay();
if(_FMSDA == 1)
{
byte |= 0b00000001;
}
_FMSCL = 0;
I2CDelay();
loop--;
} while(loop > 0);
return byte;
}
///////////////////////////////////////
// ______
// Send start bit FMSDA >4us \_____
// ___________
// SCL \__
///////////////////////////////////////
void I2CStart(void)
{
_FMSCL = 1;
_FMSDA = 1; //先设电平,再设输入输出状态,
_TRISFMSDA = 0;
I2CDelay();
_FMSDA = 0;
I2CDelay();
_FMSCL = 0;
//I2CDelay();
}
///////////////////////////////////////
//I2C stop
// ____
// FMSDA _______/
// ____________
// SCL
///////////////////////////////////////
void I2CStop(void)
{
_TRISFMSDA = 0;
_FMSDA = 0;
I2CDelay();
_FMSCL = 1;
I2CDelay();
//_FMSDA = 1;
_TRISFMSDA = 1;
I2CDelay();
_TRISFMSDA = 1; //把FMSDA引脚置为输入态
}
///////////////////////////////////////
//////////byte acknowledge
// FMSDA _______
// __
// SCL _/ \_
///////////////////////////////////////
void I2CACK(void)
{
_TRISFMSDA = 0;
_FMSDA = 0;
I2CDelay();
_FMSCL = 1;
I2CDelay();
_FMSCL = 0;
I2CDelay();
}
///////////////////////////////////////
// byte no acknowledge
// ______
// FMSDA
// __
// SCL _/ \_
///////////////////////////////////////
void I2CNOACK(void)
{
_TRISFMSDA = 0;
_FMSDA = 1;
I2CDelay();
_FMSCL = 1;
I2CDelay();
_FMSCL = 0;
I2CDelay();
}
/////////////delay 400k//////////
void I2CDelay(void)
{
Nop();
Nop();
Nop();
Nop();
}
/*************************************
* 时钟相关操作
* 时钟芯片 RX8025
* 地址有区别,在高四位(0~F)
* 因为8025两次操作之间不能小于500ms延时,所以特殊处理
* 软件时钟秒不为零,直接写入
* 为零主循环中判断后再写入
* put string to RX8025
***************************************/
unsigned char
putStrRTC(unsigned char Addr, bank2 unsigned char *src, unsigned char n)
{
v_IntRunFlag = c_putStrRTC;
safeCheck();
v_ssCont = 59; //保证修改时钟,可以马上刷新时间参数
GIE = 0; //关闭中断
RTCStart();
if(_FALSE == RTCByteTX(c_RTCSlaveAddr & 0b11111110)) //发送器件地址,bit0 = 0是写
{
GIE = 1; //使能中断
return _FALSE;
}
if(_FALSE == RTCByteTX(Addr<<4)) //发送逻辑地址
{
GIE = 1; //使能中断
return _FALSE;
}
//发送数据
while(n--)
{
ClrWdt();
if(_FALSE == RTCByteTX(*src++))
{
GIE = 1; //使能中断
return _FALSE;
}
}
//停止位
RTCStop();
GIE = 1; //使能中断
return _TRUE;
}
unsigned char
putStrRTClow(unsigned char Addr, unsigned char *src, unsigned char n)
{
v_IntRunFlag = c_putStrRTC;
safeCheck();
v_ssCont = 59; //保证修改时钟,可以马上刷新时间参数
GIE = 0; //关闭中断
RTCStart();
if(_FALSE == RTCByteTX(c_RTCSlaveAddr & 0b11111110)) //发送器件地址,bit0 = 0是写
{
GIE = 1; //使能中断
return _FALSE;
}
if(_FALSE == RTCByteTX(Addr<<4)) //发送逻辑地址
{
GIE = 1; //使能中断
return _FALSE;
}
//发送数据
while(n--)
{
ClrWdt();
if(_FALSE == RTCByteTX(*src++))
{
GIE = 1; //使能中断
return _FALSE;
}
}
//停止位
RTCStop();
GIE = 1; //使能中断
return _TRUE;
}
///////////////////////////////////////
// get string from RX8025
// 固定读取模式,从0x0f开始,顺序读取
// 例如:地址0x01 的数据应该是第3个字节,第一个是0x0f,第二个是0x00
///////////////////////////////////////
unsigned char
getStrRTC(bank2 unsigned char *dec, unsigned char Addr, unsigned char n)
{
unsigned char len; //计数扔掉几字节
RTCStart();
if(_FALSE == RTCByteTX(c_RTCSlaveAddr)) //发送器件地址,默认就是读取
{
return _FALSE;
}
len = Addr + 1; //地址Addr前有Addr+1个无效字节
while(len--)
{
RTCByteRX(); //只读不存
RTCACK();
}
while(n--)
{
*dec++ = RTCByteRX(); //有效数据
if(n!=0)
{
RTCACK();
}
}
RTCNOACK();
RTCStop();
return _TRUE;
}
unsigned char
getStrRTClow(unsigned char *dec, unsigned char Addr, unsigned char n)
{
unsigned char len; //计数扔掉几字节
RTCStart();
if(_FALSE == RTCByteTX(c_RTCSlaveAddr)) //发送器件地址,默认就是读取
{
return _FALSE;
}
len = Addr + 1; //地址Addr前有Addr+1个无效字节
while(len--)
{
RTCByteRX(); //只读不存
RTCACK();
}
while(n--)
{
*dec++ = RTCByteRX(); //有效数据
if(n!=0)
{
RTCACK();
}
}
RTCNOACK();
RTCStop();
return _TRUE;
}
///////////////////////////////////////
// I2C byte tx
// 要求入口SCL = 0
// 先发送高位 __
// SCL__/ \__/...\_
// 程序出口SCL = 0
///////////////////////////////////////
unsigned char RTCByteTX(unsigned char byte)
{
unsigned char loop;
loop = 8;
_RTCTRISSDA = 0;
_RTCTRISSCL = 0;
do
{
if(byte & 0b10000000) //获取高位状态
{
_RTCFMSDA = 1;
}
else
{
_RTCFMSDA = 0;
}
I2CDelay();
_RTCSCL = 1;
I2CDelay();
_RTCSCL = 0;
byte <<= 1;
I2CDelay();
loop--;
} while(loop > 0);
//等待ACK
_RTCSCL = 1;
_RTCTRISSDA = 1; //输入态
I2CDelay();
if(_RTCFMSDA == 1)
{
_RTCSCL = 1;
return _FALSE;
}
_RTCSCL = 0;
I2CDelay();
return _TRUE;
}
/////////////////////////////////////
//I2C byte rx
/////////////////////////////////////
unsigned char RTCByteRX(void)
{
unsigned char byte;
unsigned char loop;
loop = 8;
_RTCTRISSDA = 1;
_RTCTRISSCL = 0;
do
{
byte <<= 1;
I2CDelay();
_RTCSCL = 1;
I2CDelay();
if(_RTCFMSDA == 1)
{
byte |= 0b00000001;
}
_RTCSCL = 0;
loop--;
} while(loop > 0);
I2CDelay();
return byte;
}
///////////////////////////////////////
// ______
// Send start bit RTCFMSDA >4us \_____
// ___________
// RTCSCL \__
///////////////////////////////////////
void RTCStart(void)
{
_RTCTRISSDA = 0;
_RTCTRISSCL = 0;
_RTCSCL = 1;
_RTCFMSDA = 1;
I2CDelay();
_RTCFMSDA = 0;
I2CDelay();
_RTCSCL = 0;
I2CDelay();
}
///////////////////////////////////////
//RTC stop
// ____
// RTCFMSDA _______/
// ____________
// RTCSCL
///////////////////////////////////////
void RTCStop(void)
{
_RTCTRISSDA = 0;
_RTCTRISSCL = 0;
_RTCSCL = 1;
_RTCFMSDA = 0;
I2CDelay();
_RTCFMSDA = 1;
I2CDelay();
_RTCTRISSDA = 1; //把FMSDA引脚置为输入态
}
///////////////////////////////////////
//////////// byte acknowledge
// FMSDA _______
// __
// SCL _/ \_
///////////////////////////////////////
void RTCACK(void)
{
_RTCTRISSDA = 0;
_RTCTRISSCL = 0;
_RTCFMSDA = 0;
I2CDelay();
_RTCSCL = 1;
I2CDelay();
_RTCSCL = 0;
I2CDelay();
}
///////////////////////////////////////
//////////byte acknowledge
// FMSDA _______
// __
// SCL _/ \_
///////////////////////////////////////
void RTCNOACK(void)
{
_RTCTRISSDA = 0;
_RTCTRISSCL = 0;
_RTCFMSDA = 1;
I2CDelay();
_RTCSCL = 1;
I2CDelay();
_RTCSCL = 0;
I2CDelay();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -