基于STM32F103C8T6设计的智能门锁-CubeMX+Keil+HAL库

本文章涉及的一些模块驱动大致参考其它作者的代码(后面有添加作者文章链接),自己做了一些和任务需求相关的代码修改,主要是以应用为主,各个模块的驱动自己能看明白知道怎么用怎么改就行

使用模块:

  1. STM32F103C8T6最小系统板
  2. 矩阵键盘
  3. 0.96寸OLED显示屏
  4. MF-RC522模块
  5. BT24蓝牙模块
  6. AS608指纹模块
  7. 蜂鸣器

CubeMX基本配置

RCC:

SYS:

时钟树:

工程配置:

  1. 自己的工程名字
  2. 工程路径,不要有中文
  3. 选择MDK-ARM
  4. 选择自己有的包,有哪个用哪个,可以不跟我一样

一、矩阵键盘:

工作原理:通过检测行列的交叉点的电平来判断对应的按键是否按下

先确定好需要用到的引脚,KEY_OUT用来固定输出一个电平,KEY_IN用来检测按键按下时的电平跳变。

代码:

key.h:

#ifndef __KEY_H_
#define __KEY_H_

#include "main.h"
uint16_t KEY_Scan(void);

#endif

key.c:

#include "key.h"
uint16_t KEY_Scan(void){
	uint8_t KEY_Flag;
	HAL_GPIO_WritePin(KEY_OUT4_GPIO_Port,KEY_OUT4_Pin,GPIO_PIN_SET);  //OUT4
	HAL_GPIO_WritePin(KEY_OUT1_GPIO_Port,KEY_OUT1_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(KEY_OUT2_GPIO_Port,KEY_OUT2_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(KEY_OUT3_GPIO_Port,KEY_OUT3_Pin,GPIO_PIN_RESET);
	if(HAL_GPIO_ReadPin(KEY_IN1_GPIO_Port,KEY_IN1_Pin) == GPIO_PIN_SET)KEY_Flag = 15; //IN1
	if(HAL_GPIO_ReadPin(KEY_IN2_GPIO_Port,KEY_IN2_Pin) == GPIO_PIN_SET)KEY_Flag = 14; //IN2
	if(HAL_GPIO_ReadPin(KEY_IN3_GPIO_Port,KEY_IN3_Pin) == GPIO_PIN_SET)KEY_Flag = 13; //IN3
	if(HAL_GPIO_ReadPin(KEY_IN4_GPIO_Port,KEY_IN4_Pin) == GPIO_PIN_SET)KEY_Flag = 12; //IN4
	
	
	HAL_GPIO_WritePin(KEY_OUT3_GPIO_Port,KEY_OUT3_Pin,GPIO_PIN_SET);  //OUT3
	HAL_GPIO_WritePin(KEY_OUT1_GPIO_Port,KEY_OUT1_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(KEY_OUT2_GPIO_Port,KEY_OUT2_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(KEY_OUT4_GPIO_Port,KEY_OUT4_Pin,GPIO_PIN_RESET);
	if(HAL_GPIO_ReadPin(KEY_IN1_GPIO_Port,KEY_IN1_Pin) == GPIO_PIN_SET)KEY_Flag = 11; //IN1
	if(HAL_GPIO_ReadPin(KEY_IN2_GPIO_Port,KEY_IN2_Pin) == GPIO_PIN_SET)KEY_Flag = 10; //IN2
	if(HAL_GPIO_ReadPin(KEY_IN3_GPIO_Port,KEY_IN3_Pin) == GPIO_PIN_SET)KEY_Flag = 9; //IN3
	if(HAL_GPIO_ReadPin(KEY_IN4_GPIO_Port,KEY_IN4_Pin) == GPIO_PIN_SET)KEY_Flag = 8; //IN4

	
	HAL_GPIO_WritePin(KEY_OUT2_GPIO_Port,KEY_OUT2_Pin,GPIO_PIN_SET);  //OUT2
	HAL_GPIO_WritePin(KEY_OUT1_GPIO_Port,KEY_OUT1_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(KEY_OUT3_GPIO_Port,KEY_OUT3_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(KEY_OUT4_GPIO_Port,KEY_OUT4_Pin,GPIO_PIN_RESET);
	if(HAL_GPIO_ReadPin(KEY_IN1_GPIO_Port,KEY_IN1_Pin) == GPIO_PIN_SET)KEY_Flag = 7; //IN1
	if(HAL_GPIO_ReadPin(KEY_IN2_GPIO_Port,KEY_IN2_Pin) == GPIO_PIN_SET)KEY_Flag = 6; //IN2
	if(HAL_GPIO_ReadPin(KEY_IN3_GPIO_Port,KEY_IN3_Pin) == GPIO_PIN_SET)KEY_Flag = 5; //IN3
	if(HAL_GPIO_ReadPin(KEY_IN4_GPIO_Port,KEY_IN4_Pin) == GPIO_PIN_SET)KEY_Flag = 4; //IN4

	
	HAL_GPIO_WritePin(KEY_OUT1_GPIO_Port,KEY_OUT1_Pin,GPIO_PIN_SET);  //OUT1
	HAL_GPIO_WritePin(KEY_OUT2_GPIO_Port,KEY_OUT2_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(KEY_OUT3_GPIO_Port,KEY_OUT3_Pin,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(KEY_OUT4_GPIO_Port,KEY_OUT4_Pin,GPIO_PIN_RESET);
	if(HAL_GPIO_ReadPin(KEY_IN1_GPIO_Port,KEY_IN1_Pin) == GPIO_PIN_SET)KEY_Flag = 3; //IN1
	if(HAL_GPIO_ReadPin(KEY_IN2_GPIO_Port,KEY_IN2_Pin) == GPIO_PIN_SET)KEY_Flag = 2; //IN2
	if(HAL_GPIO_ReadPin(KEY_IN3_GPIO_Port,KEY_IN3_Pin) == GPIO_PIN_SET)KEY_Flag = 1; //IN3
	if(HAL_GPIO_ReadPin(KEY_IN4_GPIO_Port,KEY_IN4_Pin) == GPIO_PIN_SET)KEY_Flag = 0; //IN4
	
	return KEY_Flag;

}

main.c:

OLED_ShowNum();是OLED大约数字的函数,可以用自己的,我的在后面也有写

uint8_t KEY_TEXT;
KEY_TEXT = KEY_Scan();
		if(KEY_TEXT != NULL){
			HAL_Delay(20);
			
		}
		OLED_ShowNum(2,1,KEY_TEXT,2);

 二、OLED显示屏:

用的是江科大的oled驱动,但是江科大的是标准库,我这里把他改成hal库的了。

这里选两个引脚作为模拟iic的SDA引脚和SCL引脚,将引脚设置为输出模式

oled.h:

#ifndef __OLED_H
#define __OLED_H

//#include "stdint.h"
#include "main.h"


/*引脚配置*/

#define OLED_SCL			GPIO_PIN_6
#define OLED_SDA			GPIO_PIN_7
#define OLED_PROT  		GPIOB

#define OLED_W_SCL(x)		HAL_GPIO_WritePin(OLED_PROT, OLED_SCL, (GPIO_PinState)(x))
#define OLED_W_SDA(x)		HAL_GPIO_WritePin(OLED_PROT, OLED_SDA, (GPIO_PinState)(x))



void OLED_Init(void);
void OLED_Clear(void);
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char);
void OLED_ShowString(uint8_t Line, uint8_t Column, char *String);
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length);
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length);
void OLED_ShowChinese(uint8_t Line, uint8_t Column, uint8_t num);
#endif

oled.c:

#include "OLED.h"
#include "OLED_Font.h"
/*引脚初始化*/
void OLED_I2C_Init(void)
{
	OLED_W_SCL(1);
	OLED_W_SDA(1);
}



/**
  * @brief  I2C开始
  * @param  无
  * @retval 无
  */
void OLED_I2C_Start(void)
{
	OLED_W_SDA(1);
	OLED_W_SCL(1);
	OLED_W_SDA(0);
	OLED_W_SCL(0);
}

/**
  * @brief  I2C停止
  * @param  无
  * @retval 无
  */
void OLED_I2C_Stop(void)
{
	OLED_W_SDA(0);
	OLED_W_SCL(1);
	OLED_W_SDA(1);
}

/**
  * @brief  I2C发送一个字节
  * @param  Byte 要发送的一个字节
  * @retval 无
  */
void OLED_I2C_SendByte(uint8_t Byte)
{
	uint8_t i;
	for (i = 0; i < 8; i++)
	{
		OLED_W_SDA(Byte & (0x80 >> i));
		OLED_W_SCL(1);
		OLED_W_SCL(0);
	}
	OLED_W_SCL(1);	//额外的一个时钟,不处理应答信号
	OLED_W_SCL(0);
}

/**
  * @brief  OLED写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void OLED_WriteCommand(uint8_t Command)
{
	OLED_I2C_Start();
	OLED_I2C_SendByte(0x78);		//从机地址
	OLED_I2C_SendByte(0x00);		//写命令
	OLED_I2C_SendByte(Command); 
	OLED_I2C_Stop();
}

/**
  * @brief  OLED写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void OLED_WriteData(uint8_t Data)
{
	OLED_I2C_Start();
	OLED_I2C_SendByte(0x78);		//从机地址
	OLED_I2C_SendByte(0x40);		//写数据
	OLED_I2C_SendByte(Data);
	OLED_I2C_Stop();
}

/**
  * @brief  OLED设置光标位置
  * @param  Y 以左上角为原点,向下方向的坐标,范围:0~7
  * @param  X 以左上角为原点,向右方向的坐标,范围:0~127
  * @retval 无
  */
void OLED_SetCursor(uint8_t Y, uint8_t X)
{
	OLED_WriteCommand(0xB0 | Y);					//设置Y位置
	OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4));	//设置X位置高4位
	OLED_WriteCommand(0x00 | (X & 0x0F));			//设置X位置低4位
}

/**
  * @brief  OLED清屏
  * @param  无
  * @retval 无
  */
void OLED_Clear(void)
{  
	uint8_t i, j;
	for (j = 0; j < 8; j++)
	{
		OLED_SetCursor(j, 0);
		for(i = 0; i < 128; i++)
		{
			OLED_WriteData(0x00);
		}
	}
}

/**
  * @brief  OLED显示一个字符
  * @param  Line 行位置,范围:1~4
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的一个字符,范围:ASCII可见字符
  * @retval 无
  */
void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char)
{      	
	uint8_t i;
	OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8);		//设置光标位置在上半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_F8x16[Char - ' '][i]);			//显示上半部分内容
	}
	OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8);	//设置光标位置在下半部分
	for (i = 0; i < 8; i++)
	{
		OLED_WriteData(OLED_F8x16[Char - ' '][i + 8]);		//显示下半部分内容
	}
}

