基于stm32-rc522的门禁系统


title: 基于stm32+rc522的门禁系统
tags: stm32

基于stm32+rc522的门禁系统

元器件:stm32f103c8t6,RC522,MG90S舵机

所有的代码放在这里了:https://gitee.com/armgpio/access-control-system

首先,配置LED以及MG90S初始化

​ MG90S的OUT口接的是PB6,也就是stm32f103c8t6定时器TIM4的通道1。通过TIM4产生周期为20ms的PWM波,当高电平所占时间为1ms时,舵机转到中点位置。

mg90s.c

void TIM4_PWM_Init(u16 arr,u16 psc)
{  
	//**结构体声明**//
	GPIO_InitTypeDef GPIO_InitStructure;            //声明GPIO
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; //声明定时器
	TIM_OCInitTypeDef  TIM_OCInitStructure;         //声明PWM通道
	
	//**时钟使能**//
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);	//使能定时器TIM4时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能PB端口时钟
	
	//配置GPIO//
	GPIO_InitStructure.GPIO_Pin = PWM_GPIO_PIN;				//PWM 端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 		 //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
	GPIO_Init(MOTO_GPIO_PORT, &GPIO_InitStructure);			//根据设定参数初始化GPIOB6
	GPIO_SetBits(MOTO_GPIO_PORT,PWM_GPIO_PIN);

  //初始化TIM4
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

	//初始化TIM4 Channel1 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC1Init(TIM4, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM4 OC1
	
	TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);  //让oc1能重装载
	
	TIM_Cmd(TIM4, ENABLE);  //使能TIM4
	
}

RC522的配置

​ 对于RC522来说,使用的是单片机的硬件SPI。在SPI通信中,需要用到微秒的延时,所以这里还要用到嘀嗒定时器。配置好嘀嗒定时器后,就是RC522的初始化。

RC522的初始化

void RC522_Init ( void )
{
	RC522_SPI_Config ();	
	RC522_Reset_Disable();	
	RC522_CS_Disable();
}

/**
  * @brief  R522 SPI配置
  * @param  无
  * @retval 无
  */
static void RC522_SPI_Config ( void )
{
  /* SPI_InitTypeDef  SPI_InitStructure */
	GPIO_InitTypeDef GPIO_InitStructure;
  
	/*!< Configure SPI_RC522_SPI pins: CS */
	RC522_GPIO_CS_CLK_FUN ( RC522_GPIO_CS_CLK, ENABLE );
	GPIO_InitStructure.GPIO_Pin = RC522_GPIO_CS_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = RC522_GPIO_CS_Mode;
	GPIO_Init(RC522_GPIO_CS_PORT, &GPIO_InitStructure);
	
  /*!< Configure SPI_RC522_SPI pins: SCK */
	RC522_GPIO_SCK_CLK_FUN ( RC522_GPIO_SCK_CLK, ENABLE );
	GPIO_InitStructure.GPIO_Pin = RC522_GPIO_SCK_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = RC522_GPIO_SCK_Mode;
	GPIO_Init(RC522_GPIO_SCK_PORT, &GPIO_InitStructure);
	
  /*!< Configure SPI_RC522_SPI pins: MOSI */
	RC522_GPIO_MOSI_CLK_FUN ( RC522_GPIO_MOSI_CLK, ENABLE );
	GPIO_InitStructure.GPIO_Pin = RC522_GPIO_MOSI_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = RC522_GPIO_MOSI_Mode;
	GPIO_Init(RC522_GPIO_MOSI_PORT, &GPIO_InitStructure);

  /*!< Configure SPI_RC522_SPI pins: MISO */
	RC522_GPIO_MISO_CLK_FUN ( RC522_GPIO_MISO_CLK, ENABLE );
	GPIO_InitStructure.GPIO_Pin = RC522_GPIO_MISO_PIN;
	GPIO_InitStructure.GPIO_Mode = RC522_GPIO_MISO_Mode;
	GPIO_Init(RC522_GPIO_MISO_PORT, &GPIO_InitStructure);	
		
  /*!< Configure SPI_RC522_SPI pins: RST */
	RC522_GPIO_RST_CLK_FUN ( RC522_GPIO_RST_CLK, ENABLE );
	GPIO_InitStructure.GPIO_Pin = RC522_GPIO_RST_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = RC522_GPIO_RST_Mode;
	GPIO_Init(RC522_GPIO_RST_PORT, &GPIO_InitStructure);
}

main函数的配置

​ 在main.c里面包含两个函数,一个是寻卡函数,一个是main函数。首先定义的是卡A的密匙,基本上都是6个0xff。在寻卡函数里面,讲预先设定好的IC卡序列号存储在数组中,再将读取到的序列号和数组进行比对,这样就能正确识别到已经保存的卡片信息。

main.c

uint8_t KeyValue[]={0xFF ,0xFF, 0xFF, 0xFF, 0xFF, 0xFF};   // 卡A密钥

void IC_test ( void )
{
	//uint32_t writeValue = 100;
	//uint32_t readValue;
	//char cStr [ 30 ];
	uint8_t ucArray_ID [ 4 ];    /*先后存放IC卡的类型和UID(IC卡序列号)*/                                                                                         
	uint8_t ucStatusReturn;      /*返回状态*/ 
	u8 ID1[]={0xA9,0x37,0x71,0xe4};
  while ( 1 )
  {    
		/*寻卡*/
		if ( ( ucStatusReturn = PcdRequest ( PICC_REQIDL, ucArray_ID ) ) != MI_OK )  //ucArray_ID是卡片类型
       /*若失败再次寻卡*/
		ucStatusReturn = PcdRequest ( PICC_REQIDL, ucArray_ID );		                                                
		if ( ucStatusReturn == MI_OK  )
		{
      /*防冲撞(当有多张卡进入读写器操作范围时,防冲突机制会从其中选择一张进行操作)*/
			if ( PcdAnticoll ( ucArray_ID ) == MI_OK )                                                                   
			{
				PcdSelect(ucArray_ID);		//选定卡片	
				PcdAuthState( PICC_AUTHENT1A, 0x11, KeyValue, ucArray_ID );//校验密码 (密码验证模式,块地址,密码,卡片序列号)
				GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);
				if(ID1[0]==ucArray_ID[0])
				{
					TIM_SetCompare1(TIM4,75);
					Delay_ms(1000);
					TIM_SetCompare1(TIM4,50);
					GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
				}
				else 
				{
					TIM_SetCompare1(TIM4,50);
					GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
					Delay_ms(1000);
					GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);
					Delay_ms(1000);
					GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
					Delay_ms(1000);
					GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);
					Delay_ms(1000);
					GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
					Delay_ms(1000);
					GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);
					Delay_ms(1000);
					GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
					Delay_ms(1000);
					GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);
					Delay_ms(1000);
				}
				PcdHalt();//令卡片进入休眠状态	
			}				
		}		
  }	
}

int main(void)
{	
	SysTick_Init (); 
	RC522_Init (); 
	
	TIM4_PWM_Init(999,1439);
	TIM_SetCompare1(TIM4,50);
	
	LED_GPIO_Config();	 
	GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);//先关灯
	
	PcdReset();
	M500PcdConfigISOType ( 'A' );
	while(1)
	{
		IC_test();
	}
}

​ 对于密码的存储是放在了代码中来进行实现的,没有添加记忆功能。

  • 18
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值