基于STM32电子密码锁

基于STM32电子密码锁

(程序+原理图+PCB+设计报告)

功能介绍

具体功能:

1.正确输入密码前提下,开锁并有正确提示;

2.错误输入密码情况下,蜂鸣器报警并短暂锁定键盘;

3.密码可以根据用户需要更改;

4.为防止误操作,更改密码需有两次确认;

5.输出密码错误三次锁死键盘;

6.密码掉电保存功能;

添加图片注释,不超过 140 字(可选)

程序

cs 复制代码
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "sys.h"
#include "delay.h"
#include "lcd.h"
#include "led.h"
#include "usart.h"
#include "dht11.h"
#include "key.h"
#include "beep.h"
#include <stdio.h>
#include "stmflash.h"
#include "timer.h"
#include "exit.h"
#define ADDR_hum_up_1  0X0800b000
#define ADDR_hum_up_2  0X0800c000
int key=0;
int j=0;
u8 k1_flag=1;
u8 k2_flag=1;
u8 k3_flag=1;
u8 k4_flag=1;
int setpass_flag11=1;//标识正在设置密码,继电器不关闭
int err3_flag=1;
int i=0;
int djtime_flag=360;
int down_flag=0;
static u8 key_up=1;//不支持连按
u8 open_flag=1;//用于标识是否是系统的第一次打开

u8 pass_shuru=0;

u8 setpassword_flag=0;
u8 setopen_flag=1;//用于标识开机之后是否打开过
u8 setpass_flag=0;//当密码设置成功之后的标志位
u8 err_flag=0;//输出错误次数记录标志位
u8 errtime_flag=0;//用于错误之后延时并重置屏幕的标志位
u8 beep_flag=1;//用于标识当按键按下,蜂鸣器滴一声的时间
u8 password[]={9,9,9,9,9,9};;//记录输入的密码
u8 setpassword1[6]={1,1,1,1,1,1};//设置密码的存放位置
u8 setpassword2[6];//设置密码的存放位置

static u8 ok_flag=0;//记录每次判断密码有几位正确
u8 flag16=1;//标志按键16是第几次按下,做相应的动作

u8 cspassword[]={0,0,0,0,0,0};
u8 cjpassword[]={1,3,1,4,2,0};

u8 table0[]="===Coded Lock===";
u8 table1[]="password:       ";
u8 table2[]="      open      ";
u8 table3[]="      error     ";
u8 table4[]="SetNewWordEnable";
u8 table5[]="input again     ";
u8 table6[]="ResetPassword OK";
u8 flash1[]={0};
u8 flash2[]={1,0,0,0,0,0};





