扫码加入

  • 方案介绍
  • 相关推荐
申请入驻 产业图谱

基于STM32单片机的图书馆手机APP管理系统

1小时前
93
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

基于STM32单片机的图书馆手机APP管理系统

1、项目简介

1.1 系统功能

  • 系统构成:
  • 功能介绍:
    • 1、一共有三个IC卡模拟三本书。
    • 2、通过按键可选择借书还是还书,10秒内刷卡代表成功借书或还书。
    • 3、OLED显示屏可现实图书是否被借阅,以及借阅,还回的时间。
    • 4、通过手机APP可查看图书是否被借阅,以及借阅,还回的时间。

1.2 演示视频

  • 演示视频:https://www.bilibili.com/video/BV1vGqpY9ECW

2、部分电路设计

2.1 STM32单片机核心板电路设计

  • ‌基于 ARM Cortex-M3内核的STM32F1系列单片机属于主流STM32单片机,其中增强型STM32F103子系列单片机的CPU 主频高达72MHz,片内Flash容量高达1MB,芯片引脚数量多达144个,有 QFN、LQFP、CSP、BGA 等多种芯片封装形式,并具有多种片内外设、USB接口和CAN 接口。根据STM32F103单片机片内Flash容量的不同,ST 公司将其分为小容量(16-32KB)、中等容量(64-128KB)、大容量(256KB-1MB)3种。
  • 电源电路:为单片机提供稳定的工作电压,通常采用3.3V电源供电。电源电路的设计要保证单片机在不同工作条件下都能获得稳定的电压输出,以确保单片机的正常工作。
  • 晶振电路:提供单片机工作所需的时钟信号。晶振电路通过晶振和电容组成,为单片机提供稳定的工作脉冲,确保单片机的定时和同步需求。
  • 复位电路:实现单片机的复位功能,类似于电脑的重启。复位电路通过电容和电阻的配合,实现单片机在上电启动时的自动复位,以及通过手动按键实现复位功能,保证单片机在程序跑飞或异常情况下能够重新开始执行程序。

STM32单片机是一种功能强大、易于使用、灵活且可靠的32位微控制器,基于ARM Cortex™-M内核。其主要功能特点包括:

  • 高性能和低功耗‌:STM32系列单片机提供多种内核选择,如Cortex-M0、Cortex-M3、Cortex-M4等,满足不同应用场景对性能的需求,同时保持低功耗特性。‌
  • 多种通信和外设接口‌:STM32单片机具备广泛的通信和外设接口,如I2CSPI、USART、USB等,便于开发者实现各种复杂功能。‌
  • 易于开发和调试‌:STM32单片机提供了丰富的软件和硬件工具,如HAL库、CubeMX等,帮助开发者快速创建和调试嵌入式系统
  • 高集成度和设计灵活性‌:STM32系列单片机全系列产品共用大部分引脚、软件和外设,优异的兼容性为开发人员带来最大的设计灵活性

单片机最小系统原理图如下图所示:

实物图:

2.2 RC522 RFID刷卡电路

  • 本系统选择MFRC-522射频模块进行刷卡操作。MF RC522是应用于13.56MHz非接触式通信中高集成度的读写卡芯片,是NXP公司针对“三表”应用推出的一款低电压、低成本、体积小的非接触式读写卡芯片,是智能仪表和便携式手持设备研发的较好选择。MF RC522利用了先进的调制和解调概念,完全集成了在13.56MHz下所有类型的被动非接触式通信方式和协议。支持14443A兼容应答器信号。数字部分处理ISO14443A帧和错误检测。
  • 此外,还支持快速CRYPTO1加密算法,用语验证MIFARE系列产品。MFRC522支持MIFARE系列更高速的非接触式通信,双向数据传输速率高达424kbit/s。作为13.56MHz高集成度读写卡系列芯片家族的新成员,MF RC522与MF RC500和MF RC530有不少相似之处,同时也具备许多特点和差异。它与主机间通信采用SPI模式,有利于减少连线,缩小PCB板体积,降低成本。
  • MF522-AN模块采用Philips MFRC522原装芯片设计读卡电路,使用方便,成本低廉,适用于设备开发、读卡器开发等高级应用的用户、需要进行射频卡终端设计/生产的用户。本模块可直接装入各种读卡器模具。模块采用电压为3.3V,通过SPI接口简单的几条线就可以直接与用户任何CPU主板相连接通信,可以保证模块稳定可靠的工作、读卡距离远;

