STM32f103 简易密码锁(一)

开头

  希望这个实验能从一个实验由(一)到(二)到(三)到…等等,相关代码在文章结尾,虽然现在能力还不够,那就力所能及叭。

主要功能

1、当输入代码正确时候,按下确定开锁按键,显示屏显示密码正确,锁打开
2、当输入代码不正确时候,按下确定开锁按键,显示屏显示密码错误,锁不能打开
3、实现再输入过程中密码由于不小心按错,将按下撤销按键实现密码重输
4、实现密码更改方便,并实现调电不丢失密码。

在这里插入图片描述


设计内容

  ①开机:按下电源,电源指示灯点亮,OLED液晶显示:“Welecome my host”,按下输入密码按键后,液晶显示:“input:”,通过按键输入密码,若密码识别成功,继电器工作,开锁成功,OLED显示“OK”。若密码输入错误,则不会开锁,OLED显示“ERROR”。
  ②设置模式:通过各个按下按键进入对应按键的模式。在模式下可以完成输入密码、撤销密码、和更改密码的功能。进入输入密码模式后,通过按键#选择哪一位密码需要更改,通过按键D将密码修改,若密码修改完成后通过按键0将密码导入,OLED显示“SUCCESS”,且此时密码修改后下一次打开保存的还是修改的密码,调电不丢失自己修改的密码。
  **若是重新将代码烧入芯片中,首先需要按下0键将密码导入存储空间中,否则不能进行正常的输入密码比较


一、所需材料

  主要采用的是stm32f103zet6的开发板、正点原子的OLED显示屏、一个矩阵按键,一个继电器、一个电磁锁模块。

二、部分程序

1.main.c

代码如下(示例):

#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "oled.h"
#include "KEY1.h"
#include "usart.h"
#include "flash.h"


unsigned char Password2[7]={1,1,1,1,1,1,0};//修改后的新密码存储在这个数组中,密码长度为6位,数组最后一位为更改后密码标志位
unsigned char Password[6]={0,0,0,0,0,0};
#define SIZE sizeof(Password2)		//数组长度
#define FLASH_SAVE_ADDR  0X08070000//存储密码地址
#define FLASH_SAVE_ADDR1  0X08020000
u8 flag=0;
unsigned char Password1[7]={1,2,3,4,5,6,0};;
unsigned char Password_count=0; 

unsigned int a_c,b_c,c_c,d_c;
unsigned char key_back;
unsigned char flag_key_back=0,flag_key_back1=0;
u16 flag_key_data=0;
u16* flag_key=&flag_key_data;
/*
修改密码并进行密码导入函数
*/
void change_key()
{
	static unsigned int i_c=0;
	unsigned char a;
	if((key_back=='#')&&(flag_key_back1==1))//选择密码修改是哪一位
	{
		a_c=Password[i_c];
		i_c++;
		if(i_c==7)
		{
			i_c=1;
			
		}
		OLED_ShowChar(50+i_c*8,8,13+' ',16,1);
	  OLED_Refresh_Gram();
		if(i_c>1)
		{
		OLED_ShowChar(50+(i_c-1)*8,8,10+' ',16,1);
		OLED_Refresh_Gram();
		}
		flag_key_back=1;
	}
	if((key_back=='D')&&(flag_key_back==1))//由上面选择是哪一位要修改的密码,在对这一位密码进行递增的方式进行修改,累加到9后回到0
	{
			a_c++;
		  if(a_c>9)
				a_c=0;
			Password2[i_c-1]=a_c;
			OLED_ShowChar(50+i_c*8,8,Password2[i_c-1]+'0',16,1);
			OLED_Refresh_Gram();
	}
	if(key_back==0)	//修改密码后按下0键确认导入
  { 
			Password2[6]=1;
		  delay_ms(10);
			STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)Password2,SIZE);
			OLED_Clear();
			OLED_ShowString(0,0,">",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>>>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>>>>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>>>>>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>>>>>>",24);OLED_Refresh_Gram();delay_ms(100);
		  OLED_Refresh_Gram();
		  delay_ms(100);
			STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)Password1,SIZE);
			OLED_Clear();
		  OLED_ShowString(25,25,"Suscess!",12);
		  OLED_Refresh_Gram();
		  delay_ms(50);
		  OLED_ShowString(25,25,"Suscess!",16);
		  OLED_Refresh_Gram();delay_ms(50);
		  OLED_ShowString(25,25,"Suscess!",24);
		  OLED_Refresh_Gram();delay_ms(50);
	}
}
/*
按键处理函数,对输入密码进行比较看密码是否输入正确
*/