/**
  * @brief  OLED显示字符串
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串,范围:ASCII可见字符
  * @retval 无
  */
void OLED_ShowString(uint8_t Line, uint8_t Column, char * String)
{
	uint8_t i;
	for (i = 0; String[i] != '\0'; i++)
	{
		OLED_ShowChar(Line, Column + i, String[i]);
	}
}

/**
  * @brief  OLED显示一个汉字
  * @param  Line 行位置,范围:1~4
  * @param  Column 列位置,范围:1~8
  * @param  num 汉字对应的序号
  * @retval 无
  */
void OLED_ShowChinese(uint8_t Line, uint8_t Column, uint8_t num)
{      	
	uint8_t i;
	OLED_SetCursor((Line - 1) * 2, (Column - 1) * 16);		//设置光标位置在上半部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(Hzk1[num][i]);			//显示上半部分内容
	}
	OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 16);	//设置光标位置在下半部分
	for (i = 0; i < 16; i++)
	{
		OLED_WriteData(Hzk1[num][i + 16]);		//显示下半部分内容
	}
}

/**
  * @brief  OLED次方函数
  * @retval 返回值等于X的Y次方
  */
uint32_t OLED_Pow(uint32_t X, uint32_t Y)
{
	uint32_t Result = 1;
	while (Y--)
	{
		Result *= X;
	}
	return Result;
}

