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中的函數(shù)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內(nèi)容如下的文件保存到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(這個文件是根據(jù)所用的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++選項卡中
- 根據(jù)所用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后生成的代碼得到優(yōu)化
- */
- //最后編譯這個沒有任何功能的工程,看是否有錯誤和警告。
- //如有則修改直至通過,之后就可以根據(jù)需要添加各種功能函數(shù)了。
- /* 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)
- //延時函數(shù)
- void Delay1(u32 nCount)
- {
- for(; nCount != 0; nCount--);
- }
- //蜂鳴器函數(shù)
- void SoundBEE(void)
- {
- BEE_Cont(1);
- Delay1(20000);
- BEE_Cont(0);
- }
- //端口初始化函數(shù)
- 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);
- //釋放調(diào)試口為通用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初始化函數(shù)
- void USART2_Configuration(void)
- {
- //定義USART初始化結構體 USART_InitStructure
- USART_InitTypeDef USART_InitStructure;
- /*
- * 波特率為9600bps
- * 8位數(shù)據(jù)長度
- * 1個停止位,無校驗
- * 禁用硬件流控制
- * 禁止USART時鐘
- * 時鐘極性低
- * 在第2個邊沿捕獲數(shù)據(jù)
- * 最后一位數(shù)據(jù)的時鐘脈沖不從 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
- //使能接收中斷,用中斷方式接收數(shù)據(jù)
- USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //當用查詢方式接收數(shù)據(jù)時不用此句
- 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; //搶占式中斷優(yōu)先級設置為0
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //響應式中斷優(yōu)先級設置為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); //啟動定時器
- }
- //
- //數(shù)字的ASCII碼
- uc8 numberascii[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
- //顯示緩沖區(qū)
- u8 dispnumber5buf[6];
- u8 dispnumber3buf[4];
- u8 dispnumber2buf[3];
- //MFRC522數(shù)據(jù)區(qū)
- 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數(shù)據(jù)區(qū)
- 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文件里定義
- //觸摸屏數(shù)據(jù)區(qū)
- extern Coordinate TouchSample[3]; //3組觸摸坐標取樣
- extern Coordinate DisplaySample[3]; //3組顯示坐標取樣
- extern Coordinate dispcoordinate; //1組顯示坐標
- extern Matrix matrix; //坐標轉換參數(shù)
- //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];
- }
- //百以內(nè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];
- }
- //萬以內(nè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測試函數(shù)
- 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); //寫卡(寫卡要小心,特別是各區(qū)的塊3)
- status=MFRC522_Read(4, card_readbuf); //讀卡
- //MFRC522_Halt(); //使卡進入休眠狀態(tài)
- //卡類型顯示
- GetHexAscii(dispnumber2buf,card_pydebuf[0]);
- GUI_Text( 82,160, White,Blue,dispnumber2buf);
- GetHexAscii(dispnumber2buf,card_pydebuf[1]);
- GUI_Text(102,160, White,Blue,dispnumber2buf);
- //卡序列號顯,最后一字節(jié)為卡的校驗碼
- 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);
- //讀卡狀態(tài)顯示,正常為0
- GetHexAscii(dispnumber2buf,status);
- GUI_Text(82,112, White,Blue,dispnumber2buf);
- //讀一個塊的數(shù)據(jù)顯示
- 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);
- }
- }
- //畫下橫線的數(shù)據(jù)為
- LCD_DrawLine(220,80,260,80,Green);
- //
- SoundBEE();
- }
- }
- //寫SM05的指令函數(shù)
- void SM05SendCmd(void)
- {
- u8 i=0;
- //
- //清除標志位,否則第1位數(shù)據(jù)會丟失
- USART_ClearFlag(USART2,USART_FLAG_TC);
- //
- for(i=0;i<15;i++)
- {
- USART_SendData(USART2, sm05cmdbuf[i]);
- //等待發(fā)完一個字節(jié)
- while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
- }
- }
- //顯示接收SM05的數(shù)據(jù)函數(shù)
- 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);
- }
- }
- //畫下線的數(shù)據(jù)為卡代碼
- 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動態(tài)值1
- #define JOG_B 0x80 //JOG動態(tài)值2
- #define JOGVAL1 0xc0 //靜態(tài)標志1
- #define JOGVAL2 0x00 //靜態(tài)標志1
- #define STATE1 0x55 //動態(tài)標志1
- #define STATE2 0xaa //動態(tài)標志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;
- //根據(jù)JOG的硬件連接情況,把讀入的16位數(shù)據(jù)轉成8位數(shù)據(jù)以方便處理(8位CPU不用轉換)
- key=(u8)(GPIO_ReadInputData(JOGPORT)>>4)&JOGVAL1; //讀JOG
- //讀到JOG的靜態(tài)值是0xc0或0x00,讀到JOG旋轉動態(tài)值是0x80或0x40
- if(key!=JOGVAL1) //如果JOG旋轉
- {
- //第一狀態(tài)檢測
- if(key==JOG_A) //當為0x40時
- state_A=STATE1; //保存動態(tài)標志值
- //第二狀態(tài)檢測
- if(key==JOG_B) //當為0x80時
- state_B=STATE2; //保存動態(tài)標志值
- }
- //如果是正轉 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;
- }
- //主函數(shù)
- 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, 下載次數(shù): 87)
2018-4-21 23:57 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|