其具体电路原理图如下图所示:

实物图:

2.3 esp8266 wifi通信电路

  • ‌光线采集电路我们是通过光敏电阻5528进行光线采集,光敏电阻会根据不同的光线值输出不同的电阻,然后把数据通过传输给单片机,单片机通过内部AD进行模数转换,根据不同的光线值单片机在通过PWM脉冲电路进行灯光调节。

其具体电路原理图如下图所示:

实物图如下:

2.4 OLED液晶显示电路

  • 0.96寸OLED屏,支持黑白、黑蓝或者黄蓝双色显示
  • 128x64分辨率,显示效果清晰,对比度高
  • 超大可视角度:大于160°(显示屏中可视角度最大的一种屏幕)
  • 宽电压供电(3V~5V),兼容3.3V和5V逻辑电平,无需电平转换芯片
  • 默认为4线制SPI总线,可以选择3线制SPI总线或者IIC总线
  • 超低功耗:正常显示仅为0.06W(远低于TFT显示屏)

其具体电路原理图如下图所示:

实物图:

3、单片机代码展示

3.1 系统初始化

void HardWare_Init(void)
{
	MX_GPIO_Init();
	MX_TIM4_Init();
	MX_USART1_UART_Init();
	/* USER CODE BEGIN 2 */
	x_Flash_Ini();
	SYSIO_SET_MAINLED(_SYSIO_STA_LOW);//开机打开指示灯
	SYSIO_SET_LED1(_SYSIO_STA_LOW);//开机打开指示灯
	SYSIO_SET_LED2(_SYSIO_STA_LOW);//开机打开指示灯
	LL_USART_EnableIT_RXNE(USART1);
	LL_TIM_EnableCounter(TIM4);//运行定时器4
	LL_TIM_EnableIT_UPDATE(TIM4);//定时器4初始化
	
	SYSIO_SET_WIFI_EN(_SYSIO_STA_LOW);
	delay_ms(100);
	SYSIO_SET_WIFI_EN(_SYSIO_STA_HIGH);
	OLED_Init();//OLED初始化
	Rc522_Init();
}

3.2 OLED显示程序

//更新显存到OLED	
void OLED_Refresh(void)
{
	u8 i,n;
	for(i=0;i<8;i++)
	{
	   WriteCmd(0xb0+i); //设置行起始地址
	   WriteCmd(0x00);   //设置低列起始地址
	   WriteCmd(0x10);   //设置高列起始地址
	   for(n=0;n<128;n++)
		 WriteDat(OLED_GRAM[n][i]);
  }
}

//清屏函数
void OLED_Clear(void)
{
	u8 i,n;
	for(i=0;i<8;i++)
	{
	   for(n=0;n<128;n++)
			{
			 OLED_GRAM[n][i]=0;//清除所有数据
			}
  }
}

//画点 
//x:0~127
//y:0~63
void OLED_DrawPoint(u8 x,u8 y)
{
	u8 i,m,n;
	i=y/8;
	m=y%8;
	n=1<<m;
	OLED_GRAM[x][i]|=n;
}

//清除一个点
//x:0~127
//y:0~63
void OLED_ClearPoint(u8 x,u8 y)
{
	u8 i,m,n;
	i=y/8;
	m=y%8;
	n=1<<m;
	OLED_GRAM[x][i]=~OLED_GRAM[x][i];
	OLED_GRAM[x][i]|=n;
	OLED_GRAM[x][i]=~OLED_GRAM[x][i];
}

/**
 * @description: 显示8*16字符
 * @param {unsigned char} x
 * @param {unsigned char} y
 * @param {unsigned char} c
 * @return {*}
 */