/**
  * @brief  OLED显示数字(十进制,正数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~4294967295
  * @param  Length 要显示数字的长度,范围:1~10
  * @retval 无
  */
void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0');
	}
}

/**
  * @brief  OLED显示数字(十进制,带符号数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-2147483648~2147483647
  * @param  Length 要显示数字的长度,范围:1~10
  * @retval 无
  */
void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length)
{
	uint8_t i;
	uint32_t Number1;
	if (Number >= 0)
	{
		OLED_ShowChar(Line, Column, '+');
		Number1 = Number;
	}
	else
	{
		OLED_ShowChar(Line, Column, '-');
		Number1 = -Number;
	}
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + '0');
	}
}

/**
  * @brief  OLED显示数字(十六进制,正数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~0xFFFFFFFF
  * @param  Length 要显示数字的长度,范围:1~8
  * @retval 无
  */
void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i, SingleNumber;
	for (i = 0; i < Length; i++)							
	{
		SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16;
		if (SingleNumber < 10)
		{
			OLED_ShowChar(Line, Column + i, SingleNumber + '0');
		}
		else
		{
			OLED_ShowChar(Line, Column + i, SingleNumber - 10 + 'A');
		}
	}
}

/**
  * @brief  OLED显示数字(二进制,正数)
  * @param  Line 起始行位置,范围:1~4
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度,范围:1~16
  * @retval 无
  */