void show1(void)
 {
	 	LCD1602_Show_dat(0,1,table1[0]);
		LCD1602_Show_dat(1,1,table1[1]);
		LCD1602_Show_dat(2,1,table1[2]);
		LCD1602_Show_dat(3,1,table1[3]);
		LCD1602_Show_dat(4,1,table1[4]);
		LCD1602_Show_dat(5,1,table1[5]);
		LCD1602_Show_dat(6,1,table1[6]);
		LCD1602_Show_dat(7,1,table1[7]);
		LCD1602_Show_dat(8,1,table1[8]);
	 	LCD1602_Show_dat(9,1,table1[9]);
	  for(j=0;j<i;j++)
	 {
		 LCD1602_Write_Dat('*');
	 }
	 for(j=0;j<6-i;j++)
	 {
		 LCD1602_Write_Dat(' ');
	 }


 } 
 void show2(void)
 {
	 	LCD1602_Show_dat(0,1,table2[0]);
		LCD1602_Show_dat(1,1,table2[1]);
		LCD1602_Show_dat(2,1,table2[2]);
		LCD1602_Show_dat(3,1,table2[3]);
		LCD1602_Show_dat(4,1,table2[4]);
		LCD1602_Show_dat(5,1,table2[5]);
		LCD1602_Show_dat(6,1,table2[6]);
		LCD1602_Show_dat(7,1,table2[7]);
		LCD1602_Show_dat(8,1,table2[8]);
	 	LCD1602_Show_dat(9,1,table2[9]);
		LCD1602_Show_dat(0xa,1,table2[10]);
		LCD1602_Show_dat(0xb,1,table2[11]);
		LCD1602_Show_dat(0xc,1,table2[12]);
		LCD1602_Show_dat(0xd,1,table2[13]);
		LCD1602_Show_dat(0xe,1,table2[14]);
		LCD1602_Show_dat(0xf,1,table2[15]);
 }
  void show3(void)
 {
	 	LCD1602_Show_dat(0,1,table3[0]);
		LCD1602_Show_dat(1,1,table3[1]);
		LCD1602_Show_dat(2,1,table3[2]);
		LCD1602_Show_dat(3,1,table3[3]);
		LCD1602_Show_dat(4,1,table3[4]);
		LCD1602_Show_dat(5,1,table3[5]);
		LCD1602_Show_dat(6,1,table3[6]);
		LCD1602_Show_dat(7,1,table3[7]);
		LCD1602_Show_dat(8,1,table3[8]);
	 	LCD1602_Show_dat(9,1,table3[9]);
		LCD1602_Show_dat(0xa,1,table3[10]);
		LCD1602_Show_dat(0xb,1,table3[11]);

	 	if(err3_flag==1)
	  {
			LCD1602_Show_dat(0xc,1,table3[12]);
			LCD1602_Show_dat(0xd,1,table3[13]);
		  LCD1602_Show_dat(0xe,1,table3[14]);
		  LCD1602_Show_dat(0xf,1,table3[15]);
	  }
	  else if(err3_flag==2)
	  {
			LCD1602_Show_dat(0xc,1,0x30+djtime_flag/2/100);
			LCD1602_Show_dat(0xd,1,0x30+djtime_flag/2/10%10);
			LCD1602_Show_dat(0xe,1,0x30+djtime_flag/2%10);
			LCD1602_Show_dat(0xf,1,'s');
		}

 }
 void show4(void)
 {
	 	LCD1602_Show_dat(0,1,table4[0]);
		LCD1602_Show_dat(1,1,table4[1]);
		LCD1602_Show_dat(2,1,table4[2]);
		LCD1602_Show_dat(3,1,table4[3]);
		LCD1602_Show_dat(4,1,table4[4]);
		LCD1602_Show_dat(5,1,table4[5]);
		LCD1602_Show_dat(6,1,table4[6]);
		LCD1602_Show_dat(7,1,table4[7]);
		LCD1602_Show_dat(8,1,table4[8]);
	 	LCD1602_Show_dat(9,1,table4[9]);
		LCD1602_Show_dat(0xa,1,table4[10]);
		LCD1602_Show_dat(0xb,1,table4[11]);
		LCD1602_Show_dat(0xc,1,table4[12]);
		LCD1602_Show_dat(0xd,1,table4[13]);
		LCD1602_Show_dat(0xe,1,table4[14]);
		LCD1602_Show_dat(0xf,1,table4[15]);
 }
 void show5(void)
 {
	 	LCD1602_Show_dat(0,1,table5[0]);
		LCD1602_Show_dat(1,1,table5[1]);
		LCD1602_Show_dat(2,1,table5[2]);
		LCD1602_Show_dat(3,1,table5[3]);
		LCD1602_Show_dat(4,1,table5[4]);
		LCD1602_Show_dat(5,1,table5[5]);
		LCD1602_Show_dat(6,1,table5[6]);
		LCD1602_Show_dat(7,1,table5[7]);
		LCD1602_Show_dat(8,1,table5[8]);
	 	LCD1602_Show_dat(9,1,table5[9]);
		LCD1602_Show_dat(0xa,1,table5[10]);
		LCD1602_Show_dat(0xb,1,table5[11]);
		LCD1602_Show_dat(0xc,1,table5[12]);
		LCD1602_Show_dat(0xd,1,table5[13]);
		LCD1602_Show_dat(0xe,1,table5[14]);
		LCD1602_Show_dat(0xf,1,table5[15]);
 }
 void show6(void)
 {
	 	LCD1602_Show_dat(0,1,table6[0]);
		LCD1602_Show_dat(1,1,table6[1]);
		LCD1602_Show_dat(2,1,table6[2]);
		LCD1602_Show_dat(3,1,table6[3]);
		LCD1602_Show_dat(4,1,table6[4]);
		LCD1602_Show_dat(5,1,table6[5]);
		LCD1602_Show_dat(6,1,table6[6]);
		LCD1602_Show_dat(7,1,table6[7]);
		LCD1602_Show_dat(8,1,table6[8]);
	 	LCD1602_Show_dat(9,1,table6[9]);
		LCD1602_Show_dat(0xa,1,table6[10]);
		LCD1602_Show_dat(0xb,1,table6[11]);
		LCD1602_Show_dat(0xc,1,table6[12]);
		LCD1602_Show_dat(0xd,1,table6[13]);
		LCD1602_Show_dat(0xe,1,table6[14]);
		LCD1602_Show_dat(0xf,1,table6[15]);
 }
