/*——————————————————————————
* @文件名 : handle
* @描述 : 用户处理函数
* @作者 : 物联网项目组
* @日期 : 2023/04/01
* @版本 : V0.0.2
*******************************************************************************
本驱动函数使用指导流程:
1、添加本驱动的.c和.h文件
2、在main.c中调用LCD_Display_Init函数进行显示初始化
3、在main.c中调用RC522_Handle()进行显示和处理
******************************************************************************/
#include “handle.h”
#include “gpio_api.h”
#include “lcd.h”
#include “gui.h”
#include “stdio.h”
#include “string.h”
/******************************内部函数定义************************************/
#define RC522_SECTOR 1 // 用户可自行修改扇区,扇区范围0~16
#define SECTOR_BLOCKNUM 0 // 用户可自行修改块序号,范围0~2
uint8_t Sector_Addr_Date[16] = {0x00,0x04,0x08,0x0C,0x10,0x14,0x18,0x1C,0x20,
0x24,0x28,0x2C,0x30,0x34,0x38,0x3C}; //每个扇区第0块分别对应的数据块值
uint8_t Pass_Word[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; //扇区初始密码
/*****************************code start 3*************************************/
uint32_t Deduction_Value1=1;
uint32_t Deduction_Value2=5;
uint32_t recharge_Value1=100;
/*****************************code end 3*************************************/
uint8_t HEXvalue[4]={0}; // 4字节数值数组
/*******************************************************************************
卡的数据块有两种应用:数据保存模式–>操作有:读/写
数值模式——>操作有:初始化/加值/减值
*******************************************************************************/
uint8_t Wallet_Block_Date[16]={0}; // 16字节块数据
uint8_t Wallet_vlaue[4]={0x0a}; // 钱包数值
uint8_t RCC522_Work_Mode = 0; // RFID卡自定义操作模式参数
int32_t Card_Money = 0; // 卡里的金额
Key_Struct key1={1};
Key_Struct key2={2};
Key_Struct key3={3};
Key_Struct key4={4};
/*****************************内部函数宏定义***********************************/
static void BEEP_RING(void);
/*******************************************************************************
* 名 称:Key_Task
* 功 能:按键处理函数
* 入口参数:无
* 返 回 值:无
* 说 明:无
* 调用方法:外部函数
*******************************************************************************/
void Key_Task(void)
{
get_key_vlaue(&key1,Key1_Read_Vlaue);
Key_Handle(&key1);
get_key_vlaue(&key2,Key2_Read_Vlaue);
Key_Handle(&key2);
get_key_vlaue(&key3,Key3_Read_Vlaue);
Key_Handle(&key3);
get_key_vlaue(&key4,Key4_Read_Vlaue);
Key_Handle(&key4);
}
/*******************************************************************************
* 名 称:key1_end_handle
* 功 能:按键1按下松手处理函数
* 入口参数:无
* 返 回 值:无
* 说 明:无
*******************************************************************************/
void key1_end_handle(void)
{
/*****************************code start 4*************************************/
RCC522_Work_Mode=1;
printf(”
*******key1按下,请将RFID卡靠近感应区,当前工作模式为扣费金额1元*****
“);
Gui_Printf_Display((uint8_t*)”设置扣费金额1元模式”);
/*****************************code end 4*************************************/
}
/*******************************************************************************
* 名 称:key2_end_handle
* 功 能:按键2按下松手处理函数
* 入口参数:无
* 返 回 值:无
* 说 明:无
*******************************************************************************/
void key2_end_handle(void)
{
RCC522_Work_Mode = 2;
printf(”
*****key2按下,请将RFID卡靠近感应区,当前工作模式为扣费金额5元*****
“);
Gui_Printf_Display((uint8_t *)”设置扣费金额5元模式”);
}
/*******************************************************************************
* 名 称:key3_end_handle
* 功 能:按键3按下松手处理函数
* 入口参数:无
* 返 回 值:无
* 说 明:无
*******************************************************************************/
void key3_end_handle(void)
{
RCC522_Work_Mode = 3;
printf(”
*****key3按下,请将RFID卡靠近感应区,当前工作模式为充值金额100元*****
“);
Gui_Printf_Display((uint8_t *)”设置充值金额100元模式”);
}
/*******************************************************************************
* 名 称:key4_end_handle
* 功 能:按键4按下松手处理函数
* 入口参数:无
* 返 回 值:无
* 说 明:无
*******************************************************************************/
void key4_end_handle(void)
{
RCC522_Work_Mode = 4;
printf(”
*****key4按下,请将RFID卡靠近感应区,初始化RFID卡*****
“);
Gui_Printf_Display((uint8_t *)”设置初始化RFID卡模式”);
}
/*******************************************************************************
* 名 称:BEEP_RING
* 功 能:蜂鸣器提示
* 入口参数:无
* 返 回 值:无
* 说 明:蜂鸣器响400ms
* 调用方法:内部函数
*******************************************************************************/
static void BEEP_RING(void)
{
beep_open();
HAL_Delay(400);
beep_close();
}
/*******************************************************************************
* 名 称:Wallet_Data_Init
* 功 能:钱包数据初始化
* 入口参数:无
* 返 回 值:无
* 说 明:蜂鸣器响400ms
* 调用方法:外部函数
*******************************************************************************/
void Wallet_Data_Init(void)
{
uint8_t * pvlaue=NULL;
pvlaue=RC522_Get_VlaueBlock_Date(Wallet_vlaue,
Sector_Addr_Date[RC522_SECTOR]+SECTOR_BLOCKNUM); // 数值块数据初始化
memcpy(Wallet_Block_Date,pvlaue,16);
}
/*******************************************************************************
* 名 称:LCD_Display_Init
* 功 能:显示屏上电初始化显示
* 入口参数:无
* 返 回 值:无
* 说 明:无
* 调用方法:外部函数
*******************************************************************************/
void LCD_Display_Init(void)
{
/*按键初始化*/
KEY_Init();
/*显示屏初始化界面*/
LCD_Init();
LCD_Clear(BLUE);//清全屏蓝
LCD_Fill(0,lcddev.height-20,lcddev.width,lcddev.height,BLUE);
LCD_Fill(0,0,lcddev.width,20,BLUE);
Gui_StrCenter(0,10,WHITE,BLUE,(uint8_t *)”RFID刷卡消费充值实验”,16,1);
Show_Str(0,30,WHITE,BLUE,(uint8_t *)”—————————–“,16,1);
Show_Str(0,46,WHITE,BLUE,(uint8_t *)”本实验功能: “,16,1);
Gui_Appoint_Display(1,”按key1,设置扣费金额1元模式”);
Gui_Appoint_Display(2,”按key2,设置扣费金额5元模式”);
Gui_Appoint_Display(3,”按key3,设置充值金额100元模式”);
Gui_Appoint_Display(4,”按key4,初始化RFID卡”);
Gui_Appoint_Display(5,”—————————–“);
Gui_Appoint_Display(6,”*****请将RFID卡靠近感应区*****”);
}
/*******************************************************************************
* 名 称:Value_Change
* 功 能:将十进制数据转换成32位数据,并按照4字节小端模式存放在数组中
* 入口参数:DECValue:待转换十进制数据
* 返 回 值:toHEXValue:转换后的数组
* 说 明:无
* 调用方法:外部函数
*******************************************************************************/
void Value_Change(uint32_t *DECValue,uint8_t *toHEXValue)
{
memcpy(toHEXValue,(uint8_t*)DECValue,4);
}
/*******************************************************************************
* 名 称:RC522_Handle
* 功 能:RFID综合处理函数
* 入口参数:无
* 返 回 值:无
* 说 明:根据用户需求可自行修改
* 调用方法:外部函数
*******************************************************************************/
void RC522_Handle(void)
{
uint8_t status = 0;
uint8_t card_type[2] = {0}; //卡类型
uint8_t card_id[4] = {0}; //卡ID缓存
uint8_t card_money[16] = {0}; //卡里的余额
char str_code[50] = {0}; //显示屏显示缓冲数组
status = RC522_Search_Cards(PICC_REQALL, card_type); // 寻卡
if(status == MI_OK) // 防冲撞
{
status = MI_ERR;
status = RC522_Anticoll(card_id);
}
if(status == MI_OK) // 选定卡
{
status = MI_ERR;
status = RC522_Select_Cards(card_id);
}
if(status==MI_OK) // 验证卡片密码
{
status = MI_ERR;
status = RC522_Verification_Password(PICC_AUTHENT1A,
Sector_Addr_Date[RC522_SECTOR]+SECTOR_BLOCKNUM, Pass_Word, card_id);
}
if(RCC522_Work_Mode == 4)
{
if(status == MI_OK) // 初始化数据
{
status = MI_ERR;
printf(“RFID卡初始化中…
“);
/*****************************code start 5*************************************/
status=RC522_Write_Date(Sector_Addr_Date[RC522_SECTOR]
+SECTOR_BLOCKNUM,Wallet_Block_Date);
/*****************************code end 5*************************************/
if(status == MI_ERR)
{
RCC522_Work_Mode = 0;
printf(“RFID卡初始化失败
“);
}
else
{
printf(“RFID卡初始化成功
“);
}
}
}
if(status==MI_OK) //读取数据
{
RC522_Read_Date(Sector_Addr_Date[RC522_SECTOR] + SECTOR_BLOCKNUM, card_money);
/*判断RFID卡是否初始化*/
if(card_money[14] != Sector_Addr_Date[RC522_SECTOR] + SECTOR_BLOCKNUM)
{
RCC522_Work_Mode = 0;
printf(“此卡未初始化,请将此卡执行初始化操作
“);
Gui_Printf_Display((uint8_t *)”请将此卡先执行初始化操作”);
BEEP_RING();
return;
}
Card_Money = (uint32_t)(card_money[0] | (card_money[1] << 8) |
(card_money[2] << 16) | (card_money[3] << 24));
if(RCC522_Work_Mode == 1) // 扣款模式一
{
if(Card_Money <= 0)
{
printf(”
*****余额不足请充值*****
“);
Gui_Printf_Display((uint8_t *)”*****余额不足请充值*****”);
}
else
{
printf(“RFID卡扣费中…
“);
/*****************************code start 6*************************************/
Value_Change(&Deduction_Value1,&HEXvalue[0]);
status=
RC522_Deduction_Recharge(PICC_DECREMENT,
Sector_Addr_Date[RC522_SECTOR]+SECTOR_BLOCKNUM,HEXvalue);
/*****************************code end 6*************************************/
if(status == MI_OK)
{
printf(“RFID卡扣费成功
“);
}
else
{
printf(“RFID卡扣费失败
“);
}
}
}
else if(RCC522_Work_Mode == 2) // 扣款模式二
{
while(Card_Money>5)
{
printf(“RFID卡扣费中…
“);
Value_Change(&Deduction_Value2,&HEXvalue[0]);
status = RC522_Deduction_Recharge(PICC_DECREMENT,
Sector_Addr_Date[RC522_SECTOR]+SECTOR_BLOCKNUM, HEXvalue);
if(status == MI_OK)
{
printf(“RFID卡扣费成功
“);
Card_Money-=5;
Gui_Printf_Display((uint8_t*)”扣除成功”);
}
else
{
printf(“RFID卡扣费失败
“);
Gui_Printf_Display((uint8_t*)”扣除失败,余额不足”);
break;
}
}
}
else if(RCC522_Work_Mode == 3) // 充值模式三
{
#define MAX_BALANCE 200
if(Card_Money+100 >= MAX_BALANCE)
{
printf(“v
******余额已达上限(%d元),无法继续充值******v
“, MAX_BALANCE);
Gui_Printf_Display((uint8_t *)”******余额已达上限,无法继续充值******”);
}
else
{
printf(“RTID卡充值中…v
“);
Value_Change(&recharge_Value1, &HEXvalue[0]);
status = RC522_Deduction_Recharge(PICC_INCREMENT,
Sector_Addr_Date[RC522_SECTOR] + SECTOR_BLOCKNUM, HEXvalue);
}
if(status == MI_OK)
{
printf(“RFID卡充值成功
“);
}
else
{
printf(“RFID卡充值失败
“);
}
}
RCC522_Work_Mode = 0;
}
if(status==MI_OK) //读RFID卡数据
{
status = MI_ERR;
status = RC522_Read_Date(Sector_Addr_Date[RC522_SECTOR]+SECTOR_BLOCKNUM, card_money);
if(status == MI_ERR)
{
printf(“RFID卡读取失败
“);
Gui_Printf_Display((uint8_t *)”RFID卡读取失败”);
}
else if(card_money[14] == Sector_Addr_Date[RC522_SECTOR] + SECTOR_BLOCKNUM)
{
/*****************************code start 8*************************************/
Card_Money=(uint32_t)(card_money[0]|(card_money[1]<<8))|
(card_money[2]<<16|(card_money[3]<<24));
/*****************************code end 8*************************************/
/*显示当前余额*/
printf(“RFID卡当前余额:%d元
“, Card_Money);
sprintf(str_code,”当前金额 = %d元”,Card_Money);
Gui_Printf_Display((uint8_t *)str_code);
BEEP_RING();
status = MI_ERR;
RC522_Sleep();
}
}
}