专注电子技术学习与研究
当前位置:单片机教程网 >> 常用芯片 >> 浏览文章

无线通信芯片TRF7960程序及中文资料

作者:huqin   来源:本站原创   点击数:  更新时间:2014年08月16日   【字体:


  TRF7960应用电路


     TRF7960引脚图
     TRF7960管脚功能图

 下面介绍有关此芯片的中文资料:

   TRF7960系列是TI推出的载波为13.56MHz、支持ISO15693、ISO14443A/B和FeliCa协议的射频接口芯片。许多人更关心它能不能读写MF1卡片,就我的理解及实际验证,由于MF1在卡选择之前的操作是遵守ISO14443A协议的,之后的卡验证和卡数据读写都是NXP自己的保密协议,所以TRF7960可以对MF1卡执行到卡选择操作,或者通俗的说可以读MF1的卡片序列号,但不能对MF1卡读写数据,除非开发者自己知道NXP的加密协议并自己编写代码实现该协议。

 
在TI官方公开的TRF7960说明书中,有详细的参考电路及基于MSP430单片机的参考代码,参考这些资料做自己的开发板或者产品板基本上难度不大。MCU可以使用并口或SPI串口操作TRF7960,并口相对简单一些,SPI通信则有一些问题需要特别注意。
 
首先,TI给出的SPI参考代码使用的是MSP430的内置SPI接口,我们实际开发中因为单片机内部资源或引脚分配限制往往需要软件模拟SPI通讯。TRF7960的SPI协议规定:
不通讯的时候,片选NSS保持高电平,时钟CLOCK保持低电平,通讯的时候NSS保持低电平。
主机向TRF7960写一位数据时,在CLOCK为低电平期间根据数据的值设置MOSI数据线,然后CLOCK上升沿通知TRF7960可以接收数据,CLOCK下降沿后继续准备下一位要发送的数据,代码如下:
      for(j=8;j>0;j--)
      {
       if(((*pbuf)&0x80)==0x80)TRF796X_MOSI_HIGH;
       else           TRF796X_MOSI_LOW;
        TRF796X_SCK_HIGH;
        (*pbuf) <<= 1;
        TRF796X_SCK_LOW;
      }
主机从TRF7960读一位数据时,在CLOCK为高电平期间TRF7960根据数据的值设置MISO数据线,然后CLOCK下降沿通知MCU可以接收数据,CLOCK上升沿后继续准备下一位要发送的数据,代码如下:
      for(j=8;j>0;j--)
      {
         TRF796X_SCK_HIGH;
         _NOP();_NOP();
         TRF796X_SCK_LOW;
         (*pbuf) <<= 1;
         if(TRF796X_MISO_LOW)(*pbuf)+=1;  
       }
 
 
其次,MCU可以使用Direct Command直接向TRF7960发送一字节的命令码,执行复位、进入省电模式、向卡片发送数据、调整接收电路增益等功能。Direct Command的SPI时序有一个特殊的要求,在发送完一字节的命令后,在SS拉高之前,CLOCK要多出一个上升沿,代码如下:
    SLAVE_SELECT_LOW;      
    for(j=8;j>0;j--)
    {
     if(((*pbuf)&0x80)==0x80)TRF796X_MOSI_HIGH;
     else                    TRF796X_MOSI_LOW;
        TRF796X_SCK_HIGH;
        (*pbuf) <<= 1;
        TRF796X_SCK_LOW;
    }
    _NOP(); _NOP();
    TRF796X_SCK_HIGH;
    _NOP(); _NOP();
    SLAVE_SELECT_HIGH;      
    _NOP(); _NOP();
    TRF796X_SCK_LOW;
 
最后,TRF7960向磁场中的卡片发送数据后,等待卡片回应,是否收到卡片回送的数据及是否反应超时等命令的执行情况都是通过中断机制来表示的。在NXP的射频芯片中,可以不使用芯片的中断引脚IRQ而是直接查询射频芯片的中断标志寄存器来获得各种事件发生的情况,但在TRF7960中不能使用这种方式,因为读一次TRF7960的中断标志寄存器将会把寄存器中的中断标志清除,所以电路中通常要使用IRQ引脚,可以用IRQ引脚使能MCU中断或直接查询IRQ引脚,从而得知TRF7960内部发生了中断事件,进而用SPI读取其中断标志寄存器获取详细的中断事件产生情况。
 
 
最后提供51单片机驱动TRF7960的源程序:
代码的完整版本下载:
 
#include "include.h"
#include <intrins.h>
 