void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length)
{
	uint8_t i;
	for (i = 0; i < Length; i++)							
	{
		OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + '0');
	}
}

/**
  * @brief  OLED初始化
  * @param  无
  * @retval 无
  */
void OLED_Init(void)
{
	uint32_t i, j;
	
	for (i = 0; i < 1000; i++)			//上电延时
	{
		for (j = 0; j < 1000; j++);
	}
	
	OLED_I2C_Init();			//端口初始化
	
	OLED_WriteCommand(0xAE);	//关闭显示
	
	OLED_WriteCommand(0xD5);	//设置显示时钟分频比/振荡器频率
	OLED_WriteCommand(0x80);
	
	OLED_WriteCommand(0xA8);	//设置多路复用率
	OLED_WriteCommand(0x3F);
	
	OLED_WriteCommand(0xD3);	//设置显示偏移
	OLED_WriteCommand(0x00);
	
	OLED_WriteCommand(0x40);	//设置显示开始行
	
	OLED_WriteCommand(0xA1);	//设置左右方向,0xA1正常 0xA0左右反置
	
	OLED_WriteCommand(0xC8);	//设置上下方向,0xC8正常 0xC0上下反置

	OLED_WriteCommand(0xDA);	//设置COM引脚硬件配置
	OLED_WriteCommand(0x12);
	
	OLED_WriteCommand(0x81);	//设置对比度控制
	OLED_WriteCommand(0xCF);

	OLED_WriteCommand(0xD9);	//设置预充电周期
	OLED_WriteCommand(0xF1);

	OLED_WriteCommand(0xDB);	//设置VCOMH取消选择级别
	OLED_WriteCommand(0x30);

	OLED_WriteCommand(0xA4);	//设置整个显示打开/关闭

	OLED_WriteCommand(0xA6);	//设置正常/倒转显示

	OLED_WriteCommand(0x8D);	//设置充电泵
	OLED_WriteCommand(0x14);

	OLED_WriteCommand(0xAF);	//开启显示
		
	OLED_Clear();				//OLED清屏
}

三、MF-RC522

这里rc522的驱动用的是其他博主的,原文见:

STM32 (基于HAL库)MFRC-522 无线射频IC卡驱动(RFID)

RC522这里用的是spi通信,所以先配置spi,由于spi只配置了3个引脚,rc522需要5个引脚通信,所以需要自己再选择两个引脚,并配置为输出模式

rc522.h:

#ifndef _RC522_H
#define _RC522_H
#include "main.h"
#include "stm32f1xx_hal.h"