void mound(void)
{			

	if(open_flag==1)
	{
		
		show1();
	}
	else if(open_flag==2)
	{
		show2();
	}
	else if(open_flag==3)
	{
		show3();
	}
	else if(open_flag==4)
	{
		show4();
	}
	else if(open_flag==5)
	{
		show5();
	}
	else if(open_flag==6)
	{
		show6();
	}


	if(key!=240 &&key_up==1)
	{
		GPIO_SetBits(GPIOC,GPIO_Pin_13);//

		delay_ms(20);
		GPIO_ResetBits(GPIOC,GPIO_Pin_13);//
		
   	key_up=0;
		if(key>=0 && key<=9)
		{

			if(pass_shuru==0)
			{
				if(i==0)
				{
				password[0]=1;
				password[1]=3;
				password[2]=1;
				password[3]=4;
				password[4]=2;
				password[5]=0;
				}
				password[i]=key;		
				i++;

			}
			else if(pass_shuru==1)
			{
				if(i==0)
				{
				password[0]=1;
				password[1]=3;
				password[2]=1;
				password[3]=4;
				password[4]=2;
				password[5]=0;
				}
				open_flag=1;
				setpassword1[i]=key;
				i++;


			}
			else if(pass_shuru==2)
			{
				if(i==0)
				{
				password[0]=1;
				password[1]=3;
				password[2]=1;
				password[3]=4;
				password[4]=2;
				password[5]=0;
				}
				open_flag=1;
				setpassword2[i]=key;
				if(key==setpassword1[i])
				{
					ok_flag++;
				}
				i++;

				

				
				

			}
		}
		if(key==13)
		{
			TIM_Cmd(TIM2, DISABLE);
			//手动关闭继电器
			GPIO_ResetBits(GPIOB,GPIO_Pin_0);
			open_flag=1;
			pass_shuru=0;
		}
		if(key==14)
		{		
			if(i!=0)
			{
				i--;
			}
			

		}
		if(key==15)
		{
			if(i==6)
			{
					if(pass_shuru==0)
					{

						if(setpass_flag==1)
						{


							for(i=0;i<6;i++)
							{
								if(password[i]==setpassword1[i])
								{
									ok_flag++;
								}
							}
							i=0;
//							LCD1602_Show_dat(0,0,0x30+ok_flag/10);
//							LCD1602_Show_dat(1,0,0x30+ok_flag%10);


							if(ok_flag==6)
							{						

								open_flag=2;
								ok_flag=0;

								GPIO_SetBits(GPIOB,GPIO_Pin_0);
								GPIO_SetBits(GPIOC,GPIO_Pin_13);//
								TIM_Cmd(TIM2, ENABLE);  //使能TIMx
								setopen_flag=2;
								err_flag=0;
							}
							else
							{
								ok_flag=0;

								for(i=0;i<6;i++)
								{
									if(password[i]==cjpassword[i])
									{
										ok_flag++;
									}
								}
								i=0;

								if(ok_flag==6)
								{
									open_flag=2;
									ok_flag=0;
									GPIO_SetBits(GPIOB,GPIO_Pin_0);
									GPIO_SetBits(GPIOC,GPIO_Pin_13);//
									TIM_Cmd(TIM2, ENABLE);  //使能TIMx
									setopen_flag=2;
									err_flag=0;
								}
								else
								{
									open_flag=3;
									ok_flag=0;
									err_flag++;
									
									if(err_flag<3)
									{
										GPIO_SetBits(GPIOC,GPIO_Pin_13);//
										TIM_Cmd(TIM4, ENABLE);  //使能TIMx
									}
									else if(err_flag==3)
									{
										TIM_Cmd(TIM4, ENABLE);
										err3_flag=2;
									}
									
								}



							}
						}
						else
						{
							for(i=0;i<6;i++)
							{
								if(password[i]==cspassword[i])
								{
									ok_flag++;
									
								}
							}
							i=0;
		//				  LCD1602_Show_dat(0,0,0x30+ok_flag/10);
		//	        LCD1602_Show_dat(1,0,0x30+ok_flag%10);

							if(ok_flag==6)
							{
								open_flag=2;
								ok_flag=0;
								GPIO_SetBits(GPIOB,GPIO_Pin_0);
								
								GPIO_SetBits(GPIOC,GPIO_Pin_13);//
								TIM_Cmd(TIM2, ENABLE);  //使能TIMx
								setopen_flag=2;
								err_flag=0;  



							}
							else
							{
								ok_flag=0;
								for(i=0;i<6;i++)
								{
									if(password[i]==cjpassword[i])
									{
										ok_flag++;
									}
								}
								i=0;
								if(ok_flag==6)
								{
									open_flag=2;
									ok_flag=0;
									GPIO_SetBits(GPIOB,GPIO_Pin_0);
									GPIO_SetBits(GPIOC,GPIO_Pin_13);//
									TIM_Cmd(TIM2, ENABLE);  //使能TIMx
									setopen_flag=2;
									err_flag=0;

								}
								else
								{
									open_flag=3;
									ok_flag=0;
									err_flag++;
									
									if(err_flag<3)
									{
										GPIO_ResetBits(GPIOC,GPIO_Pin_13);//
										TIM_Cmd(TIM4, ENABLE);  //使能TIMx
									}
									else if(err_flag==3)
									{
										TIM_Cmd(TIM4, ENABLE);
										err3_flag=2;
									}
								}


							}

						}
						
					}
				}
			else
			{
				i=0;
				open_flag=3;
				ok_flag=0;
				err_flag++;
				
				if(err_flag<3)
				{
					GPIO_SetBits(GPIOC,GPIO_Pin_13);//
					TIM_Cmd(TIM4, ENABLE);  //使能TIMx
				}
				else if(err_flag==3)
				{
					TIM_Cmd(TIM4, ENABLE);
					err3_flag=2;
				}
			}
			
		}
		if(key==16)
		{

			if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_0))
			{			
				setpass_flag11=2;
				if(flag16==1)
				{
						open_flag=4;
						pass_shuru=1;
						flag16=2;
						i=0;
				}
				else if(flag16==2)
				{			
					open_flag=5;
					pass_shuru=2;
					flag16=3;
					i=0;
				}
				else if(flag16==3)
			  {
					i=0;
					if(ok_flag==6)
					{
						
						setpass_flag=1;
						flash1[0]=setpass_flag;
						STMFLASH_Write(ADDR_hum_up_1,(u16*)flash1,sizeof(flash1));
						for(j=0;j<6;j++)
						{
							flash2[j]=setpassword1[j];
							
						}
						STMFLASH_Write(ADDR_hum_up_2,(u16*)flash2,sizeof(flash2));
						j=0;
						open_flag=6;
						ok_flag=0;
						TIM_Cmd(TIM2, ENABLE);  //使能TIMx

					}
					else
					{
						open_flag=3;
						ok_flag=0;
						TIM_Cmd(TIM4, ENABLE);  //使能TIMx			
					}
					flag16=0;
					pass_shuru=0;
					setpass_flag11=1;
					GPIO_ResetBits(GPIOB,GPIO_Pin_0);
				}
			}

	  }
  }

	
}
	