#define RXERROR 0x0f
#define NOERROR 0X00
 
//============= 全局变量定义 ======================================================================
 unsigned char RXTXstate; //发送数据计数
 unsigned char i_reg;            //中断寄存器
 unsigned char idata buf[32];
 unsigned char Data[10];
 unsigned char flags;            //标志
 unsigned char RXErrorFlag;
 
 //bit fReadUID;
 bit fIntrrupt;
 
 
 void SendByte(unsigned char i);
 void delay(int n);
 void delay1(void);
 void DelayMs(unsigned char j);
 void EnableSlotCounter(void);
 void DisableSlotCounter(void);
 void STOPcondition(void);
 void STOPcont(void);
 void STARTcondition(void);
 void WriteSingle(unsigned char *pbuf, unsigned char lenght);
 void WriteCont(unsigned char *pbuf, unsigned char lenght);
 void ReadSingle(unsigned char *pbuf, unsigned char lenght);
 void ReadCont(unsigned char *pbuf, unsigned char lenght);
 void DirectCommand(unsigned char *pbuf);
 void RAWwrite(unsigned char *pbuf, unsigned char lenght);
 void Initial7960s(void);
 bit  InventoryRequest(unsigned char *ReadBuff) ;
 void InterruptHandlerReader(unsigned char *Register);
 
 
 
void delay(int n)    
{
while(n--);
}
 
void InitPort(void)
{
    DataPort = 0x00;                        //
 
    clkOFF;
    
    //OOKdirIN;                        // 设置OOK 端口   
}
//*************************************************************************************************
// 功能描述 : 时隙计数使能
// 输入参数 : 无
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void EnableSlotCounter(void)
{
    unsigned char buff[2];
    buff[1] = IRQMask;
    buff[0] = IRQMask;
    ReadSingle(&buff[1], 1);
    buff[1] |= 0x01;
    WriteSingle(&buff[0], 2);
}
//*************************************************************************************************
// 功能描述 : 禁止时隙计数
// 输入参数 : 无
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void DisableSlotCounter(void)
{
    unsigned char buff[2];
    buff[1] = IRQMask;  
    buff[0] = IRQMask;
    ReadSingle(&buff[1], 1);
    buff[1] &= 0xfe;  
    WriteSingle(&buff[0], 2);
}
 
//*************************************************************************************************
// 功能描述 : 简单结束并口通信
// 输入参数 : 无
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void STOPcondition(void)
{
// P0M1=00000000;
//    P0M0=11111111; 
    DataPort |= 0x80;
    clkON;
    DataPort = 0x00;
    clkOFF;
}
//*************************************************************************************************
// 功能描述 : 彻底结束并口通信
// 输入参数 : 无
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void STOPcont(void)
{
//P0M1=00000000;
    //P0M0=11111111; 
    DataPort = 0x00;
    //TRFDirOUT;
    DataPort = 0x80;
    DataPort = 0x00;
}
//*************************************************************************************************
// 功能描述 : 并口通信起始
// 输入参数 : 无
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void STARTcondition(void)
{
// P0M1=00000000;
//    P0M0=11111111; 
    DataPort = 0x00;
    clkON;
    DataPort = 0xff;
    clkOFF;
}
//*************************************************************************************************
// 功能描述 : 单个写
// 输入参数 : 内容指针,长度
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void WriteSingle(unsigned char *pbuf, unsigned char lenght)
{
    unsigned char i;
    STARTcondition();
    while(lenght > 0)
    {
        *pbuf = (0x1f &*pbuf);                        // 设置地址为非连续写  register address 
        for(i = 0; i < 2; i++)                          // 单个地址和数据写操作
        {
            DataPort = *pbuf;                        //发送命令和数据 
            clkON;
            clkOFF;
            pbuf++;
            lenght--;
        }
    }
    STOPcondition();
}
//*************************************************************************************************
// 功能描述 : 连续写
// 输入参数 : 内容指针,长度
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void WriteCont(unsigned char *pbuf, unsigned char lenght)
{
    STARTcondition();
    *pbuf = (0x20 | *pbuf);                             // 设置地址写为连续模式   address, write, continous
    *pbuf = (0x3f & *pbuf);                        // 设置寄存器地址 
    
    while(lenght > 0)
    {
        DataPort = *pbuf;                        //发送命令
        clkON;
        clkOFF;
        pbuf++;
        lenght--;
    }
    STOPcont();
}  
 