/***********************************************************************************
*								MFRC522驱动程序			        				   *
************************************************************************************/
/*MFRC522寄存器定义*/
//PAGE0
#define MFRC_RFU00              	0x00    
#define MFRC_CommandReg         	0x01    
#define MFRC_ComIEnReg             	0x02    
#define MFRC_DivlEnReg             	0x03    
#define MFRC_ComIrqReg             	0x04    
#define MFRC_DivIrqReg             	0x05
#define MFRC_ErrorReg              	0x06    
#define MFRC_Status1Reg            	0x07    
#define MFRC_Status2Reg            	0x08    
#define MFRC_FIFODataReg           	0x09
#define MFRC_FIFOLevelReg          	0x0A
#define MFRC_WaterLevelReg         	0x0B
#define MFRC_ControlReg            	0x0C
#define MFRC_BitFramingReg         	0x0D
#define MFRC_CollReg               	0x0E
#define MFRC_RFU0F                 	0x0F
//PAGE1     
#define MFRC_RFU10                 	0x10
#define MFRC_ModeReg               	0x11
#define MFRC_TxModeReg             	0x12
#define MFRC_RxModeReg             	0x13
#define MFRC_TxControlReg          	0x14
#define MFRC_TxAutoReg             	0x15 //中文手册有误
#define MFRC_TxSelReg              	0x16
#define MFRC_RxSelReg              	0x17
#define MFRC_RxThresholdReg        	0x18
#define MFRC_DemodReg              	0x19
#define MFRC_RFU1A                 	0x1A
#define MFRC_RFU1B                 	0x1B
#define MFRC_MifareReg             	0x1C
#define MFRC_RFU1D                 	0x1D
#define MFRC_RFU1E                 	0x1E
#define MFRC_SerialSpeedReg        	0x1F
//PAGE2    
#define MFRC_RFU20                 	0x20  
#define MFRC_CRCResultRegM         	0x21
#define MFRC_CRCResultRegL         	0x22
#define MFRC_RFU23                 	0x23
#define MFRC_ModWidthReg           	0x24
#define MFRC_RFU25                 	0x25
#define MFRC_RFCfgReg              	0x26
#define MFRC_GsNReg                	0x27
#define MFRC_CWGsCfgReg            	0x28
#define MFRC_ModGsCfgReg           	0x29
#define MFRC_TModeReg              	0x2A
#define MFRC_TPrescalerReg         	0x2B
#define MFRC_TReloadRegH           	0x2C
#define MFRC_TReloadRegL           	0x2D
#define MFRC_TCounterValueRegH     	0x2E
#define MFRC_TCounterValueRegL     	0x2F
//PAGE3      
#define MFRC_RFU30                 	0x30
#define MFRC_TestSel1Reg           	0x31
#define MFRC_TestSel2Reg           	0x32
#define MFRC_TestPinEnReg          	0x33
#define MFRC_TestPinValueReg       	0x34
#define MFRC_TestBusReg            	0x35
#define MFRC_AutoTestReg           	0x36
#define MFRC_VersionReg            	0x37
#define MFRC_AnalogTestReg         	0x38
#define MFRC_TestDAC1Reg           	0x39  
#define MFRC_TestDAC2Reg           	0x3A   
#define MFRC_TestADCReg            	0x3B   
#define MFRC_RFU3C                 	0x3C   
#define MFRC_RFU3D                 	0x3D   
#define MFRC_RFU3E                 	0x3E   
#define MFRC_RFU3F                 	0x3F

/*MFRC522的FIFO长度定义*/
#define MFRC_FIFO_LENGTH       		64 

/*MFRC522传输的帧长定义*/
#define MFRC_MAXRLEN                18                

/*MFRC522命令集,中文手册P59*/
#define MFRC_IDLE              		0x00	//取消当前命令的执行
#define MFRC_CALCCRC           		0x03    //激活CRC计算
#define MFRC_TRANSMIT          		0x04    //发送FIFO缓冲区内容
#define MFRC_NOCMDCHANGE            0x07	//无命令改变
#define MFRC_RECEIVE           		0x08    //激活接收器接收数据
#define MFRC_TRANSCEIVE        		0x0C    //发送并接收数据
#define MFRC_AUTHENT           		0x0E    //执行Mifare认证(验证密钥)
#define MFRC_RESETPHASE        		0x0F    //复位MFRC522

/*MFRC522通讯时返回的错误代码*/
#define MFRC_OK                 	(char)0
#define MFRC_NOTAGERR            	(char)(-1)
#define MFRC_ERR                	(char)(-2)