void data_key()
{
	 unsigned char i;
	 unsigned char flag_data_key1=0;
		i=' ';//因为采用的ASCII码数组来显示OLED所以需要先转换成ASCII码

	if(key_back=='C')
	{
		OLED_Clear();
		OLED_ShowString(0,8,"input:",16);
		flag=1;
    Password_count=0;
		flag_key_back=0;
		flag_key_back1=1;
		flag_data_key1=1;
		GPIO_SetBits(GPIOF,GPIO_Pin_13);
	}
	if(flag==1)
	{
		if(key_back>0&&key_back<=9)			  //输入密码0-9
		    {
			   if(Password_count<6) 
			    {
				   Password[Password_count]=key_back;
				   Password_count++;
					 if(Password_count==1)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
						 OLED_Refresh_Gram();
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==2)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==3)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==4)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
						 OLED_Refresh_Gram();

					 }
					 if(Password_count==5)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==6)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
						 OLED_Refresh_Gram();
					 }
				  }
			  }
		else if((key_back=='A'))				  //撤销按键
			 {
			   	if(Password_count>0) Password_count--;
				 if(Password_count==0)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==1)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==2)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==3)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();

					 }
					 if(Password_count==4)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==5)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();
					 }
				  
			 }	
		else if((key_back=='B')&&(Password1[6]==0))				  //确认按键
			 {
				 if((Password[0]==1&&Password[1]==2&&Password[2]==3&&Password[3]==4&&Password[4]==5&&Password[5]==6)||(Password[0]==Password1[0]&&Password[1]==Password1[1]&&Password[2]==Password1[2]&&Password[3]==Password1[3]&&Password[4]==Password1[4]&&Password[5]==Password1[5]))
						{  
								OLED_Clear();
								OLED_ShowString(20,20,"OK",24);
							  OLED_Refresh_Gram();
							flag_key_back1=0;
							flag_data_key1=0;
							GPIO_SetBits(GPIOF,GPIO_Pin_13);  //继电器的引脚PF13
						}
					else 
					 {
						 OLED_Clear();
						 OLED_ShowString(20,20,"ERROR",24);
						 OLED_Refresh_Gram();
						 flag_key_back1=0;
						 flag_data_key1=0;
						 GPIO_ResetBits(GPIOF,GPIO_Pin_13);							 
					 }
			 }
			 		else if((key_back=='B')&&(Password1[6]==1))				  //确认按键
			 {
				 if(Password[0]==Password1[0]&&Password[1]==Password1[1]&&Password[2]==Password1[2]&&Password[3]==Password1[3]&&Password[4]==Password1[4]&&Password[5]==Password1[5])
						{  
								OLED_Clear();
								OLED_ShowString(60,30,"OK",24);
							  OLED_Refresh_Gram();
							  //¼ÌµçÆ÷Òý½Åpf13
							GPIO_ResetBits(GPIOF,GPIO_Pin_13);
						}
					else 
					 {
						 OLED_Clear();
						 OLED_ShowString(40,30,"ERROR",24);
						 OLED_Refresh_Gram();
						 GPIO_SetBits(GPIOF,GPIO_Pin_13);
					 }
				 }
			 OLED_Refresh_Gram();
			 
	}
}
/*
主函数,来调用子函数的内容
*/
 int main(void)
 {	 
	
	delay_init();	    	 //延时函数初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 //设置NVIC中断优先级分组2,2位抢占优先级,2位响应优先级
	OLED_Init();			//初始化OLED
 Matrix_Key_Init(); 
  OLED_ShowString(0,0," --------------- ",16);   
	OLED_ShowString(20,16, "Welecome",24);  
 	OLED_ShowString(25,46,"MY HOST",16);  
	OLED_Refresh_Gram();		//更新显示到OLED
	delay_ms(1000);
  GPIO_SetBits(GPIOF,GPIO_Pin_13);

		  delay_ms(1000);
			STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)Password1,SIZE);
	while(1) 
	{
		key_back=Matrix_Key_Scan();
		data_key();
    change_key();

	}	 
 }

