MSP430F2131讀寫DS1991
// msp430f2131的MCLK來至DCO,配置成1M
//******************************************************************************
// MSP430x2xx Demo - Software Toggle P1.0
//
// Description; Toggle P1.0 by xoring P1.0 inside of a software loop.
// ACLK = n/a, MCLK = SMCLK = default DCO
//
// MSP430x2xx
// -----------------
// /|| XIN|-
// | | |
// --|RST XOUT|-
// | |
// | P1.0|-->LED
//
// A. Dannenberg
// Texas Instruments, Inc
// January 2006
// Built with IAR Embedded Workbench Version: 3.40A
//******************************************************************************
#include "msp430x20x1.h"
#define TM_OUT(level) P2OUT = ((unsigned int)level) ? (P2IN|BIT4) : (P2IN&~BIT4)
#define TM_DIR(level) P2DIR = ((unsigned int)level) ? (P2DIR|BIT4) : (P2DIR&~BIT4)
#define TM_IN (P2IN&BIT4)
/******************************
函數(shù)功能:測試DS1991是否在線
DS1991在線則返回1,
否則返回0
********************************/
unsigned char rest(void)
{
unsigned char i=0;
unsigned char k=0;
TM_DIR(1); //5u
TM_OUT(0); //9u
for(i=0;i<0x61;i++); //3+x*5 //492us //發(fā)復(fù)位低脈沖tRSTL>80us
TM_OUT(1); //9u //釋放總線,等待上拉電阻將總線恢復(fù)高電平tPDH=5us~60us
TM_DIR(0); //5u
i=0;
do //等待對方返回低脈沖, tPDL=60us~240us
{
if(TM_IN==0)
{
k=1;
for(i=0;i<0x09;i++); //52us
i=0;
do
{
if(TM_IN==1) //等待對方恢復(fù)高電平
break;
}while(i++<0x20);
TM_DIR(1);
TM_OUT(1);
for(i=0;i<0x61;i++); //482us
break;
}
}
while(i++<0x35); //530us
TM_DIR(1);
TM_OUT(1);
for(i=0;i<0x5;i++); //27us
return k;
}
/******************************
函數(shù)功能:DS1991寫數(shù)據(jù)
*byte1為數(shù)據(jù)指針,
num表示寫的數(shù)據(jù)個數(shù)
********************************/
void wrbyte(unsigned char *byte1,unsigned char num)
{
unsigned char i=0,j=0,k=0,byte=0,temp=0;
TM_DIR(1);
for(k=0;k
byte=*(byte1+k);
for(j=0;j<8;j++)
{
temp=(byte>>j)&0x01; //14us
TM_OUT(0); //1us
i=0; //2us //總線值低電平tLow1=1us~15us
TM_OUT(temp);
//TM=temp; //4us//寫周期TH=60us-tLow1,對方在檢測到總線=0開始15us后,將總線采樣寫入
for(i=0;i<0x12;i++); //91us
TM_OUT(1);
for(i=0;i<1;i++); //5us
}
}
}
/******************************
函數(shù)功能:DS1991讀數(shù)據(jù)
num表示讀的數(shù)據(jù)個數(shù)
函數(shù)返回指針
********************************/
unsigned char *rbyte(unsigned char num)
{
unsigned char i,j,k,byte1=0,byte2=0;
unsigned char *pp,temp[48]={0};
for(k=0;k
for(j=0;j<8;j++)
{
TM_OUT(0); //總線值低電平tSu<1us
i=0;
i=1; //2us
TM_OUT(1); //等待總線數(shù)據(jù)到達(dá)tLOW=1us~15us
TM_DIR(0);
//采樣周期,對方在檢測到總線=0開始15us后,將數(shù)據(jù)放在總線上,持續(xù)時間0~45us
//然后釋放總線,總時間共60us-TL.
if(TM_IN) byte2|=0x01;
byte2=byte2<<7;
byte1=byte1>>1;
byte1=byte1|byte2;
byte2=0;
for(i=0;i<0x8;i++); //40us
TM_DIR(1);
TM_OUT(1);
for(i=0;i<1;i++); //5us
}
temp[k]=byte1;
}
pp=temp;
return pp;
}
unsigned char *rdsubkey(unsigned char quNO)
{
unsigned char temp[56]={0};
unsigned char i=0,*pp;
////////////
i=rest();
temp[0]=0xcc;
wrbyte(temp,1);
i=(quNO<<6);
temp[0]=0x66;temp[1]=(0x10+i);temp[2]=(0xff-temp[1]); // Read
wrbyte(temp,3);
pp=rbyte(0x8); //讀取ID
for(i=0;i<8;i++)
temp=*(pp+i);
wrbyte(oldpw,8);//寫密碼
pp=rbyte(0x30); //讀取數(shù)據(jù)
for(i=0;i<0x30;i++)
temp[i+0x08]=*(pp+i);
i=rest();
pp=temp;
return pp;
}
////////////////////
//注意考慮操作的可靠性
////////////////////////////
void TM_pro(void)
{
unsigned int i=0;
unsigned char j=0,*pp,temp[56]={0};
///////////////////
_DINT(); //關(guān)中斷
/////////////////
for(;;)
{
i=rest(); //測試TM卡是否在線,i=1表示在線,
//在線則跳出循環(huán)
if(i==1){break;}
if(j++>0x0A){break;} //不在線時,多測試幾次,這里為10次
for(i=0;i<1000;i++);
}
if(i==1) //TM卡在線
{
///////////// 讀取8位家族碼48位唯一的序列號和8位CRC校驗(yàn)碼
temp[0]=0x33;
wrbyte(temp,1);
pp=rbyte(0x8);
for(i=0;i<8;i++)
temp=*(pp+i);
if(temp[0]==0x02) //ds1991家族碼為02
{
pp=rdsubkey(0x10); //00,01,10
for(i=0;i<56;i++)
temp=*(pp+i);
switch(temp[8])
{}
}
else;//家族碼不正確
}
else ; //卡不在線
///////////////
TM_DIR(0);
_EINT();
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
BCSCTL1=CALBC1_1MHZ;
DCOCTL=CALDCO_1MHZ;
for (;;)
{
if(tmflag==1)
{
P2IE |= 0x00; // P2.4 interrupt enabled
P2IES |= 0x00;
tmflag=0;
//TM_pro();
///////////// 讀取8位家族碼48位唯一的序列號和8位CRC校驗(yàn)碼
temp[0]=0x33;
wrbyte(temp,1);
pp=rbyte(0x8);
for(i=0;i<8;i++)
temp=*(pp+i);
if(temp[0]==0x02) //ds1991家族碼為02
{
i=rest();
temp[0]=0xcc; //Skip ROM
wrbyte(temp,1);
temp[0]=0x96;temp[1]=0xc0;temp[2]=(0xff-temp[1]); //Write Scratchpad [96H]
wrbyte(temp,3);
temp[0]=0x34;
wrbyte(temp,1);
// pp=rbyte(0x8);
// for(i=0;i<8;i++)
// temp=*(pp+i);
// wrbyte(temp,8);
// wrbyte(id,8);
// wrbyte(pw,8);
i=rest();
////////////////////
i=rest();
temp[0]=0xcc;
wrbyte(temp,1);
temp[0]=0x69;temp[1]=0xc0;temp[2]=(0xff-temp[1]); // Read Scratchpad [69H]
wrbyte(temp,3);
pp=rbyte(0x2);
for(i=0;i<2;i++)
temp=*(pp+i);
i=rest();
i=9;
}
////////////
}
TM_DIR(0);
P2IE |= 0x10; // P2.4 interrupt enabled
P2IES |= 0x10; // P2.4 Hi/lo edge
P2IFG &= ~0x10;
_EINT();
}
}
評論