ds2502在一次性器件上应用较多,通过写入时间或特定的信息做限时使用(一次性)保证,
因为ds2502 每位只能由逻辑 1 编程为逻辑 0,但永远不能从逻辑 0 改为逻辑 1(Individual bits can be changed only from alogical 1 to a logical 0, never from a logical 0 to a logical 1.)
ds2502只需要两个脚接入即可工作,data数据脚和gnd地脚,数据的写入和读出及芯片供电均通过data脚进行
ds2502的硬件电路是这样的
2n7000可用2n7002替代(PNP型mos管)
bss110可用bss84替代(NPN型mos管)
从图中可以看出ds2502的输出都在一个脚,而且写了(open drain),所以我们需要把单片机的引脚设为开漏输出状态,
PGM脚是编程脚(低电平有效),设成推挽输出,
void DQ_Init (void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void PGM_Init (void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
“复位和在线应答脉冲”初始化时序
int DS_Init(void)
{
int flag=0; //初始化标志:0不成功,1成功
unsigned int t=0;
DQ_OUT=0;
delay_us(800);//拉低480~960us均可
DQ_OUT=1;
delay_us(30);//置高15~60us
while(t<1600)
{
if(DQ_IN==0)
{
flag=1;
break;
}
t++;
}
delay_us(100); //
return flag;
}
写1时序
写0时序
void DS_Write(unsigned char command)
{
unsigned char i,temp;
for(i=0;i<8;i++)
{
temp=command&0x01;
command=command>>1;
DQ_OUT=0;
delay_us(2);
if(temp)
DQ_OUT=1;
else
DQ_OUT=0;
delay_us(60); // delay(80); //>60
DQ_OUT=1;
delay_us(10); // delay(80); //>60
}
// delay_us(10);
}
读数据时序
unsigned char DS_Read(void)
{
unsigned char i,j;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
for(j=0;j<5;j++);
DQ_OUT = 0; //
dat=dat>>1; //
delay_us(2);
DQ_OUT = 1; //
delay_us(15);
if(DQ_IN==1)
dat|=0x80;
delay_us(50);
}
return(dat);
}
校验
unsigned char getcrc(unsigned char *p,unsigned char len)
{
unsigned crc,i,n,cbit,bit0,byte,r;
crc=0;
for(i=0;i<len;i++)
{
byte=*p;
for(n=0;n<8;n++)
{
cbit=crc&0x01;
bit0=byte&0x01;
crc=crc>>1;
r=cbit^bit0;
if(r==1) crc=crc^0x8c;
byte=byte>>1;
}
p++;
}
return crc; //crc==0 校验正确
}
主函数。。。
int main(void)
{
int init_flag=0;
int DQ_Buf ,DQ_Buf2;
int ci;
unsigned char ds_num[100];
u8 cmd[100];
u8 tmp[100];
u8 tcrc;
u8 tcrc1;
int si;
LED_Init();
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
TIM3_Int_Init(4999,7199);//10KhzµÄ¼ÆÊýƵÂÊ£¬¼ÆÊýµ½5000Ϊ500ms
uart_init(9600); //´¿Ú³õʼ»¯Îª
//usart2_init(9600);
//usart3_init(9600);
printf("no problem\r\n");
PGM_Init ();
DQ_Init ();
PGM = 1;
init_flag = DS_Init(); //³õʼ»¯
printf("init_flag = %d\r\n",init_flag);
DS_Write(DS_READROM);
for(ci=0;ci<8;ci++)ds_num[ci]=DS_Read();
printf("DS_Num = ");
for(ci=0;ci<8;ci++)printf("%x ", ds_num[ci]);
printf("\r\n");
//======================================================================
cmd[0]=DS_READMEMORY;
cmd[1]=0x00;
cmd[2]=0;
tcrc = getcrc(cmd,3);
printf("tcrc_2=%d \r\n",tcrc);
DS_Init(); //³õʼ»¯
DS_Write(DS_SKIPROM); //SKIP ROM
DS_Write(cmd[0]); //read memory
DS_Write(cmd[1]); //¶ÁÈ¡µÚ2502µÄ0Ò³ÊÕ¾Ý
DS_Write(cmd[2]);
tcrc1=DS_Read(); //¶ÁÈ¡CRCУÑéÖµ
if(tcrc1==tcrc){
printf("tcrc == tcrcl\r\n");
}
printf("tcrc = %d tcrcl = %d \r\n",tcrc, tcrc1);
for(ci=0;ci<48;ci++)
ds_num[ci]=DS_Read();
for(ci=0;ci<48;ci++){
printf("[%2d]=%x ", ci, ds_num[ci]);
}
//===========================================================================
tmp[0]=0xaa;
//**дDS2502************************************
cmd[0]=DS_WRITEMEMORY;
cmd[1]=0x00; //µØÖ·0x20
cmd[2]=0x00;
cmd[3]=tmp[0];
ci=0;
tcrc=getcrc(cmd,4);
si=0; //дÈë³É¹¦¼ÆÊý
DS_Init(); //³õʼ»¯
DS_Write(DS_SKIPROM); //SKIP ROM
DS_Write(DS_WRITEMEMORY); //write memory
DS_Write(0x00); //µØÖ·
DS_Write(0x00);
DS_Write(tmp[0]); //ҪдÈëµÄÊý¾Ý
tcrc1=DS_Read();
if(tcrc1==tcrc){
printf("tcrc == tcrcl\r\n");
}
printf("tcrc = %d tcrcl = %d \r\n",tcrc, tcrc1);
//if(tcrc1==tcrc) // crcУÑéÕýÈ·
{
delay_us(10);
PGM2=0;
delay_ms(1); //дÈëÂö³å
PGM2=1;
delay_us(5);
delay_us(500);
tcrc=DS_Read();
printf("write tcrc=%d \r\n",tcrc);
if(tcrc==tmp[0])
si++;
}
//============================================================================
cmd[0]=DS_READMEMORY;
cmd[1]=0x00;
cmd[2]=0;
tcrc = getcrc(cmd,3);
printf("tcrc_2=%d \r\n",tcrc);
DS_Init(); //³õʼ»¯
DS_Write(DS_SKIPROM); //SKIP ROM
DS_Write(cmd[0]); //read memory
DS_Write(cmd[1]); //¶ÁÈ¡µÚ2502µÄ0Ò³ÊÕ¾Ý
DS_Write(cmd[2]);
tcrc1=DS_Read(); //¶ÁÈ¡CRCУÑéÖµ
if(tcrc1==tcrc){
printf("tcrc == tcrcl\r\n");
}
printf("tcrc = %d tcrcl = %d \r\n",tcrc, tcrc1);
for(ci=0;ci<48;ci++)
ds_num[ci]=DS_Read();
for(ci=0;ci<48;ci++){
printf("[%2d]=%x ", ci, ds_num[ci]);
}
while(1)
{
}
}
欸,本来想详细分析的,拖太久了,不想动了,留给自己看吧