2.key.c

(有较强的可移植性,之前根据五一单片机的那种矩阵按键格式写的,但后来在网上进行翻阅的时候发现下面这种代码有很强的移植性,要是要更改只需更改.h文件中引脚就可以,所以网友们还是万能的)

代码如下(示例):

#include "KEY1.h"
#include "delay.h"
#include "sys.h"

unsigned char Y1,Y2,Y3,Y4;


void Matrix_Key_Init(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;   
   RCC_APB2PeriphClockCmd(X1_RCC|X2_RCC|X3_RCC|X4_RCC|Y1_RCC|Y2_RCC|Y3_RCC|Y4_RCC|RCC_APB2Periph_AFIO, ENABLE);
   GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 
	
   GPIO_InitStructure.GPIO_Pin =  X1_GPIO_PIN ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(X1_GPIO_PORT, &GPIO_InitStructure);
    
   GPIO_InitStructure.GPIO_Pin =  X2_GPIO_PIN ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(X2_GPIO_PORT, &GPIO_InitStructure);
    
   GPIO_InitStructure.GPIO_Pin =  X3_GPIO_PIN ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(X3_GPIO_PORT, &GPIO_InitStructure);
	
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Pin = X4_GPIO_PIN ;    
   GPIO_Init(X4_GPIO_PORT, &GPIO_InitStructure);
   
   GPIO_InitStructure.GPIO_Pin =  Y1_GPIO_PIN ;   
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(Y1_GPIO_PORT, &GPIO_InitStructure);	
   
   GPIO_InitStructure.GPIO_Pin =  Y2_GPIO_PIN ;   
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(Y2_GPIO_PORT, &GPIO_InitStructure);	
   
   GPIO_InitStructure.GPIO_Pin =  Y3_GPIO_PIN ;   
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(Y3_GPIO_PORT, &GPIO_InitStructure);	
	
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Pin = Y4_GPIO_PIN;      
   GPIO_Init(Y4_GPIO_PORT, &GPIO_InitStructure);	
	 
	 GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13 ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOF, &GPIO_InitStructure);
}

int Matrix_Key_Scan(void)
{
	static char key_down = 0;
	uchar KeyVal = KEY_ERR;
	GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN);  
	GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN);  
	GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN);  
	GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN);  

	if ((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y2_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y3_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y4_GPIO_PIN)==1))
	{
		delay_ms(10);
		if ((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y2_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y3_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y4_GPIO_PIN)==1))
		{
			if (key_down == 0)
			{	
				key_down = 1;		
				
				GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN);
				GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
				GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
				GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
					 
				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
				
				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
					KeyVal='A';
				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
					KeyVal='B';
				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
					KeyVal='C';
				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
					KeyVal='D';
/**************************************************/		
				
				GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
				GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN);
				GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
				GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
								
				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
				
				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
					KeyVal=3;
				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
					KeyVal=6;
				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
					KeyVal=9;
				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
					KeyVal='#';
				
/**************************************************/
				
				GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
				GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
				GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN);
				GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);   

				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
				
				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
					KeyVal=2;
				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
					KeyVal=5;
				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
					KeyVal=8;
				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
					KeyVal=0;	
				
/**************************************************/
				
				GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
				GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN); 
				GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN); 
				GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN); 
				
				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
				
				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
					KeyVal=1;
				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
					KeyVal=4;
				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
					KeyVal=7;
				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
					KeyVal='*';
			}
		}
	}
	else
	{
		key_down = 0;
		KeyVal = KEY_ERR;
	}
	
	return KeyVal;
}

