?? 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 + -