//

 void KEY_Scan(void) //实现矩阵键盘。返回值为,各按键的键值,此键值由用户自己定义。
{
	
  GPIO_ResetBits(GPIOB,GPIO_Pin_13);
	GPIO_ResetBits(GPIOB,GPIO_Pin_14);
	GPIO_ResetBits(GPIOB,GPIO_Pin_15);
	GPIO_ResetBits(GPIOA,GPIO_Pin_8);

	if(P5==1 && P6==1 && P7==1&& P8==1)
	{
		key=240;
		key_up=1;

	}
	else if(key_up==1&&(P5==0 ||  P6==0 || P7==0 || P8==0))
	{
	  		

	GPIO_SetBits(GPIOB,GPIO_Pin_14);
	GPIO_SetBits(GPIOB,GPIO_Pin_15);
	GPIO_SetBits(GPIOA,GPIO_Pin_8);
		GPIO_ResetBits(GPIOB,GPIO_Pin_13);
		if(P5==0 ||  P6==0 || P7==0 || P8==0)  //如果PA8.15.14.13全为0,则没有键按下。此时,返回值为-1.
	  {
			if(P8==0)
			{
					key=1;
			}
			else if(P7==0)
			{
					key=2;
			}
			else if(P6==0)
			{
				key=3;
			}
			else if(P5==0)
			{
				key=11;
			}
  	}
	  GPIO_SetBits(GPIOB,GPIO_Pin_13);
	  GPIO_SetBits(GPIOB,GPIO_Pin_15);
  	GPIO_SetBits(GPIOA,GPIO_Pin_8);
		GPIO_ResetBits(GPIOB,GPIO_Pin_14);
		if(P5==0 ||  P6==0 || P7==0 || P8==0)  //如果PA8.15.14.13全为0,则没有键按下。此时,返回值为-1.
	  {
			if(P8==0)
			{
				key=4;
			}
			else if(P7==0)
			{
				key=5;
			}
			else if(P6==0)
			{
				key=6;
			}
			else if(P5==0)
			{
				key=12;
			}
	  }
	  GPIO_SetBits(GPIOB,GPIO_Pin_14);
	  GPIO_SetBits(GPIOB,GPIO_Pin_13);
	  GPIO_SetBits(GPIOA,GPIO_Pin_8);
		GPIO_ResetBits(GPIOB,GPIO_Pin_15);
		if(P5==0 ||  P6==0 || P7==0 || P8==0)  //如果PA8.15.14.13全为0,则没有键按下。此时,返回值为-1.
	  {
			if(P8==0)
			{
				key=7;
			}
			else if(P7==0)
			{
				key=8;
			}
			else if(P6==0)
			{
				key=9;
			}
			else if(P5==0)
			{
				key=13;
			}
	  }
	  GPIO_SetBits(GPIOB,GPIO_Pin_14);
	  GPIO_SetBits(GPIOB,GPIO_Pin_13);
	  GPIO_SetBits(GPIOB,GPIO_Pin_15);
		GPIO_ResetBits(GPIOA,GPIO_Pin_8);
		if(P5==0 ||  P6==0 || P7==0 || P8==0)  //如果PA8.15.14.13全为0,则没有键按下。此时,返回值为-1.
	  {
			if(P8==0)
			{
				key=14;
			}
			else if(P7==0)
			{
				key=0;
			}
			else if(P6==0)
			{
				key=15;
			}
			else if(P5==0)
			{
				key=16;
			}
	  }
		
		
		
		
		
	}





}


