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)
|