51/AVR单片机技术驿站!  <在线翻译>     便利工具    特色网址   无弹窗、无插件的绿色站点...  英才招聘   学历查询  喜欢>>收藏我站 

当前位置:首页 > 单片机技术文章 > MSP430单片机 > 详细内容
MSP430F2131读写DS1991多密钥芯片
发布时间:2009/7/27  阅读次数:608  字体大小: 【】 【】【

  

//注:以下程序用来完成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)

/******************************
  函数功能:测试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     //发复位低脉冲tRSTL>80us
   TM_OUT(1);   //9u                                             //释放总线,等待上拉电阻将总线恢复高电平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)               //等待对方恢复高电平
               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;

}
/******************************
  函数功能:DS1991写数据
                     *byte1为数据指针,
                     num表示写的数据个数
********************************/
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
     }
  }
}
/******************************
  函数功能:DS1991读数据
                     num表示读的数据个数
                     函数返回指针
********************************/
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);             //等待总线数据到达tLOW=1us~15us
           TM_DIR(0);
                                         //采样周期,对方在检测到总线=0开始15us后,将数据放在总线上,持续时间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);   //读取数据
     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();             //关中断
  /////////////////    
  for(;;)
       {          
         i=rest();                 //测试TM卡是否在线,i=1表示在线,
                                             //在线则跳出循环
         if(i==1){break;}                    
         if(j++>0x0A){break;} //不在线时,多测试几次,这里为10次
         for(i=0;i<1000;i++);
       }
  if(i==1)       //TM卡在线
  {
     /////////////   读取8 位家族码48 位唯一的序列号和8 位CRC 校验码
       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 校验码
       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();
      
   }
  
}

我要评论
  • 匿名发表
  • [添加到收藏夹]
  • 发表评论:(匿名发表无需登录,已登录用户可直接发表。) 登录状态:未登录
最新评论
所有评论[0]
    暂无已审核评论!

网站导航 管理登陆 ┊ 免责声明 问题反馈  友链说明
本站部分内容来自网络共享资源,如有冒犯您的权利请来信告之删除或纠正!
不得对本站进行复制、盗链或镜像,转载内容须获得同意或授权;欢迎友情链接、站务合作!

    我要报警 Alexa
 mcusy_cn#126.com (请把#改成@) 交流:522422171
本站学习交流群:138..158(高级群1-)、77930286(高级群2)、61804809(群3)
Copyright© MCUSY All Rights Reserved
本站网警备案号: WZ36040002485
  ICP备案证书号:粤ICP备09034963号