3.key.h

#ifndef _KEY1_H
#define _KEY1_H	 

#include <stm32f10x.h>
#include "usart.h"
#include "sys.h"

#define uint unsigned int 
#define uchar unsigned char

#define X1_GPIO_PORT GPIOF           
#define X2_GPIO_PORT GPIOF   
#define X3_GPIO_PORT GPIOF           
#define X4_GPIO_PORT GPIOF 

#define Y1_GPIO_PORT GPIOF         
#define Y2_GPIO_PORT GPIOF   
#define Y3_GPIO_PORT GPIOF           
#define Y4_GPIO_PORT GPIOF 

#define X1_GPIO_PIN GPIO_Pin_7
#define X2_GPIO_PIN GPIO_Pin_6
#define X3_GPIO_PIN GPIO_Pin_5
#define X4_GPIO_PIN GPIO_Pin_4

#define Y1_GPIO_PIN GPIO_Pin_0
#define Y2_GPIO_PIN GPIO_Pin_1
#define Y3_GPIO_PIN GPIO_Pin_2
#define Y4_GPIO_PIN GPIO_Pin_3

#define X1_RCC RCC_APB2Periph_GPIOF
#define X2_RCC RCC_APB2Periph_GPIOF
#define X3_RCC RCC_APB2Periph_GPIOF
#define X4_RCC RCC_APB2Periph_GPIOF

#define Y1_RCC RCC_APB2Periph_GPIOF
#define Y2_RCC RCC_APB2Periph_GPIOF
#define Y3_RCC RCC_APB2Periph_GPIOF
#define Y4_RCC RCC_APB2Periph_GPIOF


#define KEY_ERR 255


void Matrix_Key_Init(void);
int Matrix_Key_Scan(void);
void Matrix_Key_Test(void) ;

#endif


三、有需要注意的地方

  ①如果大家用的是开发板的引脚输出来的高低电平作为5v继电器开与关的状态,这样电压是不够的,,因为引脚输出的电压是3.3v,而继电器需要的是5v的电压,所以需要在作为连接继电器的输出引脚再连接一个放大电路3.3v转5v,我也是焊接了一个这样的电路,只需要两个电阻和一个三极管组成就可以了,不懂的可以在网上搜关于这个电路
  ②如果对于功能不能正常实现可以慢慢找到相对应的错误所在,如何找到对应代码,可以用串口助手进行调试也可以用OLED调试,因为这个实验用到了OLED,所以直接用OLED调试也蛮方便,在认为错误的代码上下加上OLED显示函数,看看经过了这个代码能不能实现OLED对应的显示,如果不能说明这段代码确实有问题。

总结

  这段程序也经过我自己操作实现了功能,只有通过实践操作才能让自己的能力一步一步上涨,虽然途中会遇到很多问题和一些错误,一个一个解决就好了,经验也是慢慢堆起来的,从简单到复杂,希望接下来我能继续对简易密码锁改善成(二),循循渐进。
在这里插入图片描述
整体轮廓
在这里插入图片描述

相关程序全部资料

链接:https://pan.baidu.com/s/1xcOLsRNtreshgxoWN3JBYw
提取码:like



学习从零开始,到无穷结束

版权声明:本文为CSDN博主「Justin-Wei」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46285130/article/details/118435145

开头

  希望这个实验能从一个实验由(一)到(二)到(三)到…等等,相关代码在文章结尾,虽然现在能力还不够,那就力所能及叭。

主要功能

1、当输入代码正确时候,按下确定开锁按键,显示屏显示密码正确,锁打开
2、当输入代码不正确时候,按下确定开锁按键,显示屏显示密码错误,锁不能打开
3、实现再输入过程中密码由于不小心按错,将按下撤销按键实现密码重输
4、实现密码更改方便,并实现调电不丢失密码。

在这里插入图片描述