void OLED_Show_char8_16(unsigned char x, unsigned char y,unsigned char c)
{
  unsigned int k;  
	
//	unsigned char wm=0;
//	unsigned int  adder = 0;
  INT8U m,y0 = y,temp;
	
  for (k=0;k<=FONTINDEXMAX_816;k++)
  {
    if(font8_16[k].Index[0]==c)
    {  
			for(INT8U j = 0;j<16;j++)
			{
				temp = font8_16[k].Msk[j];
				
				for(m=0;m<8;m++)           //写入数据
				{
					if(temp&0x01)OLED_DrawPoint(x,y);
					else OLED_ClearPoint(x,y);
					temp>>=1;
					y++;
					if((y-y0)==16)
					{
						y=y0;
						x++;
						break;
					}
				}
				
			}
			break;
    }
  }
}

/**
 * @description: 显示8*16字符串
 * @param {unsigned char} x
 * @param {unsigned char} y
 * @param {INT8U} *pu8I_Buff
 * @return {*}
 */
void OLED_Show_Str8_16(unsigned char x, unsigned char y,INT8U *pu8I_Buff)
{
	INT8U u8T_Index = 0;
	while(*pu8I_Buff)
	{
		OLED_Show_char8_16(x+u8T_Index*8,y,*pu8I_Buff);
		u8T_Index++;
		pu8I_Buff++;
	}
}

3.3 RC522程序

/*************************************************************************************************
函 数 名:void Rc522_Init(void)
功    能:RC522刷卡模块初始化,同时读取密码信息,存卡数量,卡片信息等数据
说    明:SaveCard[0]~SaveCard[3]----用于存放管理员密码
					SaveCard[4]~SaveCard[5]----用于存放卡片数量
					剩余位置用于存放卡片信息
入口参数:无
返 回 值:无
设    计:LLP                   日    期:2018-10-30
修    改:                       日    期:
************************************************************************************************/
void Rc522_Init(void)
{
	PcdReset();
	PcdAntennaOff(); 
	PcdAntennaOn();	
}
/*************************************************************************************************
函 数 名:static uint8 n_CarCompare(uint8 *pu8I_Car)
功    能:卡片对比
说    明:
入口参数:无
返 回 值:无
设    计:LLP                   日    期:2018-10-30
修    改:                       日    期:
************************************************************************************************/
static uint8 n_CarCompare(uint8 *pu8I_Car)
{
	for(uint8 i = 0;i<CARMAX;i++)
	{
		uint8 j;
		for(j = 0;j<4;j++)
		{
			if(pu8I_Car[j] != au8T_CarSave[i][j])
			{
				break;
			}
		}
		if(j == 4)
		{
			return i+1;
		}
	}
	
	return 0;
}
/*************************************************************************************************
函 数 名:static void n_CarAdd(uint8 *pu8I_Car)
功    能:卡片对比
入口参数:无
返 回 值:无
设    计:LLP                   日    期:2018-10-30
修    改:                       日    期:
************************************************************************************************/
static void n_CarAdd(uint8 *pu8I_Car)
{
	uint8 i = 0,j = 0;
	if(u16_CarNumber < CARMAX)
	{
		u16_CarNumber++;
		for(i = 0;i<CARMAX;i++)
		{
			for(j = 0;j<CARDSERIALNUMLEN;j++)
			{
				if(au8T_CarSave[i][j] != 0)
				{
					break;
				}
			}
			
			if(j == 4)
			{
				for(j = 0;j<CARDSERIALNUMLEN;j++)
				{
					au8T_CarSave[i][j] = pu8I_Car[j];
				}
				e_Card_EventSta = _RC522_SaveSuc;
				return;
			}
		}
	}
	e_Card_EventSta = _RC522_SaveSFil;
}
/*************************************************************************************************
函 数 名:static void n_CarDel(uint8 u8I_Cnt)
功    能:删除卡片
入口参数:无
返 回 值:无
设    计:LLP                   日    期:2018-10-30
修    改:                       日    期:
************************************************************************************************/
static void n_CarDel(uint8 u8I_Cnt)
{
	uint8 j = 0;
	if(u16_CarNumber)
	{
		u16_CarNumber--;

		for(j = 0;j<CARDSERIALNUMLEN;j++)
		{
			au8T_CarSave[u8I_Cnt-1][j] = 0;
		}
	}
    e_Card_EventSta = _RC522_DeleteSuc;
}

相关推荐