int main(void)
{
	BEEP_Init();
	LED_Init();
	delay_init();  
	LCD1602_Init();
  KEY_Init();
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	TIM2_Int_Init(4999,7199);
  TIM3_Int_Init(29,35999);
	TIM4_Int_Init(4999,7199);//每500ms计算一次速度的值,并显示
	LCD1602_Show_dat(0,0,table0[0]);
	LCD1602_Show_dat(1,0,table0[1]);
	LCD1602_Show_dat(2,0,table0[2]);
	LCD1602_Show_dat(3,0,table0[3]);
	LCD1602_Show_dat(4,0,table0[4]);
	LCD1602_Show_dat(5,0,table0[5]);
	LCD1602_Show_dat(6,0,table0[6]);
	LCD1602_Show_dat(7,0,table0[7]);
	LCD1602_Show_dat(8,0,table0[8]);
	LCD1602_Show_dat(9,0,table0[9]);
	LCD1602_Show_dat(0xa,0,table0[10]);
	LCD1602_Show_dat(0xb,0,table0[11]);
	LCD1602_Show_dat(0xc,0,table0[12]);
	LCD1602_Show_dat(0xd,0,table0[13]);
	LCD1602_Show_dat(0xe,0,table0[14]);
	LCD1602_Show_dat(0xf,0,table0[15]);
//	flash1[0]=100;
//STMFLASH_Write(ADDR_hum_up_1,(u16*)flash1,sizeof(flash1));
//STMFLASH_Write(ADDR_hum_up_2,(u16*)flash2,sizeof(flash2));

  TIM_Cmd(TIM3, ENABLE);
  STMFLASH_Read(ADDR_hum_up_1,(u16*)flash1,sizeof(flash1));
	setpass_flag=flash1[0];
  STMFLASH_Read(ADDR_hum_up_2,(u16*)flash2,sizeof(flash2));
	for(j=0;j<6;j++)
	{
		setpassword1[j]=flash2[j];
		
	}
	j=0;
	
	open_flag=1;
	pass_shuru=0;
	while(1)
	{
		mound();
		if(down_flag==2)
		{
			GPIO_ResetBits(GPIOC,GPIO_Pin_13);
		}
		if(down_flag==5)
		{
			down_flag=0;
			if(setpass_flag11==2)
			{
			 TIM_Cmd(TIM2, DISABLE);
			}
			else
			{			
				open_flag=1;
			  pass_shuru=0;
			  GPIO_ResetBits(GPIOC,GPIO_Pin_13);
			  TIM_Cmd(TIM2, DISABLE);
				GPIO_ResetBits(GPIOB,GPIO_Pin_0);
			}

		}
		
		if(errtime_flag==2)
		{
			GPIO_ResetBits(GPIOC,GPIO_Pin_13);
		}
		if(errtime_flag==3)
		{
			GPIO_SetBits(GPIOC,GPIO_Pin_13);
		}
		if(errtime_flag==4)
		{
			GPIO_ResetBits(GPIOC,GPIO_Pin_13);
		}
		if(errtime_flag==5)
		{
			GPIO_SetBits(GPIOC,GPIO_Pin_13);
		}

		if(errtime_flag==6)
		{
			open_flag=1;
			pass_shuru=0;
			errtime_flag=0;
			GPIO_ResetBits(GPIOC,GPIO_Pin_13);
			TIM_Cmd(TIM4, DISABLE);
		}

	}


	
	

}
	