设计内容

  ①开机:按下电源,电源指示灯点亮,OLED液晶显示:“Welecome my host”,按下输入密码按键后,液晶显示:“input:”,通过按键输入密码,若密码识别成功,继电器工作,开锁成功,OLED显示“OK”。若密码输入错误,则不会开锁,OLED显示“ERROR”。
  ②设置模式:通过各个按下按键进入对应按键的模式。在模式下可以完成输入密码、撤销密码、和更改密码的功能。进入输入密码模式后,通过按键#选择哪一位密码需要更改,通过按键D将密码修改,若密码修改完成后通过按键0将密码导入,OLED显示“SUCCESS”,且此时密码修改后下一次打开保存的还是修改的密码,调电不丢失自己修改的密码。
  **若是重新将代码烧入芯片中,首先需要按下0键将密码导入存储空间中,否则不能进行正常的输入密码比较


一、所需材料

  主要采用的是stm32f103zet6的开发板、正点原子的OLED显示屏、一个矩阵按键,一个继电器、一个电磁锁模块。

二、部分程序

1.main.c

代码如下(示例):

#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "oled.h"
#include "KEY1.h"
#include "usart.h"
#include "flash.h"


unsigned char Password2[7]={1,1,1,1,1,1,0};//修改后的新密码存储在这个数组中,密码长度为6位,数组最后一位为更改后密码标志位
unsigned char Password[6]={0,0,0,0,0,0};
#define SIZE sizeof(Password2)		//数组长度
#define FLASH_SAVE_ADDR  0X08070000//存储密码地址
#define FLASH_SAVE_ADDR1  0X08020000
u8 flag=0;
unsigned char Password1[7]={1,2,3,4,5,6,0};;
unsigned char Password_count=0; 

unsigned int a_c,b_c,c_c,d_c;
unsigned char key_back;
unsigned char flag_key_back=0,flag_key_back1=0;
u16 flag_key_data=0;
u16* flag_key=&flag_key_data;
/*
修改密码并进行密码导入函数
*/
void change_key()
{
	static unsigned int i_c=0;
	unsigned char a;
	if((key_back=='#')&&(flag_key_back1==1))//选择密码修改是哪一位
	{
		a_c=Password[i_c];
		i_c++;
		if(i_c==7)
		{
			i_c=1;
			
		}
		OLED_ShowChar(50+i_c*8,8,13+' ',16,1);
	  OLED_Refresh_Gram();
		if(i_c>1)
		{
		OLED_ShowChar(50+(i_c-1)*8,8,10+' ',16,1);
		OLED_Refresh_Gram();
		}
		flag_key_back=1;
	}
	if((key_back=='D')&&(flag_key_back==1))//由上面选择是哪一位要修改的密码,在对这一位密码进行递增的方式进行修改,累加到9后回到0
	{
			a_c++;
		  if(a_c>9)
				a_c=0;
			Password2[i_c-1]=a_c;
			OLED_ShowChar(50+i_c*8,8,Password2[i_c-1]+'0',16,1);
			OLED_Refresh_Gram();
	}
	if(key_back==0)	//修改密码后按下0键确认导入
  { 
			Password2[6]=1;
		  delay_ms(10);
			STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)Password2,SIZE);
			OLED_Clear();
			OLED_ShowString(0,0,">",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>>>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>>>>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>>>>>",24);OLED_Refresh_Gram();delay_ms(100);
		OLED_ShowString(0,0,">>>>>>>>",24);OLED_Refresh_Gram();delay_ms(100);
		  OLED_Refresh_Gram();
		  delay_ms(100);
			STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)Password1,SIZE);
			OLED_Clear();
		  OLED_ShowString(25,25,"Suscess!",12);
		  OLED_Refresh_Gram();
		  delay_ms(50);
		  OLED_ShowString(25,25,"Suscess!",16);
		  OLED_Refresh_Gram();delay_ms(50);
		  OLED_ShowString(25,25,"Suscess!",24);
		  OLED_Refresh_Gram();delay_ms(50);
	}
}
/*
按键处理函数,对输入密码进行比较看密码是否输入正确
*/

