📄 24c02srtest.bak
字号:
/*** 引用yajou整理的I2C万能驱动程序 **************************************/
/*** 整理:yajou 2008-02-28 || http://hi.baidu.com/yajou/ ****************/
/*-------------------------------------------------------------------------*/
#include "reg51.h"
#include "intrins.h"
#include "24C02SRTest.h"
/********************************************************
* Main *
********************************************************/
main(void)
{
uint i;
uchar j;
SDA = 1;
SCL = 1;
// data_shengyu = 12345678;
// data_leiji = 87654321;
// data_zongji = 99999999;
// data_baojing = 3058;
// data_guanfa = 30;
// data_ciganrao= 8;
// data_kaigai = 5;
if(ReadAllData()) //从AT24C02读出数据
{
data_shengyu = 111;
}
data_shengyu = data_shengyu - 1;
data_leiji = data_leiji + 1;
data_zongji = data_shengyu +data_leiji;
data_baojing = data_baojing + 1;
data_guanfa = data_guanfa + 1;
data_ciganrao= data_ciganrao + 1;
data_kaigai = data_kaigai + 1;
if(SaveAllData()) //写入数据到AT24C02
{
data_shengyu = 222;
}
temp1 = data_shengyu;
datasw();
while(1)
{
i++;
if(i > 100)
{
i = 0;
j++;
if(j == 7) j = 0;
switch(j)
{
case 0:{temp1 = data_shengyu;break;}
case 1:{temp1 = data_leiji;break;}
case 2:{temp1 = data_zongji;break;}
case 3:{temp1 = data_baojing;break;}
case 4:{temp1 = data_guanfa;break;}
case 5:{temp1 = data_ciganrao;break;}
case 6:{temp1 = data_kaigai;break;}
default:{temp1 = data_shengyu;break;}
}
datasw();
}
ledplay();
}
}
/********************************************************
* 读取剩余量、运行参数、各报警标志及数据校验 *
********************************************************/
bit ReadAllData(void)
{
uchar *ptr_ulint;
ulint temp=0;
uint data_crc1=0,data_crc2=0;
ptr_ulint = &temp; //其实只要取该变量的首地址
if(ReadData_ulint(ptr_ulint,0x00,4)) //剩余量
{
return 1;
}
data_shengyu = temp;
data_crc1 = CalCRC_ulint(ptr_ulint,4);
if(ReadData_ulint(ptr_ulint,0x04,4))
{
return 1;
}
data_crc2 = temp;
if(data_crc1 != data_crc2)
{
return 1;
}
if(ReadData_ulint(ptr_ulint,0x08,4)) //累计量
{
return 1;
}
data_leiji = temp;
data_crc1 = CalCRC_ulint(ptr_ulint,4);
if(ReadData_ulint(ptr_ulint,0x0c,4))
{
return 1;
}
data_crc2 = temp;
if(data_crc1 != data_crc2)
{
return 1;
}
if(ReadData_ulint(ptr_ulint,0x10,4)) //总计量
{
return 1;
}
data_zongji = temp;
data_crc1 = CalCRC_ulint(ptr_ulint,4);
if(ReadData_ulint(ptr_ulint,0x14,4))
{
return 1;
}
data_crc2 = temp;
if(data_crc1 != data_crc2)
{
return 1;
}
if(ReadData_ulint(ptr_ulint,0x20,4)) //报警量
{
return 1;
}
data_baojing = temp;
data_crc1 = CalCRC_ulint(ptr_ulint,4);
if(ReadData_ulint(ptr_ulint,0x24,4))
{
return 1;
}
data_crc2 = temp;
if(data_crc1 != data_crc2)
{
return 1;
}
if(ReadData_ulint(ptr_ulint,0x28,4)) //关阀量
{
return 1;
}
data_guanfa = temp;
data_crc1 = CalCRC_ulint(ptr_ulint,4);
if(ReadData_ulint(ptr_ulint,0x2c,4))
{
return 1;
}
data_crc2 = temp;
if(data_crc1 != data_crc2)
{
return 1;
}
if(ReadData_ulint(ptr_ulint,0x30,4)) //磁扰数
{
return 1;
}
data_ciganrao = temp;
data_crc1 = CalCRC_ulint(ptr_ulint,4);
if(ReadData_ulint(ptr_ulint,0x34,4))
{
return 1;
}
data_crc2 = temp;
if(data_crc1 != data_crc2)
{
return 1;
}
if(ReadData_ulint(ptr_ulint,0x38,4)) //开盖次数
{
return 1;
}
data_kaigai = temp;
data_crc1 = CalCRC_ulint(ptr_ulint,4);
if(ReadData_ulint(ptr_ulint,0x3c,4))
{
return 1;
}
data_crc2 = temp;
if(data_crc1 != data_crc2)
{
return 1;
}
return(0);
}
/********************************************************
* 保存计量数据 *
********************************************************/
bit SaveJiliangData(void)
{
uchar *ptr_ulint;
ulint temp;
ptr_ulint = &temp; //其实只要取该变量的首地址
temp = data_shengyu; //剩余量
if(WriteData_ulint(ptr_ulint,0x00,4))
{
return 1;
}
temp = CalCRC_ulint(ptr_ulint,4);
if(WriteData_ulint(ptr_ulint,0x04,4))
{
return 1;
}
temp = data_leiji; //累计量
if(WriteData_ulint(ptr_ulint,0x08,4))
{
return 1;
}
temp = CalCRC_ulint(ptr_ulint,4);
if(WriteData_ulint(ptr_ulint,0x0c,4))
{
return 1;
}
temp = data_zongji; //总计量
if(WriteData_ulint(ptr_ulint,0x10,4))
{
return 1;
}
temp = CalCRC_ulint(ptr_ulint,4);
if(WriteData_ulint(ptr_ulint,0x14,4))
{
return 1;
}
return(0);
}
/********************************************************
* 保存所有数据 *
********************************************************/
bit SaveAllData(void)
{
uchar *ptr_ulint;
ulint temp;
ptr_ulint = &temp; //其实只要取该变量的首地址
temp = data_shengyu; //剩余量
if(WriteData_ulint(ptr_ulint,0x00,4))
{
return 1;
}
temp = CalCRC_ulint(ptr_ulint,4);
if(WriteData_ulint(ptr_ulint,0x04,4))
{
return 1;
}
temp = data_leiji; //累计量
if(WriteData_ulint(ptr_ulint,0x08,4))
{
return 1;
}
temp = CalCRC_ulint(ptr_ulint,4);
if(WriteData_ulint(ptr_ulint,0x0c,4))
{
return 1;
}
temp = data_zongji; //总计量
if(WriteData_ulint(ptr_ulint,0x10,4))
{
return 1;
}
temp = CalCRC_ulint(ptr_ulint,4);
if(WriteData_ulint(ptr_ulint,0x14,4))
{
return 1;
}
temp = data_baojing; //报警量
if(WriteData_ulint(ptr_ulint,0x20,4))
{
return 1;
}
temp = CalCRC_ulint(ptr_ulint,4);
if(WriteData_ulint(ptr_ulint,0x24,4))
{
return 1;
}
temp = data_guanfa; //关阀量
if(WriteData_ulint(ptr_ulint,0x28,4))
{
return 1;
}
temp = CalCRC_ulint(ptr_ulint,4);
if(WriteData_ulint(ptr_ulint,0x2c,4))
{
return 1;
}
temp = data_ciganrao; //磁扰数
if(WriteData_ulint(ptr_ulint,0x30,4))
{
return 1;
}
temp = CalCRC_ulint(ptr_ulint,4);
if(WriteData_ulint(ptr_ulint,0x34,4))
{
return 1;
}
temp = data_kaigai; //开盖次数
if(WriteData_ulint(ptr_ulint,0x38,4))
{
return 1;
}
temp = CalCRC_ulint(ptr_ulint,4);
if(WriteData_ulint(ptr_ulint,0x3c,4))
{
return 1;
}
return 0;
}
/********************************************************
* 延时函数 *
********************************************************/
void Delayms(uchar ms)
{
uchar k;
while(ms--)
{
for(k = 0; k < 120; k++);
}
}
/********************************************************
* 短延时 *
********************************************************/
void Delaynop(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/********************************************************
* 开始 *
********************************************************/
void Start(void)
{
SCL = 0;
Delaynop();
SDA = 1;
Delaynop();
SCL = 1;
Delaynop();
SDA = 0;
Delaynop();
SCL = 0;
Delaynop();
}
/********************************************************
* 停止 *
********************************************************/
void Stop(void)
{
SCL = 0;
Delaynop();
SDA = 0;
Delaynop();
SCL = 1;
Delaynop();
SDA = 1;
Delaynop();
}
/********************************************************
* 接收器应答 == *
********************************************************/
void Ack(void) //读数据时接收器应答
{
SDA = 0; //8bit后生成应答信号
SCL = 1;
Delaynop();
SCL = 0;
SDA = 1; //释放SDA
}
/********************************************************
* 接收器不应答 == *
********************************************************/
void NoAck(void) //读数据最后接收器不进行确认应答
{
SDA = 1;
SCL = 1;
Delaynop();
SCL = 0;
}
/********************************************************
* 写8Bit *
********************************************************/
bit Write8Bit(unsigned char input)
{
unsigned char temp;
bit ErrorBit = 1;
uchar i = 255; //因故障超时255
for(temp = 8;temp != 0;temp--)
{
SDA = (bit)(input&0x80);
Delaynop();
SCL = 1;
Delaynop();
SCL = 0;
Delaynop();
input = input<<1;
}
SDA = 1;
Delaynop();
SCL = 1;
while(i > 0 & ErrorBit) //等待从器件应答,超时返回错误
{
ErrorBit = SDA;
i--;
}
SCL = 0;
Delaynop();
return(ErrorBit);
}
/********************************************************
* 写数据ulint *
********************************************************/
bit WriteData_ulint(uchar *Wdata,unsigned char RomAddress,unsigned char number)
{
Start();
if(Write8Bit(OP_Write)) //判断写操作是否写成功
{
Stop();
return 1;
}
if(Write8Bit(RomAddress))
{
Stop();
return 1;
}
for(;number != 0;number--)
{
if(Write8Bit(*Wdata))
{
Stop();
return 1;
}
Wdata++;
}
Stop();
Delayms(10); //24Cxx系列写周期限制要求10ms
return 0; //返回值为0表示本次操作成功,1操作失败
}
/********************************************************
* 读8Bit *
********************************************************/
unsigned char Read8Bit(void)
{
unsigned char temp,rbyte=0;
for(temp = 8;temp != 0;temp--)
{
SCL = 1;
rbyte = rbyte << 1;
rbyte = rbyte|((unsigned char)(SDA));
SCL = 0;
Delaynop();
}
return(rbyte);
}
/********************************************************
* 读数据ulint *
********************************************************/
bit ReadData_ulint(uchar *RamAddress,unsigned char RomAddress,unsigned char bytes)
{
Start();
if(Write8Bit(OP_Write)) //判断写操作是否写成功
{
Stop();
return 1;
}
if(Write8Bit(RomAddress))
{
Stop();
return 1;
}
Start();
if(Write8Bit(OP_Read))
{
Stop();
return 1;
}
while(bytes != 1)
{
*RamAddress = Read8Bit();
Ack(); //应答
RamAddress++;
bytes--;
}
*RamAddress = Read8Bit();
NoAck(); //不应答
Stop();
return 0;
}
/**********************************************************
数据转换函数
**********************************************************/
void datasw()
{
display[7]=temp1/10000000;
temp1=temp1%10000000;
display[6]=temp1/1000000;
temp1=temp1%1000000;
display[5]=temp1/100000;
temp1=temp1%100000;
display[4]=temp1/10000;
temp1=temp1%10000;
display[3]=temp1/1000;
temp1=temp1%1000;
display[2]=temp1/100;
temp1=temp1%100;
display[1]=temp1/10;
display[0]=temp1%10;
}
/**********************************************************
数据显示函数
**********************************************************/
void ledplay()
{
P0 = ledcode[display[0]]; //显示
P2 = 0x7f;
Delayms(2);
P0 = ledcode[display[1]]; //显示
P2 = 0xbf;
Delayms(2);
P0 = ledcode[display[2]] ; //显示小数位
P2 = 0xdf;
Delayms(2);
P0 = ledcode[display[3]]; //显示
P2 = 0xef;
Delayms(2);
P0 = ledcode[display[4]]; //显示
P2 = 0xf7;
Delayms(2);
P0 = ledcode[display[5]]; //显示
P2 = 0xfb;
Delayms(2);
P0 = ledcode[display[6]]; //显示
P2 = 0xfd;
Delayms(2);
P0 = ledcode[display[7]]; //显示
P2 = 0xfe;
Delayms(2);
}
/**********************************************************
CRC ulint
**********************************************************/
ulint CalCRC_ulint(uchar *ptr, unsigned char len) //只要传入待算数的首地址
{
uint crc;
ulint data_crc;
uchar da;
uint data crc_ta[16]={ 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef };
crc = 0;
while(len--> 0)
{
da=((uchar)(crc/256))/16; // 暂存CRC 的高四位
crc<<=4; //CRC 右移4 位,相当于取CRC 的低12 位)
crc^=crc_ta[da^(*ptr/16)]; // CRC 的高4 位和本字节的前半字节相加后查表计算CRC,然后加上上一次CRC 的余数
da=((uchar)(crc/256))/16; // 暂存CRC 的高4 位
crc<<=4; //CRC 右移4 位, 相当于CRC 的低12 位)
crc^=crc_ta[da^(*ptr&0x0f)]; // CRC 的高4 位和本字节的后半字节相加后查表计算CRC,然后再加上上一次CRC 的余数
ptr++;
}
data_crc = crc;
return(data_crc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -