智能RFID刷卡扣费系统

/*——————————————————————————
* @文件名        : 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(); 
        }
    }

}

© 版权声明

相关文章

暂无评论

none
暂无评论...