void data_key()
{
	 unsigned char i;
	 unsigned char flag_data_key1=0;
		i=' ';//因为采用的ASCII码数组来显示OLED所以需要先转换成ASCII码

	if(key_back=='C')
	{
		OLED_Clear();
		OLED_ShowString(0,8,"input:",16);
		flag=1;
    Password_count=0;
		flag_key_back=0;
		flag_key_back1=1;
		flag_data_key1=1;
		GPIO_SetBits(GPIOF,GPIO_Pin_13);
	}
	if(flag==1)
	{
		if(key_back>0&&key_back<=9)			  //输入密码0-9
		    {
			   if(Password_count<6) 
			    {
				   Password[Password_count]=key_back;
				   Password_count++;
					 if(Password_count==1)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
						 OLED_Refresh_Gram();
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==2)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==3)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==4)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
						 OLED_Refresh_Gram();

					 }
					 if(Password_count==5)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==6)
					 {
					 OLED_ShowChar(50+Password_count*8,8,10+i,16,1);
						 OLED_Refresh_Gram();
					 }
				  }
			  }
		else if((key_back=='A'))				  //撤销按键
			 {
			   	if(Password_count>0) Password_count--;
				 if(Password_count==0)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==1)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==2)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==3)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();

					 }
					 if(Password_count==4)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();
					 }
					 if(Password_count==5)
					 {
					 OLED_ShowChar(58+Password_count*8,8,13+i,16,1);
					 OLED_ShowChar(58+(Password_count+1)*8,8,i,16,1);
						 OLED_Refresh_Gram();
					 }
				  
			 }	
		else if((key_back=='B')&&(Password1[6]==0))				  //确认按键
			 {
				 if((Password[0]==1&&Password[1]==2&&Password[2]==3&&Password[3]==4&&Password[4]==5&&Password[5]==6)||(Password[0]==Password1[0]&&Password[1]==Password1[1]&&Password[2]==Password1[2]&&Password[3]==Password1[3]&&Password[4]==Password1[4]&&Password[5]==Password1[5]))
						{  
								OLED_Clear();
								OLED_ShowString(20,20,"OK",24);
							  OLED_Refresh_Gram();
							flag_key_back1=0;
							flag_data_key1=0;
							GPIO_SetBits(GPIOF,GPIO_Pin_13);  //继电器的引脚PF13
						}
					else 
					 {
						 OLED_Clear();
						 OLED_ShowString(20,20,"ERROR",24);
						 OLED_Refresh_Gram();
						 flag_key_back1=0;
						 flag_data_key1=0;
						 GPIO_ResetBits(GPIOF,GPIO_Pin_13);							 
					 }
			 }
			 		else if((key_back=='B')&&(Password1[6]==1))				  //确认按键
			 {
				 if(Password[0]==Password1[0]&&Password[1]==Password1[1]&&Password[2]==Password1[2]&&Password[3]==Password1[3]&&Password[4]==Password1[4]&&Password[5]==Password1[5])
						{  
								OLED_Clear();
								OLED_ShowString(60,30,"OK",24);
							  OLED_Refresh_Gram();
							  //¼ÌµçÆ÷Òý½Åpf13
							GPIO_ResetBits(GPIOF,GPIO_Pin_13);
						}
					else 
					 {
						 OLED_Clear();
						 OLED_ShowString(40,30,"ERROR",24);
						 OLED_Refresh_Gram();
						 GPIO_SetBits(GPIOF,GPIO_Pin_13);
					 }
				 }
			 OLED_Refresh_Gram();
			 
	}
}
/*
主函数,来调用子函数的内容
*/
 int main(void)
 {	 
	
	delay_init();	    	 //延时函数初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 //设置NVIC中断优先级分组2,2位抢占优先级,2位响应优先级
	OLED_Init();			//初始化OLED
 Matrix_Key_Init(); 
  OLED_ShowString(0,0," --------------- ",16);   
	OLED_ShowString(20,16, "Welecome",24);  
 	OLED_ShowString(25,46,"MY HOST",16);  
	OLED_Refresh_Gram();		//更新显示到OLED
	delay_ms(1000);
  GPIO_SetBits(GPIOF,GPIO_Pin_13);

		  delay_ms(1000);
			STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)Password1,SIZE);
	while(1) 
	{
		key_back=Matrix_Key_Scan();
		data_key();
    change_key();

	}	 
 }