//*************************************************************************************************
// 功能描述 : 单个读
// 输入参数 : 地址和长度
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void ReadSingle(unsigned char *pbuf, unsigned char lenght)
{
    STARTcondition();
    while(lenght > 0)
    {
        *pbuf = (0x40 | *pbuf);                         //地址, 读,单个
        *pbuf = (0x5f & *pbuf);                        //积存器地址 
 
// P0M1=00000000;
//     P0M0=11111111; 
 
        DataPort = *pbuf;                        // 发送命令
        clkON;
        clkOFF;
_nop_();
        //TRFDirIN;                        // 上升沿读取数据 
 
// P0M1=00000000;
//     P0M0=00000000; 
 
P0=0xff;
        clkON;
        *pbuf = DataPort;
        clkOFF;
 
// P0M1=00000000;
//     P0M0=11111111;
        DataPort = 0x00; 
        //TRFDirOUT;
_nop_();
 
        pbuf++;
        lenght--;
    }
    STOPcondition();  
}
//*************************************************************************************************
// 功能描述 : 连续读
// 输入参数 : 地址和长度
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void ReadCont(unsigned char *pbuf, unsigned char lenght)
{
    STARTcondition();
    *pbuf = (0x60 | *pbuf);                             //地址, 读,连续 
    *pbuf = (0x7f & *pbuf);                        //积存器地址
    DataPort = *pbuf;                        //发送命令 
    clkON;
    clkOFF;
    //TRFDirIN;                        //上升沿读取数据 
 
    while(lenght > 0)
    {
P0=0xff;
        clkON;
        *pbuf = DataPort;
        clkOFF;
        pbuf++;
        lenght--;
    }
    STOPcont();
}
 
//*************************************************************************************************
// 功能描述 : 发送命令
// 输入参数 : 命令指针
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void DirectCommand(unsigned char *pbuf)
{
    STARTcondition();
    *pbuf = (0x80 | *pbuf);                                 //命令 
    *pbuf = (0x9f & *pbuf);                            //命令码
    DataPort = *pbuf;            //发送命令 
    clkON;
    clkOFF;
    STOPcondition();
}
 
//*************************************************************************************************
// 功能描述 : 直接写数据
// 输入参数 : 数据指针,长度
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void RAWwrite(unsigned char *pbuf, unsigned char lenght)
{
    STARTcondition();
    while(lenght > 0)
    {
        DataPort = *pbuf;                            //发送命令 
        clkON;
        clkOFF;
        pbuf++;
        lenght--;
    }
    STOPcont();
}
//*************************************************************************************************
// 功能描述 : 初始化7860
// 输入参数 : 无
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void Initial7960s(void)
{    
    unsigned char command[4];
    
    TRFDisable;                                                 // 复位TRF7960
    DelayMs(10);
    TRFEnable;
     //DelayMs(1);
 
 
    command[0] = ModulatorControl;
    command[1] = 0x01;   //在此各种调制方式都行,最好为0x07,即ASK 30% 
    WriteSingle(command, 2);
//DelayMs(1);
// command[0] = 0x0a;
//    command[1] = 0x43;   //在此各种调制方式都行,最好为0x07,即ASK 30% 
//    WriteSingle(command, 2);
 
    command[0] = ModulatorControl;
    ReadSingle(command, 1);
//SendByte(command[0]);
 
// command[0] = ModulatorControl;
// command[1] = 0x01;                  //调制形式为 OOK  
// command[2] = ISOControl;
//    command[3] = 0x02;                  // ISO15693 高速, 单载波, 4出1
// WriteSingle(command, 4);
//
// command[0] = ModulatorControl;
// ReadSingle(command, 1);
// SendByte(command[0]);
//
// command[0] = ISOControl;
// ReadSingle(command, 1);
}
//*************************************************************************************************
// 功能描述 : 清点命令
// 输入参数 : 无
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
bit InventoryRequest(unsigned char *ReadBuff)              
{
    unsigned char i = 1,j,command, found = 0;
    unsigned int size;                          // 请求命令数据帧大小
    unsigned char NoSlots = 2;                  // 时隙总数,默认1 时隙(NoSlots = 时隙数 + 1)
    unsigned int n = 0;
bit bbit;
        if((flags & 0x20) == 0x00)                  // 判断时隙类型  
    {  
        NoSlots = 17; // 16 时隙 
        EnableSlotCounter();
    }
    size = 3;                                   //长度 = flag + command + lenght
 
    buf[0] = 0x8f;                              // 复位
    buf[1] = 0x91;                              // 传送带CRC
    buf[2] = 0x3d;                              // 连续写,从1D开始
    buf[3] = (char) (size >> 8);                // 发送的长度
    buf[4] = (char) (size << 4);                // 按15693命令格式写入FIFO
    buf[5] = flags;                // 写FIFO ISO15693 flags
    buf[6] = 0x01;                // 15693 之清点命令  
    buf[7] = 0x00;                              // 掩码长度
 
    command = IRQStatus;
    ReadSingle(&command, 1);
    RAWwrite(&buf[0], 8);                // 写 FIFO
 
fIntrrupt = 0;
 
i_reg = 0x01;
 
// command = IRQStatus;
//    ReadSingle(&command, 1);
 
    for(i = 1; i < NoSlots; i ++)               // 1 或 16 时隙 
    {
        RXTXstate = 1;                // 接收数据保存从buf[1]开始
   DelayMs(3);
 
       n = 0;
//DelayMs(1);
        while(i_reg == 0x01)                    // 等待RX完成 
        {
            n++;
            if(n == 500)
            {
                i_reg = 0x00;
                RXErrorFlag = NOERROR;
                break;
            }
        }
 
        if(i_reg == 0xFF)
        { //接收到 UID 
LED1=0;
            found = 1;
        }
 
        command = Reset; // FIFO 在下个时隙前必须复位
        DirectCommand(&command);
 
        if((NoSlots == 17) && (i < 16))         // 发送EOF(next slot)  
        {
            command = StopDecoders;
            DirectCommand(&command);
            command = RunDecoders;
            DirectCommand(&command);
            command = TransmitNextSlot;
            DirectCommand(&command);
        }
        else if((NoSlots == 17) && (i == 16))  // 所以时隙发送完成,停止时隙计数 
        {
            DisableSlotCounter();
        }
        else if(NoSlots == 2)
            break;
    }
    if(found)
    {
LED3=0;   
        for(j = 0;j < 8;j++)                   //提取接收缓存中的数据
        {
            ReadBuff[j] = buf[10 - j];         
        }
bbit = 1;
    }
    else
    {
LED3=1;
        for(j = 0;j < 8;j++)                   
        {
            ReadBuff[j] = 0;        
        } 
bbit = 0;       
    }
 
return bbit;
}
 
