基于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 字(可选)

点赞分享一起学习成长。

相关推荐
qq_401700412 小时前
单片机之单总线通信DS18B20和红外遥控
stm32
深圳市尚想信息技术有限公司2 小时前
工业4.0核心引擎!意法STM32F407ZET6 单片机 赋能智能PLC/网关设计
stm32·单片机·嵌入式硬件·st意法·单片机mcu
GodKK老神灭3 小时前
STM32 串口寄存器开发
stm32·单片机·嵌入式硬件
郦7776 小时前
MO+内核32位普冉单片机PY32F003开发板
单片机·嵌入式硬件
Ivy烎7 小时前
STM32学习笔记
笔记·stm32·学习
蜡笔小电芯8 小时前
【STM32】 LWIP -TCP 客户端收发数据
网络·stm32·tcp/ip
邹诗钰-电子信息工程8 小时前
嵌入式自学第四十二天
单片机·嵌入式硬件
iCxhust9 小时前
使用 Visual Studio 创建安装包的完整指南
ide·单片机·嵌入式硬件·microsoft·c#·visual studio
深圳市尚想信息技术有限公司11 小时前
意法STM32F103C8T6 单片机ARM Cortex-M3 国民MCU 电机控制到物联网专用
arm开发·stm32·单片机