DS2431读写操作记录

最近拿到一块DS2431芯片,需要进行控制操作。虽然最后把芯片玩坏了(被锁死了),但还是成功实现了功能,这里简单记录一下。

1. DS2431芯片

1.1 芯片概述

        DS2431 是一款 1024 位 1-Wire® EEPROM芯片,由四个存储器页组成,每页 256 位。数据先被写入一个8 字节暂存器中,经校验无误后复制到EEPROM存储器。其特点在于,四个存储器页相互独立,可以单独设置写保护或EPROM仿真模式,在EPROM仿真模式下,所有位的状态只能从 1 变成 0。 DS2431 通过一根1-Wire总线进行通信。通信采用Dallas Semiconductor标准的 1-Wire协议。每个器件都有唯一 的、不能更改的 64 位ROM地址码,该地址码由工厂光刻写入芯片。在一个多点的 1-Wire网络环境中,该地址码用于对器件进行寻址。在这里插入图片描述

1.2 芯片存储器结构

       DS2431总共有144个byte,其中地址0000 ~ 007FH包含了4页,总共128个byte的内存可供读写;0081H~0084H分别用于控制前四页的写保护,一旦设置了写保护,对应页讲无法进行写操作。在这里插入图片描述

1.3 几个重要的指令及操作方式

       0xCCH:单一从机总线系统中,主机使用此命令访问存储器命令;
       0x0FH:写缓存器数据命令
       0xAAH:读缓存器数据命令
       0x55H:拷贝缓存器数据到内存命令
在这里插入图片描述

2. DS2431读写操作

2.1 DS2431数据转换流程

       要成功实现将数据写入DS2431的00~7FH地址去,首先要将数据写到缓存器中去,然后通过缓存器的校验无误,再通过数据拷贝命令,将缓存器数据复制到内存中去。

2.2 DS2431读写一个字节

       1、初始化DS2431的GPIO输入输出引脚
       这里需要注意,当配置GPIO为输入模式时,一定要配置为上拉模式,不然可能读取不到数据,全为0XFF。这里我用的是STM32F767单片机,IO用的是PH2。

#define DQ_MODE_IN()  	{GPIOH->MODER&=~(3<<(2*2));GPIOH->MODER|=0<<2*2;GPIOH->PUPDR&=~(3<<(2*2));GPIOH->PUPDR|=1<<2*2;}	
#define DQ_MODE_OUT() 	{GPIOH->MODER&=~(3<<(2*2));GPIOH->MODER|=1<<2*2;GPIOH->OSPEEDR&=~(3<<(2*2));} 						
#define DQ_OUT(x)		((x)?HAL_GPIO_WritePin(GPIOH, GPIO_PIN_2, GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOH, GPIO_PIN_2, GPIO_PIN_RESET))
#define DQ_READ			HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2)

       2、DS2431向总线发送一个字节数据

void bus_sendbyte(uint8_t dat)
{
	uint8_t count;
	
	DQ_MODE_OUT();
	DQ_OUT(1);
	for(count=0;count<8;count++)
	{
		if((dat&(0x01<<count))==0)
		{
			DQ_OUT(0);
			delay_us(55);
			DQ_OUT(1);
			delay_us(5);
		}
		else
		{
			DQ_OUT(0);
			delay_us(5);
			DQ_OUT(1);
			delay_us(55);
		}
	}
	DQ_OUT(1);
	DQ_MODE_IN();
	delay_us(100);
}

       3、DS2431向总线接收一个字节数据

uint8_t bus_getbyte(void)
{
	uint8_t dat=0;
	uint8_t count;
	for(count=0;count<8;count++)
	{
		DQ_MODE_OUT() ;
		DQ_OUT(0);
		delay_us(5);	
		DQ_OUT(1);
		DQ_MODE_IN();
		delay_us(10);
		if(DQ_READ==GPIO_PIN_SET)
		{
			dat|=(0x01<<count);
		}
		delay_us(40);
	}
	delay_us(100);
	return dat;
}

2.3 DS2431复位操作

       每次对DS2431进行命令操作前,都需要进行复位,保证芯片的正常应答,在此之后,再进行相应的操作。

uint8_t bus_reset(void)
{
	DQ_MODE_OUT() ;
	DQ_OUT(1);
	delay_ms(1);
	DQ_OUT(0);
	delay_us(500);
	DQ_OUT(1);
	DQ_MODE_IN();
	delay_us(100);
	if(DQ_READ==GPIO_PIN_RESET)
	{
		delay_us(150);
		return OK;
	}
	else
	{	
		delay_us(150);
		return NG;
	}
}

2.4 DS2431写缓存器及查看操作

       1、写缓存器
       前面我们提到,要想将数据写入DS2431的内存,首先要将数据写缓存器,以下就是写数据到缓存器的操作。
在这里插入图片描述