//*************************************************************************************************
// 功能描述 : 获取单块数据,无地址的读
// 输入参数 : 起始块
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
 
void ReadSingleBlock(unsigned char Block)
{
unsigned char i;
    unsigned char command, found = 0;
    unsigned int size;                          // 请求命令数据帧大小
    //unsigned char buf[20];         // 时隙总数,默认1 时隙(NoSlots = 时隙数 + 1)
    size=3;
buf[0] = 0x8f; // Reset FIFO command
buf[1] = 0x91; // send with CRC
buf[2] = 0x3d; // write continuous from register 1D
buf[3] = (char)(size>>8);// Data for register 1D, data length
buf[4] = (char)(size<<4);// Data for register 1E
buf[5] = 0x00;// ISO15693 flag with Option flag set
buf[6] = 0x20; // Read mul Blocks command code 
buf[7] = Block; // First Block Number
  
    RAWwrite(&buf[0], 8);                // 写 FIFO
 
    i_reg = 0x01;                               // 当前状态为RX状态
 
     DelayMs(5);
    RXTXstate = 1;                // 接收数据保存从buf[1]开始
while(i_reg == 0x01)
{
}
i_reg = 0x01;
 
DelayMs(5);  
 
     if(i_reg == 0xFF)
    { //接收到 UID 
       found = 1;
     }
 
        command = Reset; // FIFO 在下个时隙前必须复位
        DirectCommand(&command);
    if(found)
    {
        LED3=0;
        for( i = 0;i <4;i++)                   //提取接收缓存中的数据
        {
            Data[i] = buf[5-i];         
        }
    }
    else
    {
        LED3=1;
        for( i = 0;i < 8;i++)                   
        {
          Data[i] = 0x01;
        }        
    }
    //irqOFF;
}
//*************************************************************************************************
// 功能描述 : IRQ中断处理
// 输入参数 : FIFO状态
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void InterruptHandlerReader(unsigned char *Register)
{
// TX IRQ 
 
     if(*Register == 0xA0)                                      //正在发送,并且FIFO只剩下3字节
     {
         i_reg = 0x00;
     }
     else if(*Register == 0x80)                                 // 在TX开始时置位,TX完毕后产生中断,发送完毕
     {
         i_reg = 0x00;
         *Register = Reset;                                // FIFO 复位
         DirectCommand(Register);
 
     }
// RX IRQ 
    else if(*Register == 0x60)                                  //  FIFO 中数据超过 75% (9 bytes) 
    {     
 
         i_reg = 0x01;                                          // 仍然是接收状态
         buf[RXTXstate] = FIFO;
         ReadCont(&buf[RXTXstate], 9);                // 从 FIFO 读 9 bytes 
         RXTXstate = RXTXstate + 9;
 
         if(IRQ==0)       
         {
              *Register = IRQStatus;                // IRQ 状态积存器地址 
              ReadSingle(Register, 1);   //irqCLR;
              
 
              if(*Register == 0x40)                             // 接收完成
              {
                   *Register = FIFOStatus;
                   ReadSingle(Register, 1); //判断在FIFO中剩余的BYTES
                   *Register = 0x0F & (*Register + 0x01);       //
                   buf[RXTXstate] = FIFO; //将接收的内容放到正确的缓存中
                                                                                                                                                                                                                             
                   ReadCont(&buf[RXTXstate], *Register);
                   RXTXstate = RXTXstate + *Register;
 
                   *Register = TXLenghtByte2; //判断是否有数据损坏 
                   ReadSingle(Register, 1); //判断损坏的位数 
 
                   if((*Register & 0x01) == 0x01)
                   {
                        *Register = (*Register >> 1) & 0x07; // 隐藏前面无关的5位
                        *Register = 8 - *Register;              //坏掉的位数
                        buf[RXTXstate - 1] &= 0xFF << *Register;
                   }
                   i_reg = 0xFF; //接收结束
                   *Register = Reset; // FIFO 复位
                   DirectCommand(Register);
              }
              else if(*Register == 0x50)                        //CRC错误
              { //接收结束,并且错误 
                   i_reg = 0x02;
              }
         }
         else                                                   // 接收完毕中断
         {
              Register[0] = IRQStatus;
              ReadSingle(Register, 2);                
              if(Register[0] == 0x00)
              {
                 i_reg = 0xFF;
//fReadUID = 1;
              }
         }
    }
    else if(*Register ==0x40)                                  // RX结束
    {  
                   
        if(RXErrorFlag == RXERROR)                              // CRC错误 BIT60x0f
         {
              i_reg = 0x02;                                     // RX 完成
              return;
         }
 
         *Register = FIFOStatus;
         ReadSingle(Register, 1); //确定FIFI中剩余的字节数
         *Register = (0x0F & *Register) + 0x01;                 // data bytes + addr
         buf[RXTXstate] = FIFO; // 将接收的数据放入缓存中;
                                                                                                                                                                                        
         ReadCont(&buf[RXTXstate], *Register);
         RXTXstate = RXTXstate + *Register;
 
        *Register = TXLenghtByte2; //判断是否有数据损坏
         ReadSingle(Register, 1); //判断损坏的位数
         if((*Register & 0x01) == 0x01)
         {
              *Register = (*Register >> 1) & 0x07; // 隐藏前面无关的5位
              *Register = 8 -*Register;
              buf[RXTXstate - 1] &= 0xFF << *Register;
         }
         *Register = Reset; //接收完成复位FIFO
         DirectCommand(Register);
         i_reg = 0xFF; //最后接收的字节
//fReadUID = 1;
    }
    else if((*Register & 0x10) == 0x10)                         // CRC错误
    {
         if((*Register & 0x20) == 0x20)                         // 是否有FIFO益出中断
         {
              i_reg = 0x01;                                // 正在RX 
              RXErrorFlag = RXERROR;
         }
         else
         {
              i_reg = 0x02;                                // RX结束 无FIFO益出
         }
    }
    else if((*Register & 0x04) == 0x04)                         // byte framing 错误
    {
         if((*Register & 0x20) == 0x20)
         {
             i_reg = 0x01;                                 //正在RX 
             RXErrorFlag = RXERROR;
         }
         else
         {
              i_reg = 0x02;                                //RX结束
         }
    }
    else if(*Register == 0x01)
    {                //无应答中断
         i_reg = 0x00;
    }
    else
    {                //其他中断处理 
        i_reg = 0x02;
        
        *Register = StopDecoders;                //接收完成复位FIFO
        DirectCommand(Register);
        
        *Register = Reset;
        DirectCommand(Register);
        
        *Register = IRQStatus;                
        ReadSingle(Register, 1);                
        //irqCLR;
    }
}
//*************************************************************************************************
// 功能描述 : 获取UID
// 输入参数 : 无
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void GetUID(unsigned char *ReadBuff)
{
    unsigned char   command[10];
    bit bbit;
 
    command[0] = ChipStateControl;          // 打开 RF 发射和接收 
    command[1] = 0x25;                      // RFID模块RF场始能,接收始能
    command[2] = ISOControl;            // ISO15693 
    command[3] = 0x02;                      // ISO15693 高速, 单载波, 4出1
    WriteSingle(command, 4);
    DelayMs(6);
   
    command[0] = ChipStateControl;
    ReadSingle(command, 1);                // 清除 IRQs 
    command[0] = ISOControl;
    ReadSingle(command, 1);                // 清除 IRQs  
 
    flags = 0x06;
 
    bbit = InventoryRequest(ReadBuff);                // 发送清点命令
    command[0] = ChipStateControl; // 关闭 RF 发射 
    command[1] = 0x01;
    WriteSingle(command, 2);
    DelayMs(1);
    command[0] = IRQStatus;
    ReadSingle(command, 1);                // 清除 IRQs 
}
 
 
void Read(unsigned char Block)
{
    unsigned char   command[10];
 
    command[0] = ChipStateControl;          // 打开 RF 发射和接收 
    command[1] = 0x25;                      // RFID模块RF场始能,接收始能
    command[2] = ISOControl;            // ISO15693 
    command[3] = 0x01;                      // ISO15693 高速, 单载波, 4出1
    WriteSingle(command, 4);
    DelayMs(6);
   
    command[0] = ChipStateControl;
    ReadSingle(command, 1);                // 清除 IRQs 
    command[0] = ISOControl;
    ReadSingle(command, 1);                // 清除 IRQs  
 
    ReadSingleBlock(Block);                // 发送清点命令
    command[0] = ChipStateControl; // 关闭 RF 发射 
    command[1] = 0x01;
    WriteSingle(command, 2);
    DelayMs(1);
    command[0] = IRQStatus;
    ReadSingle(command, 1);                // 清除 IRQs 
}
 