void TIM2_IRQHandler(void)   //TIM2中断
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
		{
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );  //清除TIMx更新中断标志 
		}

		down_flag++;
		





		
}

//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
		{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
		}
	if(err_flag<3)
	{
		KEY_Scan();


	}



}
*******//完整资料
****//***微信公众号:木子单片机****/

//定时器4中断服务程序
void TIM4_IRQHandler(void)   //TIM4中断
{
	if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
	{
	TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx更新中断标志 
	}
	
	if(err3_flag==1)
	{
		errtime_flag++;
	}
	else if(err3_flag==2)
	{
		TIM_Cmd(TIM3, DISABLE);
		
		if(err_flag==3)
		{
			open_flag=3;
      djtime_flag--;
			if(djtime_flag%2==0)
			{
				GPIO_ResetBits(GPIOC,GPIO_Pin_13);
			}
			else
			{
				GPIO_SetBits(GPIOC,GPIO_Pin_13);
			}
			if(djtime_flag==0)
			{
				open_flag=1;
				pass_shuru=0;
				err_flag=0;
				djtime_flag=360;
				TIM_Cmd(TIM4, DISABLE);
				TIM_Cmd(TIM3, ENABLE);
			}
		}
	}

	
}

#include "sys.h"
#include "usart.h"	  
// 	 
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h"					//ucos 使用	  
#endif
//	 
/***微信公众号:木子单片机****/
// 	  
 