uint8_t Write_To_Sp(uint8_t addr,uint8_t *data)
{
	uint8_t i = 0,crc[2]={0};
	uint8_t crc_dat[11]={0};
	uint16_t crc_result = 0;
	
	if((data==NULL)||(addr>0x8F))
		return 1;
	if(bus_reset()==NG)
	{
		printf("bus_reset err!!!\r\n");
		return 1;
	}
	else
	{
		bus_sendbyte(0xcc);
		bus_sendbyte(0x0f);
		bus_sendbyte(addr);
		bus_sendbyte(0x00);
		crc_dat[0]=0x0f;
		crc_dat[1]=addr;
		crc_dat[2]=0x00;
		for(i=0;i<8;i++)
		{
			bus_sendbyte(data[i]);
			crc_dat[i+3]=data[i];
		}
		crc_result = CRC16(crc_dat,11);
		crc[0] = bus_getbyte();
		crc[1] = bus_getbyte();
		if(((crc[0]<<8)+crc[1])!=((uint16_t)~crc_result))
		{
			printf("Write_To_Sp err\r\n");
			return 1;
		}
		//printf("read crc :%x ,cal crc:%x\r\n",(crc[0]<<8)+crc[1],~crc_result);
		return 0;
	}
}

       当向缓存器正常写入数据后,缓存器会返回一个crc16的校验,通过这个校验值,我们可以判断写入数据的正确性。关于DS2431的校验,它使用的是CRC-16/MAXIM的校验方式,这个需要注意。
       2、读缓存器
       通过读缓存器中的内容,我们可以更加直观判断写入的数据的正确性。

void Read_Cur_Sp(uint8_t *data)
{
	uint8_t i = 0,ta_es[3]={0},crc[2]={0};
	if(bus_reset()==NG)
	{
		printf("bus_reset err!!!\r\n");
	}
	else
	{
		bus_sendbyte(0xcc);
		bus_sendbyte(0xaa);
		ta_es[0]=bus_getbyte();
		ta_es[1]=bus_getbyte();
		ta_es[2]=bus_getbyte();
		printf("TA1:%x TA2:%x E/S:%x\r\n",ta_es[0],ta_es[1],ta_es[2]);
		for(i=0;i<8;i++)
		{
			data[i] = bus_getbyte();
			printf("Read_Sp data[%d]:%x\r\n",i,data[i]);
		}
		crc[0] = bus_getbyte();
		crc[1] = bus_getbyte();
		printf("crc:%x %x\r\n",crc[0],crc[1]);
	}
}

2.5 DS2431复制缓存器操作

       在确定校验值正常的情况下,我们就可以使用复制命令,将缓存器中的值复制到存储器当中去了。其中,addr表示复制到存储器的地址。
在这里插入图片描述

uint8_t Copy_Spdata_To_Mem(uint8_t addr)
{
	uint8_t i = 0,crc[2]={0},ret=0;
	if(bus_reset()==NG)//???
	{
		printf("bus_reset err!!!\r\n");
		return 1;
	}
	else
	{
		bus_sendbyte(0xcc);
		bus_sendbyte(0x55);
		bus_sendbyte(addr);
		bus_sendbyte(0x00);
		bus_sendbyte(0x07);
		delay_us(1000);

		ret = bus_getbyte();
		if(ret!=0xaa)
		{
			printf("Copy_Spdata_To_Mem err!!!\r\n");
			return 1;
		}
		else
		{
			//printf("Copy_Spdata_To_Mem Success!!!\r\n");
			return 0;
		}	
	}
}

2.6 DS2431复制缓存器操作

       最后,我们可以通过读存储器内容,看看我们写入的数据是否正确。
在这里插入图片描述

uint8_t Read_Mem_Data(uint8_t addr,uint8_t *read_buf,uint8_t len)
{
	uint8_t i = 0,crc[2]={0},ret=0,data[144];
	
	if((read_buf==NULL)||(len>128)||(addr>0x8F))
	{
		return 1;
	}
	
	if(bus_reset()==NG)
	{
		printf("bus_reset err!!!\r\n");
	}
	else
	{
		bus_sendbyte(0xcc);
		bus_sendbyte(0xf0);
		bus_sendbyte(addr);
		bus_sendbyte(0x00);
		for(i=0;i<len;i++)
		{
			read_buf[i] = bus_getbyte();
		}
	}
}

3 结果

       通过以上步骤,我们就可以完成一片DS2431芯片的读写操作,最后看看结果。
       可以看到,数据是写进去了,也读出来了,但是就像我开头说的那样,我为了验证DS2431的写保护功能,把页写来保护起了,并且,把写保护寄存器也保护起来了,导致最后无法解除写保护(我试了多次,都不行),芯片就GG了。如果大家有解除保护的办法,希望能指教一下,谢谢。
在这里插入图片描述

  • 12
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 24
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值