www.pudn.com > rfid.rar > main.c, change:2012-04-22,size:12546b


/******************************************************************************* 
 * 文件名称:main.c 
 * 功    能:2.45GHz RFID演示 
 * 作    者:Ronnie 
 * 公    司:湘潭斯凯电子科技有限公司 
 *           www.sikai-tech.com 
 * 日    期:2011-06-26 
 ******************************************************************************/ 
 
 
/* 包含头文件 */ 
/********************************************************************/ 
#include <MSP430x23x0.h>     	 
#include "lcd.h" 
#include "hal_2.45GHz_Reader.h" 
#include "stdio.h" 
/********************************************************************/ 
 
 
/* 宏定义 */ 
/********************************************************************/ 
#define EnableInterrupts  _EINT()          // 使能全局中断 
#define BEEP_DIR_OUT      P1DIR |= BIT5    // 控制蜂鸣器的引脚方向为输出 
#define BEEP_ON           P1OUT &= ~BIT5   // 打开蜂鸣器 
#define BEEP_OFF          P1OUT |= BIT5    // 关闭蜂鸣器 
/********************************************************************/ 
 
 
/* RFID Reader的数据管道0接收地址为"READR" */ 
/********************************************************************/ 
unsigned char RFID_READER_ADDR_P0[] = {'R', 'D', 'A', 'E', 'R'}; 
/********************************************************************/ 
 
 
/* XXTEA加密块数量 */ 
/********************************************************************/ 
#define TEA_ENCRYPTION_BLOCK_COUNT 4 
/********************************************************************/ 
 
 
/* XXTEA密钥 */ 
/********************************************************************/ 
const long XXTEA_KEY[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; 
/********************************************************************/ 
 
 
/* XXTEA算法相关变量和宏定义 */ 
/********************************************************************/ 
unsigned long z, y, sum, tmp, mx; 
unsigned char e; 
#define TEA_ROUNDS_COUNT (6+52/4) 
#define MX ((((z>>5)^(y<<2))+((y>>3)^(z<<4)))^((sum^y)+(XXTEA_KEY[(p&3)^e]^z))) 
#define DELTA 0x9E3779B9 
/********************************************************************/ 
 
 
/* 数据包结构体类型 */ 
/********************************************************************/ 
typedef struct 
{ 
  unsigned char len;        // 数据包的长度字段(单位:字节) 
  unsigned char protocol;   // 数据包的协议类型字段 
  unsigned char flags;      // 数据包的标志字段(按下Tag上的按键,flag为0x02;否则为0x00) 
  unsigned char txpower;    // 数据包的发送功率字段 
  unsigned long seq;        // 数据包的序号字段 
  unsigned long oid;        // 数据包的对象标识符字段 
  unsigned short reserved;  // 数据包的保留字段 
  unsigned short crc;       // 数据包的CRC字段 
}PKT; 
/********************************************************************/ 
 
 
/* 加密数据包结构体类型 */ 
/********************************************************************/ 
typedef union 
{ 
  PKT pkt; 
  unsigned long dataUL[TEA_ENCRYPTION_BLOCK_COUNT]; 
  unsigned char dataB[TEA_ENCRYPTION_BLOCK_COUNT * sizeof (unsigned long)]; 
}ENCRYPTED_PKT; 
/********************************************************************/ 
 
 
/* 用于Tag的加密数据包结构体变量 */ 
/********************************************************************/ 
static ENCRYPTED_PKT g_Tag; 
/********************************************************************/ 
 
 
/* "打乱"功能宏 — SHUFFLE */ 
/********************************************************************/ 
#define SHUFFLE(a,b) 	tmp = g_Tag.dataB[a];\ 
			g_Tag.dataB[a] = g_Tag.dataB[b];\ 
			g_Tag.dataB[b] = tmp; 
/********************************************************************/ 
 
 
/********************************************************************* 
 * 函数名称:htonl 
 * 功    能:将主机字节顺序表达的32位无符号长整形数转换成网络字节顺序 
 *           表达的32位无符号长整形数 
 * 入口参数:hostlong  主机字节顺序表达的32位无符号长整形数 
 * 出口参数:无 
 * 返 回 值:网络字节顺序表达的32位无符号长整形数 
 ********************************************************************/ 
static unsigned long htonl (unsigned long hostlong) 
{ 
  unsigned long res; 
 
  ((unsigned char *) &res)[0] = ((unsigned char *) &hostlong)[3]; 
  ((unsigned char *) &res)[1] = ((unsigned char *) &hostlong)[2]; 
  ((unsigned char *) &res)[2] = ((unsigned char *) &hostlong)[1]; 
  ((unsigned char *) &res)[3] = ((unsigned char *) &hostlong)[0]; 
 
  return res; 
} 
 
 
/********************************************************************* 
 * 函数名称:htons 
 * 功    能:将主机字节顺序表达的16位无符号短整形数转换成网络字节顺序 
 *           表达的16位无符号短整形数 
 * 入口参数:hostlong  主机字节顺序表达的16位无符号短整形数 
 * 出口参数:无 
 * 返 回 值:网络字节顺序表达的16位无符号短整形数 
 ********************************************************************/ 
static unsigned short htons (unsigned short hostshort) 
{ 
  unsigned short res; 
 
  ((unsigned char *) &res)[0] = ((unsigned char *) &hostshort)[1]; 
  ((unsigned char *) &res)[1] = ((unsigned char *) &hostshort)[0]; 
 
  return res; 
} 
 
 
/********************************************************************* 
 * 函数名称:Shuffle_TX_ByteOrder 
 * 功    能:"打乱"待发送数据的字节顺序 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
static void Shuffle_TX_ByteOrder (void) 
{ 
  unsigned char tmp; 
 
  SHUFFLE (0 + 0, 3 + 0); 
  SHUFFLE (1 + 0, 2 + 0); 
  SHUFFLE (0 + 4, 3 + 4); 
  SHUFFLE (1 + 4, 2 + 4); 
  SHUFFLE (0 + 8, 3 + 8); 
  SHUFFLE (1 + 8, 2 + 8); 
  SHUFFLE (0 + 12, 3 + 12); 
  SHUFFLE (1 + 12, 2 + 12); 
} 
 
 
/********************************************************************* 
 * 函数名称:CRC16 
 * 功    能:CRC16计算 
 * 入口参数:buffer  指向存储待进行CRC16计算的数据的缓冲区的指针 
 *           size    待进行CRC16计算的数据的长度     
 * 出口参数:无 
 * 返 回 值:CRC16计算结果 
 * 注    意:CC2530自身带有CRC计算功能,但为了提高代码的可移植性,我们 
 *           不使用CC2530自身带有的CRC计算功能,而使用该函数。 
 ********************************************************************/ 
static unsigned short CRC16 (const unsigned char *buffer, unsigned char size) 
{ 
  unsigned short crc = 0xFFFF; 
   
  if(buffer) 
  { 
    while(size--) 
    { 
      crc = (crc >> 8) | (crc << 8); 
      crc ^= *buffer++; 
      crc ^= ((unsigned char) crc) >> 4; 
      crc ^= crc << 12; 
      crc ^= (crc & 0xFF) << 5; 
    } 
  } 
   
  return crc; 
} 
 
 
/********************************************************************* 
 * 函数名称:MX_Update 
 * 功    能:XXTEA算法的MX更新 
 * 入口参数:p 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
static void MX_Update (unsigned char p) 
{ 
  mx = MX; 
} 
 
 
/********************************************************************* 
 * 函数名称:MX_Decode 
 * 功    能:XXTEA算法的MX解码 
 * 入口参数:p 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
static void MX_Decode (unsigned char p) 
{ 
  MX_Update (p); 
  y = tmp - mx; 
} 
 
 
/********************************************************************* 
 * 函数名称:MX_Decode 
 * 功    能:XXTEA解码 
 * 入口参数:p 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void XXTEA_Decode (void) 
{ 
  y = g_Tag.dataUL[0]; 
  sum = DELTA * TEA_ROUNDS_COUNT; 
 
  while (sum != 0) 
  { 
    e = sum >> 2 & 3; 
 
    z = g_Tag.dataUL[2]; 
    tmp = g_Tag.dataUL[3]; 
    MX_Decode (3); 
    g_Tag.dataUL[3] = y; 
 
    z = g_Tag.dataUL[1]; 
    tmp = g_Tag.dataUL[2]; 
    MX_Decode (2); 
    g_Tag.dataUL[2] = y; 
 
    z = g_Tag.dataUL[0]; 
    tmp = g_Tag.dataUL[1]; 
    MX_Decode (1); 
    g_Tag.dataUL[1] = y; 
 
    z = g_Tag.dataUL[3]; 
    tmp = g_Tag.dataUL[0]; 
    MX_Decode (0); 
    g_Tag.dataUL[0] = y; 
 
    sum -= DELTA; 
  } 
} 
 
 
/********************************************************************* 
 * 函数名称:InitNRF4Reader 
 * 功    能:针对RFID Reader功能初始化nRF24L01+ 
 * 入口参数:无     
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void InitNRF4Reader(void) 
{ 
  hal_nrf_nop(); 
   
  hal_nrf_write_reg(CONFIG, 0x00); 
   
  hal_nrf_write_reg(EN_AA, 0x00); 
   
  hal_nrf_write_reg(SETUP_AW, 0x03); 
   
  hal_nrf_write_multibyte_reg(RX_ADDR_P0, RFID_READER_ADDR_P0, 5); 
   
  hal_nrf_write_reg(EN_RXADDR, 0x01); 
   
  hal_nrf_write_reg(RX_PW_P0, 16);   
   
  hal_nrf_write_reg(RF_CH, 81);     
   
  hal_nrf_write_reg(STATUS, 0x70); 
   
  hal_nrf_write_reg(CONFIG, 0x01); 
} 
 
 
/********************************************************************* 
 * 函数名称:Delay_nMS 
 * 功    能:毫秒级延时函数 
 * 入口参数:n_ms  延时长度 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void Delay_nMS(unsigned int n_ms)  
{ 
  unsigned int ii1, ii0; 
     
  for(ii0=n_ms; ii0>0; ii0--)  
  { 
    ii1 = 0x07FF; 
    do (ii1--); 
    while (ii1 != 0); 
  } 
} 
 
 
/********************************************************************* 
 * 函数名称:kputchar 
 * 功    能:从串口输出一个字符 
 * 入口参数:TXchar  待输出的字符 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void kputchar(char TXchar) 
{ 
  /* 等待TX缓冲区就绪 */ 
  while(!(IFG2 & UCA0TXIFG)); 
 
  /* 发送字符 */ 
  UCA0TXBUF = TXchar; 
} 
 
 
/********************************************************************* 
 * 函数名称:send_cstring 
 * 功    能:从串口输出字符串 
 * 入口参数:pstr  指向待输出字符串的指针 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void send_cstring(char *pstr) 
{ 
  while(*pstr != '\0') 
  { 
    kputchar(*pstr++); 
  } 
} 
 
 
/********************************************************************* 
 * 函数名称:main 
 * 功    能:2.45GHz RFID演示 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void main(void)  
{  
  /* 定义相关变量 */ 
  unsigned char i; 
  unsigned short crc; 
  unsigned long oid; 
  char uartString[64]; 
   
  /* 关闭看门狗 */ 
  WDTCTL = WDTPW + WDTHOLD; 
  
  /* 使用内部DCO,16MHz */ 
  BCSCTL1 = CALBC1_16MHZ;    
  DCOCTL  = CALDCO_16MHZ;   
   
  /* 设置P3.4,P3.5为UART模式 */ 
  P3SEL |= BIT4 + BIT5; 
   
  /* 设置P3.4为输出 */ 
  P3DIR |= BIT4; 
   
  /* 禁止UART */ 
  UCA0CTL1 |= UCSWRST; 
  UCA0CTL0 = 0x00; 
   
  /* 选择使用SMCLK */ 
  UCA0CTL1 |= UCSSEL_2; 
   
  /* 波特率115200 */ 
  UCA0BR0 = 8; 
  UCA0BR1 = 0; 
  UCA0MCTL = 0xB1; 
   
  /* 初始化USCI状态机 */ 
  UCA0CTL1 &= ~UCSWRST; 
   
  /* RFID-2.45GHz-Reader硬件抽象层初始化 */ 
  hal_2G4Hz_Reader_Init(); 
   
  /* 针对RFID Reader功能初始化nRF24L01+ */ 
  InitNRF4Reader(); 
   
  /* 使能中断 */ 
  EnableInterrupts; 
   
  /* LCD初始化 */ 
  LCD_Init(); 
   
  /* LCD清屏 */ 
  LCD_Clear(); 
   
  /* 在LCD上显示相关信息 */ 
  LCD_WriteString(10,0,"RFID-2.45GHz-Demo");   
  LCD_WriteString(0,2,"Information of tags"); 
  LCD_WriteString(0,3,"will be sent to pc"); 
  LCD_WriteString(0,4,"via rs232.");  
  LCD_WriteString(0,5,"Put tags in the field"); 
  LCD_WriteString(0,6,"of antenna radiancy!");  
   
  /* 蜂鸣器控制初始化 */ 
  BEEP_OFF; 
  BEEP_DIR_OUT; 
 
  /* 永久循环 */   
  while(1) 
  { 
    hal_nrf_set_power_mode(HAL_NRF_PWR_UP); 
     
    Delay_nMS(RF_POWER_UP_DELAY);     
     
    CE_DATA_H; 
     
    LPM0; 
     
    LED_ON;  
    BEEP_ON; 
      
    /* 读取接收到的数据 */ 
    for(i = 0; i < 16; i++) 
    { 
      g_Tag.dataB[i] = Radio_Get_Pload_Byte(i); 
    } 
       
    /* 解码接收到的数据 */ 
    Shuffle_TX_ByteOrder(); 
    XXTEA_Decode(); 
    Shuffle_TX_ByteOrder(); 
     
    /* 校验接收到的数据 */  
    crc = CRC16(g_Tag.dataB, sizeof(g_Tag.pkt) - sizeof (g_Tag.pkt.crc)); 
    
    /*  接收到的g_Tag数据包CRC16校验错误 */ 
    if(htons(g_Tag.pkt.crc) != crc) 
    { 
      /* 用户自行处理 */ 
    } 
    /* 接收到的g_Tag数据包CRC16校验正确 */ 
    else 
    {  
      LED_ON; 
      BEEP_ON; 
       
      /* 从MSP430的UART0输出接收到来自Tag的信息 */ 
      oid = htonl(g_Tag.pkt.oid); 
      sprintf(uartString,"OID:%08lx\nTX power:%d\nButton push:%d\n\n", oid, g_Tag.pkt.txpower, g_Tag.pkt.flags);   
      send_cstring(uartString); 
    } 
     
    /* 设置nrf24L01+的RF为IDLE */ 
    Radio_Set_Status(RF_IDLE); 
 
    LED_OFF; 
    BEEP_OFF; 
  } 
}