#include "msp430g2553.h"
#include <intrinsics.h>
#include "Rc522Reg.h" //见NXP的代码
#include "ErrCode.h" //见NXP的代码
#include "OpCtrl.h" //见NXP的代码
#include "Mifare.h" //见NXP的代码
#define txbeforerx 0x01 //bitflag
#define i2ctxend 0x02 //bitflag
#define i2crxend 0x04 //bitflag
#define tx1byte 0x08 //bitflag
#define epr24_addr 0x50 //24LC02B器件地址
#define rc522_addr 0x2A //MFRC522器件地址
unsigned char TxData[9];
unsigned char RxBuffer[8];
unsigned char cachedata[40];
unsigned char *PTxData,*PRxData;
unsigned char bitflag;
/*----------------------------------------------------------------------------
功能:USCI_B0的I2C功能初始化
输入:
输出:
说明:SMCLK=DCOCLK
----------------------------------------------------------------------------*/
void I2C_init(void)
{
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset, receiver
UCB0BR0 = 11; // fSCL = SMCLK/11
UCB0BR1 = 0;
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
bitflag &= 0xF0;
}
/*----------------------------------------------------------------------------
功能:从I2C接口接收n个字节数据
输入:待接收字节个数 num,7-bit从机地址slave_addr
输出:接收的数据存放在RxBuffer数组
说明:接收之前需要发送的数据放在TxData[0],比如源数据内存地址;适合接收2个以上字节
----------------------------------------------------------------------------*/
void I2CRxnbyte(unsigned char slave_addr, unsigned char num)
{
UCB0I2CSA = slave_addr;
IE2 |= UCB0TXIE + UCB0RXIE; // Enable TX RX interrupt
PRxData = (unsigned char *)RxBuffer; // Start of RX buffer
PTxData = (unsigned char *)TxData; // TX array start address
TxByteCount = 1;
RxByteCount = num; // Load RX byte counter
bitflag |= txbeforerx;
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register( GIE ); // Enable general interrupt
while( bitflag & txbeforerx ) //TxByteCount != 1
{
__no_operation();
}
IFG2 &= ~UCB0TXIFG;
IE2 &= ~UCB0TXIE;
while( !(bitflag & i2crxend) ) // Wait until all data is RX'd
{
__no_operation();
}
IE2 &= ~UCB0RXIE; // Disable RX interrupt
bitflag &= ~i2crxend;
}
/*----------------------------------------------------------------------------
功能:从I2C接口的当前地址接收1个字节数据
输入:7-bit从机地址slave_addr
输出:接收的数据存放在RxBuffer数组
说明:在接收第1个字节过程中需要置位停止位,接收数据放在RxBuffer[0]
----------------------------------------------------------------------------*/
void I2CRx1byte(unsigned char slave_addr)
{
UCB0I2CSA = slave_addr;
IE2 |= UCB0RXIE; // Enable TX RX interrupt
PRxData = (unsigned char *)RxBuffer; // Start of RX buffer
RxByteCount = 1; // Load RX byte counter
UCB0CTL1 &= ~UCTR; // I2C RX
UCB0CTL1 |= UCTXSTT;
while( UCB0CTL1 & UCTXSTT )
{
__no_operation();
}
__no_operation();
UCB0CTL1 |= UCTXSTP;
while( !(bitflag & i2crxend) ) // Wait until all data is RX'd
{
__no_operation();
}
IE2 &= ~UCB0RXIE; // Disable RX interrupt
bitflag &= ~i2crxend;
__no_operation();
}
/*----------------------------------------------------------------------------
功能:向I2C接口发送n个字节数据
输入:待发送字节个数 num,7-bit从机地址slave_addr
输出:
说明:待发送数据存放在TxData数组中;适合发送2个以上字节
----------------------------------------------------------------------------*/
void I2CTxnbyte(unsigned char slave_addr, unsigned char num)
{
UCB0I2CSA = slave_addr; // 24C02 Write Address is 0a0h
IE2 |= UCB0TXIE; // Enable TX interrupt
PTxData = (unsigned char *)TxData; // TX array start address
TxByteCount = num; // Load TX byte counter
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register( GIE ); // Enter LPM0 w/ interrupts
while( !(bitflag & i2ctxend) ) // Wait until all data is RX'd
{
__no_operation();
}
IE2 &= ~UCB0TXIE; // Disable TX interrupt
IFG2 &= ~UCB0TXIFG;
bitflag &= ~i2ctxend;
}
/*----------------------------------------------------------------------------
功能:向I2C接口发送1个字节数据
输入:待发送字节个数 num,7-bit从机地址slave_addr
输出:
说明:在发送第1个字节过程中需要置位停止位,待发送数据放在TxData[0]
----------------------------------------------------------------------------*/
void I2CTx1byte(unsigned char slave_addr)
{
UCB0I2CSA = slave_addr; // 24C02 Write Address is 0a0h
bitflag |= tx1byte;
IE2 |= UCB0TXIE; // Enable TX interrupt
PTxData = (unsigned char *)TxData; // TX array start address
TxByteCount = 1; // Load TX byte counter
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register( GIE ); // Enter LPM0 w/ interrupts
while( UCB0CTL1 & UCTXSTT )
{
__no_operation();
}
__no_operation();
UCB0CTL1 |= UCTXSTP;
while( !(bitflag & i2ctxend) ) // Wait until all data is RX'd
{
__no_operation();
}
IE2 &= ~UCB0TXIE; // Disable TX interrupt
bitflag &= ~tx1byte;
IFG2 &= ~UCB0TXIFG;
bitflag &= ~i2ctxend;
__no_operation();
}
/*----------------------------------------------------------------------------
功能:软件延时
输入:u16Val,延时长度,ms
输出:
说明:参数范围0-65535,延时单位约为1ms@1MHz MCLK
----------------------------------------------------------------------------*/
void soft_delay_ms(unsigned int u16Val)
{
unsigned int i;
while(u16Val--)
{
i = 1000;
while(i--)
{
__no_operation();
// _nop_();
// _nop_();
}
}
}
/*----------------------------------------------------------------------------
功能:向24LC02B发送n个字节数据
输入:待发送字节个数 num(包括地址字节),写入的目的地址d_addr
输出:
说明:待发送数据存放在TxData数组中,地址存放TxData[0],数据从TxData[1]开始存放
----------------------------------------------------------------------------*/
void Write_24c02_nbyte(unsigned char num,unsigned char d_addr)
{
TxData[0] = d_addr;
I2CTxnbyte(epr24_addr, num);
}
/*----------------------------------------------------------------------------
功能:从24LC02B接收n个字节数据
输入:待接收字节个数 num,待读取的源数据地址s_addr
输出:接收的数据存放在RxBuffer数组
说明:接收之前需要发送的数据放在TxData[0],比如源数据内存地址,待接收字节数应大于2
----------------------------------------------------------------------------*/
void Read_24c02_nbyte(unsigned char num,unsigned char s_addr)
{
TxData[0] = s_addr;
I2CRxnbyte(epr24_addr,num);
}
/*----------------------------------------------------------------------------
功能:向24LC02B更新所有数据
输入:
输出:
说明:cachedata[]是被保存的数据,只是个示例
----------------------------------------------------------------------------*/
void renew_24c02(void)
{
TxData[1] = cachedata[0];
TxData[2] = cachedata[1];
TxData[3] = cachedata[2];
TxData[4] = cachedata[3];
TxData[5] = cachedata[4];
TxData[6] = cachedata[5];
TxData[7] = cachedata[6];
TxData[8] = cachedata[7];
Write_24c02_nbyte(9,0); //page1
soft_delay_ms(2);
TxData[1] = cachedata[8];
TxData[2] = cachedata[9];
TxData[3] = cachedata[10];
TxData[4] = cachedata[11];
TxData[5] = cachedata[12];
TxData[6] = cachedata[13];
TxData[7] = cachedata[14];
TxData[8] = cachedata[15];
Write_24c02_nbyte(9,8); //page2
soft_delay_ms(2);
TxData[1] = cachedata[16];
TxData[2] = cachedata[17];
TxData[3] = cachedata[18];
TxData[4] = cachedata[19];
TxData[5] = cachedata[20];
TxData[6] = cachedata[21];
TxData[7] = cachedata[22];
TxData[8] = cachedata[23];
Write_24c02_nbyte(9,0x10); //page3
soft_delay_ms(2);
TxData[1] = cachedata[24];
TxData[2] = cachedata[25];
TxData[3] = cachedata[26];
TxData[4] = cachedata[27];
TxData[5] = cachedata[28];
TxData[6] = cachedata[29];
TxData[7] = cachedata[30];
TxData[8] = cachedata[31];
Write_24c02_nbyte(9,0x18); //page4
soft_delay_ms(2);
TxData[1] = cachedata[32];
TxData[2] = cachedata[33];
TxData[3] = cachedata[34];
TxData[4] = cachedata[35];
TxData[5] = cachedata[36];
TxData[6] = cachedata[37];
TxData[7] = cachedata[38];
TxData[8] = cachedata[39];
Write_24c02_nbyte(9,0x20); //page5
}
/*----------------------------------------------------------------------------
功能:从24LC02B还原所有数据
输入:
输出:
说明:cachedata[]是被还原的数据,只是个示例
----------------------------------------------------------------------------*/
void recover_24c02(void)
{
Read_24c02_nbyte(8,0);
cachedata[0] = RxBuffer[0];
cachedata[1] = RxBuffer[1];
cachedata[2] = RxBuffer[2];
cachedata[3] = RxBuffer[3];
cachedata[4] = RxBuffer[4];
cachedata[5] = RxBuffer[5];
cachedata[6] = RxBuffer[6];
cachedata[7] = RxBuffer[7];
Read_24c02_nbyte(8,8);
cachedata[8] = RxBuffer[0];
cachedata[9] = RxBuffer[1];
cachedata[10] = RxBuffer[2];
cachedata[11] = RxBuffer[3];
cachedata[12] = RxBuffer[4];
cachedata[13] = RxBuffer[5];
cachedata[14] = RxBuffer[6];
cachedata[15] = RxBuffer[7];
Read_24c02_nbyte(8,0x10);
cachedata[16] = RxBuffer[0];
cachedata[17] = RxBuffer[1];
cachedata[18] = RxBuffer[2];
cachedata[19] = RxBuffer[3];
cachedata[20] = RxBuffer[4];
cachedata[21] = RxBuffer[5];
cachedata[22] = RxBuffer[6];
cachedata[23] = RxBuffer[7];
Read_24c02_nbyte(8,0x18);
cachedata[24] = RxBuffer[0];
cachedata[25] = RxBuffer[1];
cachedata[26] = RxBuffer[2];
cachedata[27] = RxBuffer[3];
cachedata[28] = RxBuffer[4];
cachedata[29] = RxBuffer[5];
cachedata[30] = RxBuffer[6];
cachedata[31] = RxBuffer[7];
Read_24c02_nbyte(8,0x20);
cachedata[32] = RxBuffer[0];
cachedata[33] = RxBuffer[1];
cachedata[34] = RxBuffer[2];
cachedata[35] = RxBuffer[3];
cachedata[36] = RxBuffer[4];
cachedata[37] = RxBuffer[5];
cachedata[38] = RxBuffer[6];
cachedata[39] = RxBuffer[7];
}
/*----------------------------------------------------------------------------
功能:Write data to register of RC522
输入:RegAddr-The address of the register;RegVal-The value to be written
输出:
说明:
----------------------------------------------------------------------------*/
void RcSetReg(unsigned char RegAddr, unsigned char RegVal)
{
TxData[0] = RegAddr;
TxData[1] = RegVal;
I2CTxnbyte(rc522_addr, 2);
}
/*----------------------------------------------------------------------------
功能:read data from register of RC522
输入:RegAddr-The address of the register to be read
输出:The value of the specified register
说明:
----------------------------------------------------------------------------*/
unsigned char RcGetReg(unsigned char RegAddr)
{
unsigned char RegVal;
short status;
TxData[0] = RegAddr;
I2CTx1byte(rc522_addr);
I2CRx1byte(rc522_addr);
status = STATUS_SUCCESS; //实际调试已经成功
RegVal = RxBuffer[0];
return RegVal;
}
/*----------------------------------------------------------------------------
功能:Change some bits of the register
输入:RegAddr-The address of the register;ModifyVal-The value to change to, set or clr;MaskByte-Only the corresponding bit '1' is valid
输出:
说明:
----------------------------------------------------------------------------*/
void RcModifyReg(unsigned char RegAddr, unsigned char ModifyVal, unsigned char MaskByte)
{
unsigned char RegVal;
RegVal = RcGetReg(RegAddr);
if(ModifyVal)
{
RegVal |= MaskByte;
}
else
{
RegVal &= (~MaskByte);
}
RcSetReg(RegAddr, RegVal);
}