一、前言
针对传统超市购物车结账排队时间长、付款效率低的问题,提出了一种更符合现代社会人们购物方式-基于RFID的自助收银系统。习惯了快节奏生活的人们都会选择自助收银机结账,理由显而易见:自助收银机结账很方便,几乎不用排队,也不用近距离和收银员接触,在防疫时期特别感觉安心。而且自助结账对每件物品的售价更是一次清晰地核对,最终需支付合计购物支出自己也更加清晰明了;这两年来,越来越多的智能设备应用在我们的生活领域里,为我们的生活提供了很多智能和便利。自助收银机从几年前就陆续涌入到各地商场、超市、便利店,自去年疫情发生后自助收银的需求比例更是呈直线上升趋势。自助收银机的启用,不仅节约了超市的人力开支成本,也从根本上提升了超市的购物支付效率,在这个快节奏的社会里,智能自助收银机也从根本上提升了超市等购物场所的服务质量。
本次设计的->基于RFID的自助收银系统<-设计主要支持的功能如下:
- RFID会员卡充值消费,可以在收银机上查询卡里的余额,个人信息。
- 商品信息的录入上架。
- 会员卡注册、充值、消费、挂失 付款是从会员卡里扣钱消费,付款完成后,采用步进电机模拟闸机开门,顾客可以离去。
硬件上采用STM32作为主控芯片,完成IC卡读写,控制步进电机-闸机。 上位机采用QT设计,语言采用C ,STM32与上位机之间使用串口进行交互没,完成整个功能设计。
二、硬件选型
2.1 步进电机
2.2 RC522 刷卡模块
2.3 STM32系统板
2.4 蜂鸣器
蜂鸣器是为了有交互声音,刷卡可以滴一声,明白刷卡成功。 当前最终的成品采用了LED来代替。
三、STM32程序设计
3.1 硬件原理
设备端采用STM32F103C8T6,刷卡模块采用RFID-RC522。
STM32设备端设计的就是一个读卡器,用来读取电子标签,会员卡等信息,将卡号上传给上位机完成处理。
在设备硬件上以一个白色LED灯,每次刷卡成功灯会闪烁一次,表示刷卡成功。
上传给上位机的数据格式如下:
代码语言:javascript复制卡类型:0x4 0x0
卡号:0x11 0xAD 0x40 0x2E
$update,171736446,
上位机解析的数据是: $update,171736446,
顾客付款成功后,下发指令open_lock
给设备,打开超市门闸机。
3.2 硬件接线
代码语言:javascript复制相关的硬件连接引脚说明:
1. RC522射频模块外部的接口:
*1--SDA <----->PB5--片选脚
*2--SCK <----->PB4--时钟线
*3--MOSI<----->PA12--输出
*4--MISO<----->PA11--输入
*5--悬空
*6--
*7--RST <----->PA8--复位脚
*8--VCC <----->VCC
2. LED灯
GND <----->GND
VCC <----->VCC
DAT <----->PA5
3. ULN2003控制28BYJ-48步进电机接线:
ULN2003接线:
IN4: PB9 d
IN3: PB8 c
IN2: PB7 b
IN1: PB6 a
: 5V
- : GND
3.3 硬件实物图
3.4 main.c代码
代码语言:javascript复制#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include <string.h>
#include "timer.h"
#include "RFID_RC522.h"
#include "motor.h"
#define LED PAout(5)
//u8 KEY[6]={0xff,0xff,0xff,0xff,0xff,0xff}; //卡密码-初始密码--白卡的出厂密码--
//u8 MIMA_1[16]={88,88,88,88,88,88,0xff,0x07,0x80,0x29,88,88,88,88,88,88}; //扇区1的密码 格式(A密码 控制位 B密码 )
//u8 MIMA_2[16]={88,88,88,88,88,88};//扇区1的A密码
unsigned char SN[4]={88,88,88,88}; //默认卡号
char SendBuff[10];
/*
函数功能: 打印卡号
*/
void print_info(unsigned char *p,int cnt)
{
int i;
for(i=0;i<cnt;i )
{
printf("0x%X ",p[i]);
}
printf("rn");
}
/*
函数功能: 读卡号--电子标签的卡号
返回值: 1成功 0失败
*/
int ReadCardNumber(void)
{
unsigned char CT[2];//卡类型
u8 status=1;
status=RC522_PcdRequest(PICC_REQIDL ,CT);//(寻卡模式,卡类型),成功返回0
if(status==MI_OK)//寻卡成功
{
status=MI_ERR;
status=RC522_PcdAnticoll(SN); //防冲撞,成功返回0,SN是读到卡号的地址
printf("卡类型:");
print_info(CT,2);//打印类型
printf("卡号:");
print_info(SN,4);//打印卡号
return 1;
}
return 0;
}
/*
函数功能: 主函数
*/
int main()
{
u32 cnt=0;
u8 key;
LED_Init();
KEY_Init();
USART1_Init(115200);
TIMER1_Init(72,20000); //超时时间20ms
RC522_Init(); //RC522
Moto_Init(); //步进电机初始化
RCC->APB2ENR|=1<<2;
GPIOA->CRL&=0xFF0FFFFF;
GPIOA->CRL|=0x00300000;
printf("正在初始化稍等.n");
while(1)
{
key=KEY_Scan(0);
if(key)
{
LED1=!LED1;
printf("按键测试.rn");
Motorcw_ring(1,300); //电机正转1圈
}
cnt ;
delay_ms(10);
if(cnt>=20)
{
cnt=0;
LED1=!LED1;
}
//读取卡号
if(ReadCardNumber())
{
sprintf(SendBuff,"$update,%d%d%d%d,",SN[0],SN[1],SN[2],SN[3]);
printf("%srn",SendBuff);
LED=1;
delay_ms(1000);
LED=0;
}
//客户付款成功后,收银系统发送指令下来,打开超市闸机门
if(USART1_RX_FLAG)
{
USART1_RX_BUFFER[USART1_RX_CNT]='