📄 m101(2)x_test.c
字号:
/*******************************************************************************
I2C协议
模块I2C地址为0xA0
通讯速率为:400K。
发送数据格式:
模块地址+W/R 长度字 命令字 数据域 校验字
模块地址+W/R:
模块地址为:0xA0,写bit0为0,则写指令为:0xA0 + 0x0 = 0xA0
模块地址为:0xA0,读bit0为1,则读指令为:0xA0 + 0x1 = 0xA1
长度字:指明从长度字到数据域最后一字节的字节数。
命令字:本条命令的含义。
数据域:此项可以为空。
校验字:从长度字到数据域最后一字节的逐字节异或值(最后一字节)。
返回数据格式:
成功: 长度字 接收到的命令字+数据域 校验字
失败: 长度字 接收到的命令字取反 校验字
*******************************************************************************/
#include "main.h"
#define READ_M101XX 0xb1
#define WRITE_M101XX 0xb0
unsigned char g_cReceBuf[43]; //接收缓冲区
unsigned char g_cReceNum; //接收字节计数
bit g_bReceCommandOk; //接收命令正确标志
bit g_bCard; //卡片进入射频场标志
unsigned char ComSet[]
= {0x03,
COMM_CONTROL_ANTENNA,
0x11};
//设置打开天线和关闭自动循卡
unsigned char code ComSearchCard[]
= {0x03,
COMM_MIFARE_SEARCH_CARD,
0x00};
//循卡后读出卡号
unsigned char cReadBlock[13]
= {0x0A,
COMM_READ_BLOCK,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
//读块No.4
unsigned char code ComReadBlock4[]
= {0x0A,
COMM_READ_BLOCK,
0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
//读块No.6
unsigned char code ComReadBlock6[]
= {0x0A,
COMM_READ_BLOCK,
0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
//写块No.4
unsigned char code ComWriteBlock4[]
= {0X1A,
COMM_WRITE_BLOCK,
0x00, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
//初始化钱包No.5 的值为0x12345678
unsigned char code ComIntiPurse5[]
= {0x0E,
COMM_INIT_PURSE,
0x00, 0x05, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff , 0x78, 0x56, 0x34, 0x12};
//读钱包的值No.6
unsigned char code ComReadPurse6[]
= {0x0A,
COMM_READ_PURSE,
0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
//钱包值加2
unsigned char code ComIncrPurse5[]
= {0x0E,
COMM_INC_VALUE,
0x00, 0x05, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00};
//钱包值减1
unsigned char code ComDecrPurse5[]
= {0x0E,
COMM_DEC_VALUE,
0x00, 0x05, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00};
// restore purse in block No.5 to block No.6
unsigned char code ComBakPurse56[]
= {0x0B,
COMM_BAK_PURSE,
0x00, 0x05, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
// 卡片休眠
unsigned char code ComHaltCard[]
= {0x02,
COMM_CARD_HALT,
};
unsigned char code ComHaltMCU[]
= {0x02,
COMM_SET_MCU_IDLE,
};
// 钱包在 INC & DEC 后的结果
unsigned char code pursevalue[]
= {0x79,0x56,0x34, 0x12};
unsigned char code ComClrPA[]
= {0X03 ,
COMM_PA_OUT_CLR ,
0XFF};
unsigned char code ComSetPA[]
= {0X03 ,
COMM_PA_OUT_SET ,
0XFF};
unsigned char code ComClrPB[]
= {0X03 ,
COMM_PB_OUT_CLR ,
0X1F};
unsigned char code ComSetPB[]
= {0X03 ,
COMM_PB_OUT_SET ,
0X1F};
void Delay100uS(unsigned int i)
{
unsigned char m;
while(i--)
{
for(m = 0; m < 13; m++)
{
LED_zhishi = CARDPIN;
}
}
}
void main()
{
unsigned char i;
unsigned char cStatus;
InitializeSystem();
i=16;
BEEP = 0;
P0 = 0XFF;
P1 = 0XFF;
P2 = 0XFF;
P3 = 0XFF;
while(i--)
{
LED_ok = ~LED_ok;
LED_UART = ~LED_UART;
LED_error = ~LED_error;
LED_zhishi = ~LED_zhishi;
Delay100uS(500);
}
while (1)
{
g_bCard = !CARDPIN;
LED_zhishi = CARDPIN;
ES = 0;
cStatus = IicTesting(); // do IIC testing by AutoSearchCard
if (SUCCESS != cStatus) // if did not success, alarm error and show error code
{
Err(); //测试失败
g_bCard = !CARDPIN;
LED_zhishi = CARDPIN;
ShowError(cStatus);
continue;
}
LED_ok = 0; //测试成功
Delay100uS(500);
LED_ok = 1;
g_bCard = !CARDPIN;
LED_zhishi = CARDPIN;
i++;
}
}
unsigned char IicTesting(void)
{
unsigned char cReadBlock[10]={0x0a, 0x21, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
unsigned char *cPa, *cPb;
unsigned char i;
unsigned char cStatus;
Send_IIC_Command(ComSet);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != ComSet[1]) || cStatus != SUCCESS)
{
return 1;
}
//寻卡
cPa = ComSearchCard;
Send_IIC_Command(cPa);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != cPa[1]) || cStatus != SUCCESS)
{
return 2;
}
cPa = ComSearchCard;
Send_IIC_Command(cPa);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != cPa[1]) || cStatus != SUCCESS)
{
return 2;
}
//依次读出s50卡片中的16个扇区,64块的数据
for(i=0; i<64 ;i++)
{
cReadBlock[3] = i;
cPa = cReadBlock;
Send_IIC_Command(cPa);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != cPa[1]) || cStatus != SUCCESS)
{
return 3;
}
Delay100uS(50);
}
//写块No.4
cPa = ComWriteBlock4;
Send_IIC_Command(cPa);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != cPa[1]) || cStatus != SUCCESS)
{
return 4;
}
//读块No.4
cPa = ComReadBlock4;
Send_IIC_Command(cPa);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != cPa[1]) || cStatus != SUCCESS)
{
return 5;
}
//比较数据
cPa = &ComWriteBlock4[10];
cPb = &g_cReceBuf[2];
if (memcmp(cPa, cPb, 16) != 0)
{
return 6;
}
//初始化No.5 作为钱包初值为0x12345678
cPa = ComIntiPurse5;
Send_IIC_Command(cPa);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != cPa[1]) || cStatus != SUCCESS)
{
return 7;
}
//增值No.5 = "2"
cPa = ComIncrPurse5;
Send_IIC_Command(cPa);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != cPa[1]) || cStatus != SUCCESS)
{
return 8;
}
//减值 "1"
cPa = ComDecrPurse5;
Send_IIC_Command(cPa);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != cPa[1]) || cStatus != SUCCESS)
{
return 9;
}
//restore the purse in block No.5 to block No.6
cPa = ComBakPurse56;
Send_IIC_Command(cPa);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != cPa[1]) || cStatus != SUCCESS)
{
return 10;
}
//读最后的值No.6
cPa = ComReadPurse6;
Send_IIC_Command(cPa);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != cPa[1]) || cStatus != SUCCESS)
{
return 11;
}
cPa = pursevalue;
cPb = &g_cReceBuf[2];
if (memcmp(cPa, cPb, 4) != 0)
{
return 12;
}
cPa = ComHaltMCU;
Send_IIC_Command(cPa);
cStatus = Read_Iic_Data(g_cReceBuf);
if ((g_cReceBuf[1] != cPa[1]) || cStatus != SUCCESS)
{
return 13;
}
return SUCCESS;
}
/*****************************************************************************
* 发光管错误指示
*****************************************************************************/
void ShowError(unsigned char cTimes)
{
Delay100uS(5000);
while (cTimes--)
{
LED_error = 0;
Delay100uS(1000);
LED_error = 1;
Delay100uS(1000);
}
}
/*****************************************************************************
错误,蜂鸣器1s
*****************************************************************************/
void Err()
{
BEEP = 1;
Delay100uS(1000);
BEEP = 0;
}
/*****************************************************************************
系统初始化
*****************************************************************************/
void InitializeSystem()
{
TMOD = 0x21;
PCON |= 0x80;
SCON = 0xD0;
TH1 = 0xFD;
TL1 = TH1;
TR1 = 0;
IE |= 0x00;
}/*****************************************************************************
*IIC start condition
*****************************************************************************/
void I2CStart(void)
{
SDA = 1;
_nop_();
SCL = 1;
_nop_();
SDA = 0;
_nop_();
_nop_();
SCL = 0;
}
/*****************************************************************************
*IIC stop condition
*****************************************************************************/
void I2CStop(void)
{
SCL = 0;
_nop_();
SDA = 0;
_nop_();
_nop_();
SCL = 1;
_nop_();
SDA = 1;
}
/*****************************************************************************
*IIC wait ACK
*****************************************************************************/
bit I2CWaitAck(void)
{
unsigned char cErrTime = 255;
SDA = 1;
_nop_();
_nop_();
SCL = 1;
_nop_();
while(SDA)
{
cErrTime--;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if (0 == cErrTime)
{
I2CStop();
return FAILURE;
}
}
SCL = 0;
return SUCCESS;
}
/*****************************************************************************
*IC send ACK
*****************************************************************************/
void I2CSendAck(void)
{
_nop_();
SDA = 0;
_nop_();
_nop_();
SCL = 1;
_nop_();
SCL = 0;
}
/*****************************************************************************
*IIC send Not ACK
*****************************************************************************/
void I2CSendNotAck(void)
{
_nop_();
SDA = 1;
_nop_();
_nop_();
SCL = 1;
_nop_();
SCL = 0;
}
/*****************************************************************************
*IIC发送一个字节
*****************************************************************************/
void I2CSendByte(unsigned char cSendByte)
{
unsigned char data i = 8;
while (i--)
{
SCL = 0;
_nop_();
SDA = (bit)(cSendByte & 0x80);
cSendByte += cSendByte;
_nop_();
_nop_();
SCL = 1;
_nop_();
}
SCL = 0;
_nop_();
}
/*****************************************************************************
接收IIC一个字节
*****************************************************************************/
unsigned char I2CReceiveByte(void)
{
unsigned char data i = 8;
unsigned char data cR_Byte = 0;
SDA = 1;
while (i--)
{
cR_Byte += cR_Byte;
SCL = 0;
_nop_();
_nop_();
SCL = 1;
_nop_();
cR_Byte |= (unsigned char)SDA;
_nop_();
}
SCL = 0;
return cR_Byte;
}
/*****************************************************************************
读取IIC返回的数据
*****************************************************************************/
unsigned char Read_Iic_Data(unsigned char *cP)
{
unsigned char cCnt;
unsigned char cCheckSum = 0;
for (cCnt=0; cCnt<0xFF; cCnt++)
{
Delay100uS(1);
I2CStart();
I2CSendByte(READ_M101XX);
if (I2CWaitAck() == SUCCESS)
{
LED_UART = ~LED_UART;
break;
}
}
if (0xFF == cCnt)
{
return FAILURE;
}
cP[0]=2;
for (cCnt=0; cCnt<cP[0]; cCnt++) // in the protocol, cP[0] is the length of this data package
{
cP[cCnt] = I2CReceiveByte();
I2CSendAck();
cCheckSum ^= cP[cCnt];
}
cP[cCnt] = I2CReceiveByte();
I2CSendNotAck();
I2CStop();
if (cCheckSum != cP[cCnt])
{
return FAILURE;
}
else
{
return SUCCESS;
}
}
/*****************************************************************************
发送控制器命令
*****************************************************************************/
unsigned char Send_IIC_Command(unsigned char *cP)
{
unsigned char i;
unsigned char cCheckSum = 0;
I2CStart();
I2CSendByte(WRITE_M101XX);
if (I2CWaitAck() == SUCCESS)
{
for(i=0; i<cP[0]; i++)
{
cCheckSum ^= cP[i];
I2CSendByte(cP[i]);
if (I2CWaitAck() != SUCCESS)
{
return FAILURE;
}
}
I2CSendByte(cCheckSum);
if (I2CWaitAck() != SUCCESS)
{
return FAILURE;
}
I2CStop();
return SUCCESS;
}
else
{
return FAILURE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -