//注:以下程序用來完成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<num;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<num;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(); } } |