?? onewire.c
字號:
//-------------------------OneWire.c----------------------
#define ONEWIRE
#include"OneWire.h"
//***************************************************
//1-Wire器件復位,并檢查應答;有應答返回0,無應答返回1
//***************************************************
unsigned char Reset(void)
{
WIRE_PORT=1;
_nop_();
WIRE_PORT=0;
DELAY_550us; //復位低脈沖保持
WIRE_PORT=1; //釋放總線后70us讀應答
DELAY_70us;
if(WIRE_PORT==0)
{
DELAY_420us;
return(0);
}
else
{
return(1);
}
}
//***************************************************
// 寫數據位1
//***************************************************
void WriteBit1(void)
{
WIRE_PORT=1;
WIRE_PORT=0; //拉低總線保持6us
DELAY_6us;
WIRE_PORT=1; //釋放總線延時65us
DELAY_65us;
}
//***************************************************
// 寫數據位0
//***************************************************
void WriteBit0(void)
{
WIRE_PORT=1;
WIRE_PORT=0; //拉低總線保持65us
DELAY_65us;
WIRE_PORT=1; //釋放總線延時6us
DELAY_6us;
}
//***************************************************
// 讀數據位
//***************************************************
unsigned char ReadBit(void)
{
bit value;
WIRE_PORT=1;
WIRE_PORT=0; //拉低總線保持6us
DELAY_6us;
WIRE_PORT=1; //釋放總線延時9us
DELAY_9us;
value = WIRE_PORT; //讀取總線狀態延時55us
DELAY_55us;
return value;
}
//***************************************************
// 寫字節
//***************************************************
void WriteByte(unsigned char value)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(value&0x01)
{
WriteBit1();
}
else
{
WriteBit0();
}
value=value>>1;
}
}
//***************************************************
// 讀字節
//***************************************************
unsigned char ReadByte(void)
{
unsigned char i,value;
value=0;
for(i=0;i<8;i++)
{
if(ReadBit())
value += 1;
value=_cror_(value,1);
}
return value;
}
//***************************************************
//讀8位家族碼;的48位序列號;8位CRC碼;讀取成功返回0
//參數: *id--讀取的數據存放地址
//返回:0--操作成功;1--總線不可用;2--校驗錯誤;
//***************************************************
unsigned char ReadRom(unsigned char *id)
{
unsigned char i;
if(Reset() != 0)
return(1);
WriteByte(CMD_READ_ROM); //寫命令
for(i=0;i<8;i++)
{
*id++ = ReadByte();
}
if(Calc_Crc8(id-8,8) != 0) //校驗
return(2);
return(0);
}
//***************************************************
//讀EPROM
//參數:tgaddr--目標地址;len--要讀取的字節數;
// *buffer--存放地址
//返回:0--操作成功;1--總線不可用;
//***************************************************
unsigned char ReadMemory(unsigned char tgaddr,unsigned char len,
unsigned char * buffer)
{
if(Reset() != 0)
return(1);
WriteByte(CMD_SKIP_ROM); //寫命令
WriteByte(CMD_READ_MEMORY); //寫命令
WriteByte(tgaddr); //寫地址低字節
WriteByte(0); //寫地址高字節
while(len--)
{
*buffer++ = ReadByte();
}
Reset();
return(0);
}
//***************************************************
//DS2431的EEPROM 共為8 X 18個字節,可以看作18個8字節塊.
//參數:nblock--塊號取值(0--17) 16塊為特殊功能寄存器
// 17塊為保留;*buffer為要寫入的8字節數據起始指針
//返回:0--操作成功;1--總線不可用; 2--寫暫存器失敗;
// 3--寫主存儲器錯誤; 4--寫暫存器校驗錯誤;
//***************************************************
unsigned char WriteBlock(unsigned char nblock,unsigned char *buffer)
{
unsigned char sbuf[14];
unsigned char i,temp;
unsigned int crcode;
if(nblock > 17)
return(3); //地址超出范圍
//構造要寫入的命令和數據
sbuf[0] = CMD_SKIP_ROM;
sbuf[1] = CMD_WRITE_SCRATCHPAD;
sbuf[2] = (nblock << 3); //寫地址低字節
sbuf[3] = 0; //寫地址高字節
for(i =0;i<8;i++) //8字節數據
sbuf[i+4] = *(buffer+i);
//器件復位
if(Reset() != 0)
return(1);
//寫命令和數據
for(i=0;i<12;i++)
WriteByte(sbuf[i]);
//讀取CRC校驗碼
temp = ReadByte();
crcode = ReadByte();
crcode = (crcode << 8) | temp;
//如果沒收到CRC校驗或校驗錯誤則讀暫存器來驗證數據,如果校驗正確可略過暫存器比較
if( (crcode ^ Calc_Crc16(sbuf+1,11)) != 0xFFFF)
return(4);
//******************讀暫存器比較寫入的數據**************
if(Reset() != 0)
return(1);
WriteByte(CMD_SKIP_ROM); //寫命令
WriteByte(CMD_READ_SCRATCHPAD);
for(i=1;i<14;i++)
sbuf[i] = ReadByte();
if(sbuf[1] != (nblock << 3)) return(2);
else if (sbuf[2] != 0) return(2);
else if (sbuf[3] != 7) return(2);
for(i=0;i<8;i++)
if(sbuf[i+4] != *(buffer+i)) return(2);
//******************拷貝暫存器數據到主存儲器**************
//構造要寫入的命令和數據
sbuf[1] = CMD_COPY_SCRATCHPAD;
sbuf[2] = (nblock << 3); //寫地址低字節
sbuf[3] = 0; //寫地址高字節
sbuf[4] = 7;
//器件復位
if(Reset() != 0)
return(1);
for(i=0;i<5;i++)
WriteByte(sbuf[i]);
DELAY_13ms;
if(ReadByte() == 0xaa)
{
Reset();
return(0);
}
else
{
Reset();
return(3);
}
}
//***************************************************
//寫保護,一旦寫保護將無法撤消
//DS2431的EEPROM 共為8 X 18個字節,可以看作4 X 32 + 16.
//4個32字節頁面加8字節寄存器,加8字節保留字節
//參數:npage--的低4位分別映射到EEPROM的0--3頁,該位為1
// 則對應頁被寫保護.
//返回:0--操作成功;1--總線不可用; 2--寫暫存器錯誤;
// 3--寫主存儲器錯誤
//***************************************************
unsigned char WriteProtect(unsigned char npage)
{
unsigned char i;
unsigned char memmap[8];
for(i=0;i<4;i++)
memmap[i] = ((npage >> i) & 0x01) * 0x55;
return (WriteBlock(16,memmap));
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -