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