2.key.c

(有较强的可移植性,之前根据五一单片机的那种矩阵按键格式写的,但后来在网上进行翻阅的时候发现下面这种代码有很强的移植性,要是要更改只需更改.h文件中引脚就可以,所以网友们还是万能的)

代码如下(示例):

#include "KEY1.h"
#include "delay.h"
#include "sys.h"

unsigned char Y1,Y2,Y3,Y4;


void Matrix_Key_Init(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;   
   RCC_APB2PeriphClockCmd(X1_RCC|X2_RCC|X3_RCC|X4_RCC|Y1_RCC|Y2_RCC|Y3_RCC|Y4_RCC|RCC_APB2Periph_AFIO, ENABLE);
   GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 
	
   GPIO_InitStructure.GPIO_Pin =  X1_GPIO_PIN ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(X1_GPIO_PORT, &GPIO_InitStructure);
    
   GPIO_InitStructure.GPIO_Pin =  X2_GPIO_PIN ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(X2_GPIO_PORT, &GPIO_InitStructure);
    
   GPIO_InitStructure.GPIO_Pin =  X3_GPIO_PIN ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(X3_GPIO_PORT, &GPIO_InitStructure);
	
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Pin = X4_GPIO_PIN ;    
   GPIO_Init(X4_GPIO_PORT, &GPIO_InitStructure);
   
   GPIO_InitStructure.GPIO_Pin =  Y1_GPIO_PIN ;   
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(Y1_GPIO_PORT, &GPIO_InitStructure);	
   
   GPIO_InitStructure.GPIO_Pin =  Y2_GPIO_PIN ;   
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(Y2_GPIO_PORT, &GPIO_InitStructure);	
   
   GPIO_InitStructure.GPIO_Pin =  Y3_GPIO_PIN ;   
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(Y3_GPIO_PORT, &GPIO_InitStructure);	
	
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Pin = Y4_GPIO_PIN;      
   GPIO_Init(Y4_GPIO_PORT, &GPIO_InitStructure);	
	 
	 GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13 ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOF, &GPIO_InitStructure);
}

int Matrix_Key_Scan(void)
{
	static char key_down = 0;
	uchar KeyVal = KEY_ERR;
	GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN);  
	GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN);  
	GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN);  
	GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN);  

	if ((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y2_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y3_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y4_GPIO_PIN)==1))
	{
		delay_ms(10);
		if ((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y2_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y3_GPIO_PIN)==1) || (GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y4_GPIO_PIN)==1))
		{
			if (key_down == 0)
			{	
				key_down = 1;		
				
				GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN);
				GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
				GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
				GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
					 
				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
				
				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
					KeyVal='A';
				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
					KeyVal='B';
				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
					KeyVal='C';
				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
					KeyVal='D';
/**************************************************/		
				
				GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
				GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN);
				GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);
				GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);
								
				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
				
				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
					KeyVal=3;
				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
					KeyVal=6;
				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
					KeyVal=9;
				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
					KeyVal='#';
				
/**************************************************/
				
				GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
				GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);
				GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN);
				GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);   

				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
				
				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
					KeyVal=2;
				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
					KeyVal=5;
				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
					KeyVal=8;
				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
					KeyVal=0;	
				
/**************************************************/
				
				GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);
				GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN); 
				GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN); 
				GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN); 
				
				Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);
				Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);
				Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);
				Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);
				
				if(Y1==1&&Y2==0&&Y3==0&&Y4==0)
					KeyVal=1;
				if(Y1==0&&Y2==1&&Y3==0&&Y4==0)
					KeyVal=4;
				if(Y1==0&&Y2==0&&Y3==1&&Y4==0)
					KeyVal=7;
				if(Y1==0&&Y2==0&&Y3==0&&Y4==1)
					KeyVal='*';
			}
		}
	}
	else
	{
		key_down = 0;
		KeyVal = KEY_ERR;
	}
	
	return KeyVal;
}