/*MFRC522函数声明*/
void MFRC_Init(void);
void MFRC_WriteReg(uint8_t addr, uint8_t data);
uint8_t MFRC_ReadReg(uint8_t addr);
void MFRC_SetBitMask(uint8_t addr, uint8_t mask);
void MFRC_ClrBitMask(uint8_t addr, uint8_t mask);
void MFRC_CalulateCRC(uint8_t *pInData, uint8_t len, uint8_t *pOutData);
char MFRC_CmdFrame(uint8_t cmd, uint8_t *pInData, uint8_t InLenByte, uint8_t *pOutData, uint16_t *pOutLenBit);



/***********************************************************************************
*							MFRC552与MF1卡通讯接口程序	 		     	     	   *
************************************************************************************/
/*Mifare1卡片命令字*/
#define PICC_REQIDL           	0x26               	//寻天线区内未进入休眠状态的卡
#define PICC_REQALL           	0x52               	//寻天线区内全部卡
#define PICC_ANTICOLL1        	0x93               	//防冲撞
#define PICC_ANTICOLL2        	0x95               	//防冲撞
#define PICC_AUTHENT1A        	0x60               	//验证A密钥
#define PICC_AUTHENT1B        	0x61               	//验证B密钥
#define PICC_READ             	0x30               	//读块
#define PICC_WRITE            	0xA0               	//写块
#define PICC_DECREMENT        	0xC0               	//减值(扣除)
#define PICC_INCREMENT        	0xC1               	//增值(充值)
#define PICC_TRANSFER         	0xB0               	//转存(传送)
#define PICC_RESTORE          	0xC2               	//恢复(重储)
#define PICC_HALT             	0x50               	//休眠

/*PCD通讯时返回的错误代码*/
#define PCD_OK                 	(char)0				//成功
#define PCD_NOTAGERR            (char)(-1)			//无卡
#define PCD_ERR                	(char)(-2)			//出错

/*PCD函数声明*/
void PCD_Init(void);
void PCD_Reset(void);
void PCD_AntennaOn(void);
void PCD_AntennaOff(void);
char PCD_Request(uint8_t RequestMode, uint8_t *pCardType);  //寻卡,并返回卡的类型
char PCD_Anticoll(uint8_t *pSnr);                           //防冲突,返回卡号
char PCD_Select(uint8_t *pSnr);                             //选卡
char PCD_AuthState(uint8_t AuthMode, uint8_t BlockAddr, uint8_t *pKey, uint8_t *pSnr); //验证密码(密码A和密码B)   
char PCD_WriteBlock(uint8_t BlockAddr, uint8_t *pData);   //写数据
char PCD_ReadBlock(uint8_t BlockAddr, uint8_t *pData);    //读数据
char PCD_Value(uint8_t mode, uint8_t BlockAddr, uint8_t *pValue);   
char PCD_BakValue(uint8_t sourceBlockAddr, uint8_t goalBlockAddr);                                 
char PCD_Halt(void);
void StartIDcardTask(void const * argument);

uint8_t readCard(uint8_t *readUid,void(*funCallBack)(void));


#endif

rc522.c:

#include "stm32f1xx_hal.h"
#include "rc522.h"
#include "stdio.h"
#include "string.h"
#include "spi.h"
#define osDelay HAL_Delay


#define RS522_RST(N) HAL_GPIO_WritePin(RC522_RST_GPIO_Port, RC522_RST_Pin, N==1?GPIO_PIN_SET:GPIO_PIN_RESET)
#define RS522_NSS(N) HAL_GPIO_WritePin(RC522_CS_GPIO_Port, RC522_CS_Pin, N==1?GPIO_PIN_SET:GPIO_PIN_RESET)

extern SPI_HandleTypeDef hspi1;

/**************************************************************************************
* 函数名称:MFRC_Init
* 功能描述:MFRC初始化
* 入口参数:无
* 出口参数:无
* 返 回 值:无
* 说    明:MFRC的SPI接口速率为0~10Mbps
***************************************************************************************/
void MFRC_Init(void)
{
    RS522_NSS(1);
    RS522_RST(1);
}


/**************************************************************************************
* 函数名称: SPI_RW_Byte
* 功能描述: 模拟SPI读写一个字节
* 入口参数: -byte:要发送的数据
* 出口参数: -byte:接收到的数据
*******************************************************************************
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值