//******延时1ms**********************//
void delay1(void)   //误差 0us
{
    unsigned char a,b;
    for(b=129;b>0;b--)
        for(a=45;a>0;a--);
}
 
 
void DelayMs(unsigned char j)
{
unsigned char i;
for(i=0;i<j;i++)
delay1();
}
 
/*串行口初始化函数*/
void SCI_Init(void)
{ /*在11.0592MHz晶振下,设置串行口9600数据传输率,方式3*/
 
PCON=0x0; /*串口接收字符RI置位,允许串口接收*/
   SCON=0x50;
TMOD=0x21;
TL1=0xfd;
TH1=0xfd;
TR1=1;
// EA = 1;
ES = 1;
}
 
void SendByte(unsigned char i)
{
  SBUF=i;
  while(!TI);
TI=0;
}
//*************************************************************************************************
// 功能描述 : 系统主循环函数
// 输入参数 : 无
// 返回参数 : 无
// 说    明 : 
//*************************************************************************************************
void main()
{
  volatile unsigned int i=0;
//bit bbit;
unsigned char idata UID[8];         //卡号,8字节
//unsigned char aa[20];
  unsigned char Block = 2;
 
//P4SW |= 0X02;   /* 通过设置P4SW,将NA/P4.4,NA/P4.5和NA/P4.6脚设置成I/O口 */
P4SW |= 0X40;
 
P4M1=0x00;
    P4M0=0x42; 
//P4M1=00000000;
//P4M0=01000010;
   
SCI_Init();  
InitPort();                               //端口设置
  Initial7960s();                           //初始化7960
 
 
 
EX0=1; //(INT0)
IT0=1; //下降沿触发
EA = 1;
delay(20);
   
   fIntrrupt = 0;
   while(1)
    {  
Read(0x02);
EA = 0;
for(i=0;i<4;i++)
SendByte(Data[i]);
DelayMs(20);
EA = 1;
 
    }  
 
}
// IRQ中断服务程序
void TRF7960(void) interrupt 0
{
unsigned char Register[2];
fIntrrupt = 1;
do
    {       
        Register[0] = IRQStatus;  
        ReadSingle(Register, 1);    // 读IRQ状态寄存器,中断标志自动清除  
        if(*Register == 0xA0)           // TX active and only 3 bytes left in FIFO  
        {
 
            goto FINISH;
        }
        InterruptHandlerReader(&Register[0]);
    } while(IRQ == 0);
 
FINISH:
;
}
 
关闭窗口

相关文章