3.key.h

#ifndef _KEY1_H
#define _KEY1_H	 

#include <stm32f10x.h>
#include "usart.h"
#include "sys.h"

#define uint unsigned int 
#define uchar unsigned char

#define X1_GPIO_PORT GPIOF           
#define X2_GPIO_PORT GPIOF   
#define X3_GPIO_PORT GPIOF           
#define X4_GPIO_PORT GPIOF 

#define Y1_GPIO_PORT GPIOF         
#define Y2_GPIO_PORT GPIOF   
#define Y3_GPIO_PORT GPIOF           
#define Y4_GPIO_PORT GPIOF 

#define X1_GPIO_PIN GPIO_Pin_7
#define X2_GPIO_PIN GPIO_Pin_6
#define X3_GPIO_PIN GPIO_Pin_5
#define X4_GPIO_PIN GPIO_Pin_4

#define Y1_GPIO_PIN GPIO_Pin_0
#define Y2_GPIO_PIN GPIO_Pin_1
#define Y3_GPIO_PIN GPIO_Pin_2
#define Y4_GPIO_PIN GPIO_Pin_3

#define X1_RCC RCC_APB2Periph_GPIOF
#define X2_RCC RCC_APB2Periph_GPIOF
#define X3_RCC RCC_APB2Periph_GPIOF
#define X4_RCC RCC_APB2Periph_GPIOF

#define Y1_RCC RCC_APB2Periph_GPIOF
#define Y2_RCC RCC_APB2Periph_GPIOF
#define Y3_RCC RCC_APB2Periph_GPIOF
#define Y4_RCC RCC_APB2Periph_GPIOF


#define KEY_ERR 255


void Matrix_Key_Init(void);
int Matrix_Key_Scan(void);
void Matrix_Key_Test(void) ;

#endif


三、有需要注意的地方

  ①如果大家用的是开发板的引脚输出来的高低电平作为5v继电器开与关的状态,这样电压是不够的,,因为引脚输出的电压是3.3v,而继电器需要的是5v的电压,所以需要在作为连接继电器的输出引脚再连接一个放大电路3.3v转5v,我也是焊接了一个这样的电路,只需要两个电阻和一个三极管组成就可以了,不懂的可以在网上搜关于这个电路
  ②如果对于功能不能正常实现可以慢慢找到相对应的错误所在,如何找到对应代码,可以用串口助手进行调试也可以用OLED调试,因为这个实验用到了OLED,所以直接用OLED调试也蛮方便,在认为错误的代码上下加上OLED显示函数,看看经过了这个代码能不能实现OLED对应的显示,如果不能说明这段代码确实有问题。

总结

  这段程序也经过我自己操作实现了功能,只有通过实践操作才能让自己的能力一步一步上涨,虽然途中会遇到很多问题和一些错误,一个一个解决就好了,经验也是慢慢堆起来的,从简单到复杂,希望接下来我能继续对简易密码锁改善成(二),循循渐进。
在这里插入图片描述
整体轮廓
在这里插入图片描述

相关程序全部资料

链接:https://pan.baidu.com/s/1xcOLsRNtreshgxoWN3JBYw
提取码:like



学习从零开始,到无穷结束

版权声明:本文为CSDN博主「Justin-Wei」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46285130/article/details/118435145

生成海报
点赞 0

Justin-Wei

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

STM32f103 简易密码锁(一)

开头 希望这个实验能从一个实验由(一)到(二)到(三)到…等等,相关代码在文章结尾,虽然现在能力还不够,那就力所能及叭

MW75蓝牙5.2双模热插拔PCB

软件支持 LDN通用蓝牙双模固件和驱动功能参考链接 一些常见问题解答(FAQ) 请参阅这个链接 电池开关 开关拨向下边(ON侧),开启电池供电(此时如果断