//
//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
_sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 

/*使用microLib的方法*/
 /* 
int fputc(int ch, FILE *f)
{
	USART_SendData(USART1, (uint8_t) ch);

	while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}	
   
    return ch;
}
int GetKey (void)  { 

    while (!(USART1->SR & USART_FLAG_RXNE));

    return ((int)(USART1->DR & 0x1FF));
}
*/
 
#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记	  
  
void uart_init(u32 bound){
  //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
  
	//USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
  //USART1_RX	  GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

  //Usart1 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  
   //USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	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(USART1, &USART_InitStructure); //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1 

}

void USART1_IRQHandler(void)                	//串口1中断服务程序
	{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
		Res =USART_ReceiveData(USART1);	//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
			{
			if(USART_RX_STA&0x4000)//接收到了0x0d
				{
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
				}
			else //还没收到0X0D
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
					}		 
				}
			}   		 
     } 
#if SYSTEM_SUPPORT_OS 	//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntExit();  											 
#endif
} 
#endif	

硬件设计

使用元器件:

单片机:STM32F103C8T6 ;

HRS1H-S-DC5V黄色6腿继电器;

2P蓝色端子;轻触按键;

3mm红色LED;蜂鸣器;

LCD1602液晶屏+16P排座;

8050三极管;3K电阻;

1K电阻;自锁开关;

添加图片注释,不超过 140 字(可选)

流程图:

添加图片注释,不超过 140 字(可选)

设计资料

01原理图

本系统原理图采用Altium Designer19设计,具体如图!

添加图片注释,不超过 140 字(可选)

02PCB

本系统pcb采用Altium Designer19设计,具体如图!

添加图片注释,不超过 140 字(可选)

03程序

本设计使用软件Keil5 MDK版本编程设计!具体如图!

添加图片注释,不超过 140 字(可选)

04设计报告

八千字设计报告,具体如下!

添加图片注释,不超过 140 字(可选)

04设计资料

全部资料包括程序(含注释)、AD原理图、PCB、实物图、任务书、元件清单、结构框图、设计报告、流程图、实物演示视频等。具体内容如下,全网最全! !

添加图片注释,不超过 140 字(可选)

点赞分享一起学习成长。

相关推荐
沉在嵌入式的鱼3 小时前
linux串口对0X0D、0X0A等特殊字符的处理
linux·stm32·单片机·特殊字符·串口配置
学习路上_write3 小时前
AD5293驱动学习
c语言·单片机·嵌入式硬件·学习
影阴3 小时前
存储器和寄存器
stm32·单片机·嵌入式硬件
吃西瓜的年年4 小时前
3. C语言核心语法2
c语言·嵌入式硬件·改行学it
李洛克075 小时前
RDMA CM UDP 通信完整指南
单片机·网络协议·udp
思茂信息5 小时前
CST电动车EMC仿真——电机控制器MCU滤波仿真
javascript·单片机·嵌入式硬件·cst·电磁仿真
小曹要微笑5 小时前
I2C总线技术解析(纯文字版)
单片机·嵌入式硬件·esp32·iic
我送炭你添花5 小时前
可编程逻辑器件(PLD)的发展历程、原理、开发与应用详解
嵌入式硬件·fpga开发
袖手蹲5 小时前
Arduino UNO Q 从 Arduino Cloud 远程控制闪烁 LED
人工智能·单片机·嵌入式硬件·电脑
平凡灵感码头6 小时前
第一次做蓝牙产品,从零开发 嵌入式开发日志(2)AC63NSDK 完整合并版目录说明
stm32·单片机·嵌入式硬件