标题:
stm32驱动mfrc522源码
[打印本页]
作者:
cjyg
时间:
2018-4-21 18:15
标题:
stm32驱动mfrc522源码
stm32驱动mfrc522单片机源程序如下:
//MDK V3.5编程模板2说明
//基本源文件结构
/*
在任何地方建一个与工程名相关的文件夹,再在这个文件夹下建立如下结构的文件夹
User/SysTick文件夹及其它需要用到的用户文件夹,如LCD等
Libraries/cmsis startup/arm src inc
Project/list out及Keil MDK工程文件
//
从STM32固件库v3.5中找出所需文件并复制到所建立的文件夹中
1:User\system_stm32f10x.c stm32f10x_it.c stm32f10x_it.h stm32f10x_conf.h
2:User\SysTick\stm32f10x_systick.c stm32f10x_systick.h
在STM32固件库v3.5没有提供stm32f10x_systick.c stm32f10x_systick.h
可从STM32固件库v2.0中找到,复制过来后要对这两文件修改一下才能用
方法是:(先把SysTick的只读属性去掉)
(1):对stm32f10x_systick.c中的函数SysTick_CLKSourceConfig(u32 SysTick_CLKSource)
注释掉。
(2):对stm32f10x_systick.h中的#define SysTick_CLKSource_HCLK_Div8 ((u32)0xFFFFFFFB)
#define SysTick_CLKSource_HCLK ((u32)0x00000004)
注释掉。
(3):#include "stm32f10x_map.h"改为#include "stm32f10x.h"
3:Libraries/cmsis/core_cm3.c core_cm3.h stm32f10x.h system_stm32f10x.h
4:Libraries/startup/arm/所有8个ARM的启动文件
5:Libraries/src\mise.c和所有外设C文件
6:Libraries/inc\mise.h和所有外设H文件
//
添加完文件后用记事本或其它C文件编辑工具编写一个名为main.c内容如下的文件保存到User中
//
#include "stm32f10x.h"
#include "stm32f10x_systick.h"
//
int main(void)
{
while (1)
{
}
}
//
*/
//基本工程文件结构
/*
完成以上工作后,打开Keil新建一个工程保存到Project中
选择CUP确定后在弹出的添加启动文件询问窗中选择否,这样就建好了一个空的工程文件
把工程的标签改成与工程名一样,当然也可不同或不改,然后在工程中加入以下文件组
User
CMSIS
StartUp
StdPeriphDriver
SysTick
//
接下来从源文件中给文件组添加文件
1:User/main.c stm32f10x_it.c
2:CMSIS/core_cm3.c system_stm32f10x.c
3:StartUp/startup_stm32f10x.hd.s(这个文件是根据所用的CPU来确定的)
4:StdPeriphDriver/misc.c stm32f10x_rcc.c stm32f10x_fsmc.c stm32f10x_gpio.c以及其它选用的外设C文件
5:SysTick/stm32f10x_systick.c
*/
//接下来要设置工程文件的一些属性选项
/*
打开工程的属性框
OutPut选项卡中
将Select Folder For Object指定到Out文件夹
勾选Great Hex File(生成Hex文件)
//
Listing选项卡中
将Select Folder For Listings指定到List文件夹
//
C/C++选项卡中
根据所用CPU选择下列条目复制到define栏
USE_STDPERIPH_DRIVER,STM32F10X_LD
USE_STDPERIPH_DRIVER,STM32F10X_MD
USE_STDPERIPH_DRIVER,STM32F10X_HD
头文件包含路径设定(所有有头文件的文件夹)
在include paths添加所有有头文件的文件夹路径
../../Libraries/inc;
../../Libraries/cmsis;
../../User
../../User/systick
也可只添加有头文件的根目录,此时必须在包含头文件前加上一级的文件名
如:#include "SysTick/stm32f10x_systick.h" stm32f10x_systick.h的上一级是SysTick
另外勾选C/C++选项卡中的One ELF Section Per Function后生成的代码得到优化
*/
//最后编译这个没有任何功能的工程,看是否有错误和警告。
//如有则修改直至通过,之后就可以根据需要添加各种功能函数了。
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "TouchPanel/TouchPanel.h"
#include "SysTick/stm32f10x_systick.h"
#include "LCD/LCD.h"
#include "LCD/AsciiLib.h"
#include "LCD/Chinese16Lib.h"
#include "MFRC522/MFRC522.h"
//BEE控制定义(PA.13)当x=1时蜂鸣器响,当x=0时蜂鸣器不响
#define BEE_Cont(x) x ? GPIO_SetBits(GPIOA,GPIO_Pin_13):GPIO_ResetBits(GPIOA,GPIO_Pin_13)
//延时函数
void Delay1(u32 nCount)
{
for(; nCount != 0; nCount--);
}
//蜂鸣器函数
void SoundBEE(void)
{
BEE_Cont(1);
Delay1(20000);
BEE_Cont(0);
}
//端口初始化函数
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//打开APB2总线上的GPIOA-D时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|
RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE,
ENABLE);
//打开APB2总线上的AFIO时钟(IO复用功能)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//开启USART2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
//释放调试口为通用IO
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
//(BEE)PA13
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//(JOG)PC10=C_key, PC11=R_key, PC12=ENTER_key
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//设置USART2的Tx脚(PA2)为推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA , &GPIO_InitStructure);
//设置USART2的Rx脚(PA3)为浮空输入脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA , &GPIO_InitStructure);
}
//串口2初始化函数
void USART2_Configuration(void)
{
//定义USART初始化结构体 USART_InitStructure
USART_InitTypeDef USART_InitStructure;
/*
* 波特率为9600bps
* 8位数据长度
* 1个停止位,无校验
* 禁用硬件流控制
* 禁止USART时钟
* 时钟极性低
* 在第2个边沿捕获数据
* 最后一位数据的时钟脉冲不从 SCLK 输出
*/
//如果波特率是9600就用默认的值来初始化串口就行了
USART_StructInit(&USART_InitStructure); //获取默认的初始化值
//如果用其它值则用以下语句
//USART_InitStructure.USART_BaudRate = 9600;
//USART_InitStructure.USART_WordLength = USART_WordLength_8b;
//USART_InitStructure.USART_StopBits = USART_StopBits_1;
//USART_InitStructure.USART_Parity = USART_Parity_No ;
//USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
//USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2 , &USART_InitStructure); //初始化串口2
//使能接收中断,用中断方式接收数据
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //当用查询方式接收数据时不用此句
USART_Cmd(USART2 , ENABLE); //使能USART2
}
//配置USART2中断
void NVIC_USART2_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
//
NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x00);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //选择中断分组0
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //选择串口2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占式中断优先级设置为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应式中断优先级设置为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断
NVIC_Init(&NVIC_InitStructure);
}
//设SysTick定时器重装时间
void SysTick_Configuration(void)
{
SysTick_CounterCmd(SysTick_Counter_Disable); //关闭定时器
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); //选择HCLK为时钟源
SysTick_CounterCmd(SysTick_Counter_Clear); //定时器清0
//主频为72MHz,配置计时值为72000*20可得到20ms的定时
SysTick_SetReload(72000*20);
SysTick_CounterCmd(SysTick_Counter_Enable); //启动定时器
}
//
//数字的ASCII码
uc8 numberascii[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
//显示缓冲区
u8 dispnumber5buf[6];
u8 dispnumber3buf[4];
u8 dispnumber2buf[3];
//MFRC522数据区
u8 mfrc552pidbuf[18];
u8 card_pydebuf[2];
u8 card_numberbuf[5];
u8 card_key0Abuf[6]={0xff,0xff,0xff,0xff,0xff,0xff};
u8 card_writebuf[16]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
u8 card_readbuf[18];
//SM05-S数据区
u8 sm05cmdbuf[15]={14,128,0,22,5,0,0,0,4,1,157,16,0,0,21};
//extern声明变量已在外部的C文件里定义,可以在主文件中使用
extern u8 sm05receivebuf[16]; //在中断C文件里定义
extern u8 sm05_OK; //在中断C文件里定义
//
extern u16 myGBlength; //在汉字库C文件里定义
//触摸屏数据区
extern Coordinate TouchSample[3]; //3组触摸坐标取样
extern Coordinate DisplaySample[3]; //3组显示坐标取样
extern Coordinate dispcoordinate; //1组显示坐标
extern Matrix matrix; //坐标转换参数
//16进显示
void GetHexAscii(u8 *buf,u8 dat)
{
u8 i,buffer[3];
//
buffer[0]=numberascii[dat/16];
buffer[1]=numberascii[dat%16];
buffer[2]=0; //结束标志为0
//
for(i=0;i<3;i++)
buf[i]=buffer[i];
}
//百以内10进显示
void GetNumberAscii_3(u8 *buf,u8 dat)
{
u8 i,buffer[4];
//
buffer[0]=numberascii[dat/100%10];
buffer[1]=numberascii[dat/10%10];
buffer[2]=numberascii[dat%10];
buffer[3]=0; //结束标志为0
//
for(i=0;i<4;i++)
buf[i]=buffer[i];
}
//万以内10进显示
void GetNumberAscii_5(u8 *buf,u16 dat)
{
u8 i,buffer[6];
//
buffer[0]=numberascii[dat/10000%10];
buffer[1]=numberascii[dat/1000%10];
buffer[2]=numberascii[dat/100%10];
buffer[3]=numberascii[dat/10%10];
buffer[4]=numberascii[dat%10];
buffer[5]=0; //结束标志为0
//
for(i=0;i<6;i++)
buf[i]=buffer[i];
}
//MFRC522测试函数
void MFRC522Test(void)
{
u8 i,j,status,card_size;
//
status=MFRC522_Request(0x52, card_pydebuf); //寻卡
//
if(status==0) //如果读到卡
{
status=MFRC522_Anticoll(card_numberbuf); //防撞处理
card_size=MFRC522_SelectTag(card_numberbuf); //选卡
status=MFRC522_Auth(0x60, 4, card_key0Abuf, card_numberbuf); //验卡
status=MFRC522_Write(4, card_writebuf); //写卡(写卡要小心,特别是各区的块3)
status=MFRC522_Read(4, card_readbuf); //读卡
//MFRC522_Halt(); //使卡进入休眠状态
//卡类型显示
GetHexAscii(dispnumber2buf,card_pydebuf[0]);
GUI_Text( 82,160, White,Blue,dispnumber2buf);
GetHexAscii(dispnumber2buf,card_pydebuf[1]);
GUI_Text(102,160, White,Blue,dispnumber2buf);
//卡序列号显,最后一字节为卡的校验码
for(i=0;i<5;i++)
{
GetHexAscii(dispnumber2buf,card_numberbuf[i]);
GUI_Text( 82+20*i,144, White,Blue,dispnumber2buf);
if(i==4) //用红色显示校验码
GUI_Text( 82+20*i,144, Red,Blue,dispnumber2buf);
}
//卡容量显示,单位为Kbits
GetNumberAscii_3(dispnumber3buf,card_size);
GUI_Text( 82,128, White,Blue,dispnumber3buf);
//读卡状态显示,正常为0
GetHexAscii(dispnumber2buf,status);
GUI_Text(82,112, White,Blue,dispnumber2buf);
//读一个块的数据显示
for(i=0;i<2;i++) //分两行显示
{
for(j=0;j<9;j++) //每行显示8个
{
GetHexAscii(dispnumber2buf,card_readbuf[j+i*9]); //16进显示
GUI_Text(82+j*20,96-i*16, White,Blue,dispnumber2buf);
}
}
//画下横线的数据为
LCD_DrawLine(220,80,260,80,Green);
//
SoundBEE();
}
}
//写SM05的指令函数
void SM05SendCmd(void)
{
u8 i=0;
//
//清除标志位,否则第1位数据会丢失
USART_ClearFlag(USART2,USART_FLAG_TC);
//
for(i=0;i<15;i++)
{
USART_SendData(USART2, sm05cmdbuf[i]);
//等待发完一个字节
while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
}
}
//显示接收SM05的数据函数
void DiscSM05ReceiveData(void)
{
u8 i,j;
u16 card_number;
//
for(i=0;i<2;i++) //分两行显示
{
for(j=0;j<8;j++) //每行显示8个
{
GetNumberAscii_3(dispnumber3buf,sm05receivebuf[j+i*8]);
GUI_Text(82+j*30,32-i*16, White,Blue,dispnumber3buf);
}
}
//画下线的数据为卡代码
LCD_DrawLine(233,15,286,15,Red);
//读卡成功
if(sm05_OK==1)
{
sm05_OK=0;
SoundBEE();
//计算卡代码并显示
card_number=sm05receivebuf[13]*256+sm05receivebuf[14];
GetNumberAscii_5(dispnumber5buf,card_number);
GUI_Text(82,0, Green,Blue,dispnumber5buf);
}
}
//飞梭连接定义
#define JOG_A 0x40 //JOG动态值1
#define JOG_B 0x80 //JOG动态值2
#define JOGVAL1 0xc0 //静态标志1
#define JOGVAL2 0x00 //静态标志1
#define STATE1 0x55 //动态标志1
#define STATE2 0xaa //动态标志2
#define COROTATION 0x55 //JOG正转标志
#define REVERSE 0xaa //JOG反转标志
#define JOGPORT GPIOC //JOG接口
//HEX 正转40 00 80 C0 反转80 00 40 C0
//(PC11)A:0->0->1->1 1->0->0->1
//(PC10)B:1->0->0->1 0->0->1->1
// 0 0 0 0 0 0 0 0
// 0 0 0 0 0 0 0 0
//旋转轮
u8 JOG_Check(void)
{
u8 key,jogmode;
static u8 state_A,state_B,jog_count;
//根据JOG的硬件连接情况,把读入的16位数据转成8位数据以方便处理(8位CPU不用转换)
key=(u8)(GPIO_ReadInputData(JOGPORT)>>4)&JOGVAL1; //读JOG
//读到JOG的静态值是0xc0或0x00,读到JOG旋转动态值是0x80或0x40
if(key!=JOGVAL1) //如果JOG旋转
{
//第一状态检测
if(key==JOG_A) //当为0x40时
state_A=STATE1; //保存动态标志值
//第二状态检测
if(key==JOG_B) //当为0x80时
state_B=STATE2; //保存动态标志值
}
//如果是正转 0x80->0xc0 0x40->0x00
if(((state_B==STATE2)&&(key==JOGVAL1))||((state_A==STATE1)&&(key==JOGVAL2)))
{
state_A=0;
state_B=0;
jogmode=COROTATION; //回返正转值
//
jog_count++;
//
GetHexAscii(dispnumber2buf,jog_count);
GUI_Text(32,218, Green,Blue,dispnumber2buf);
//
SoundBEE();
}
//如果是反转 0x40->0xc0 0x80->0x00
if(((state_A==STATE1)&&(key==JOGVAL1))||((state_B==STATE2)&&(key==JOGVAL2)))
{
state_A=0;
state_B=0;
jogmode=REVERSE; //回返反转值
//
jog_count--;
//
GetHexAscii(dispnumber2buf,jog_count);
GUI_Text(32,218, Red,Blue,dispnumber2buf);
//
SoundBEE();
}
//
return jogmode;
}
//中间键
void KeyEnterFunctional(void)
{
u8 key;
static u8 keyscan,entercont=0xaa;
//
key=(u8)(GPIO_ReadInputData(JOGPORT)>>8&0x10);
//
if(key!=0x10)
{
if(((key&0x10)==0)&&((keyscan&0x10)!=0))
{
entercont=~entercont;
//
if(entercont==0x55)
{
GUI_Text(2,218, Green,Blue,"开");
}
else
{
GUI_Text(2,218, Red,Blue,"关");
}
//
SoundBEE();
}
}
//
keyscan=key;
}
//主函数
int main(void)
{
u8 i,j;
u16 count;
//
GPIO_Configuration(); //初始化端口
//
Delay1(2000);
BEE_Cont(0); //关BEE
SysTick_Configuration(); //SysTick定时器屏初化
Touch_Initializtion(); //触摸屏初化
LCD_Initializtion(); //LCD初始化
MFRC522_Initializtion(); //初始化MFRC522
USART2_Configuration(); //初始化USART2
NVIC_USART2_Configuration(); //USART2中断配置
//
//TouchPanel_Calibrate(); //触摸屏校准
//
LCD_Clear(Blue); //清屏成蓝色
Delay1(20000);
//画水平线
LCD_DrawLine(0,180,320,180,Green);
//画垂直线
//LCD_DrawLine(80,0,80,180,Green);
//
GUI_Text(88,218, Red,Blue,"STM32+触摸屏学习板");
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
MFRC522_Pro.rar
(338.01 KB, 下载次数: 87)
2018-4-21 23:57 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
zhang@#
时间:
2019-10-27 14:39
请问用的是那个处理器?
作者:
Jy0607
时间:
2023-4-3 19:08
用得到学习下!谢谢楼主共享资料.
作者:
xiang8000
时间:
2023-11-2 14:52
这是STM32F几的CPU?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1