B45 - Design of home fire protection and anti-theft system based on STM32 microcontroller

Design requirements

This design research is about the home fire prevention and anti-theft system based on STM32. The system uses STM32 single-chip microcomputer as the core of acquisition and control, and uses a variety of sensors to collect information, such as using temperature and humidity sensors to obtain environmental temperature and humidity. Digitalization of environmental information, using combustible gas sensors to provide the system with combustible gas leakage, smoke, etc. for real-time monitoring of the possibility of fires inside the house, to achieve real-time alarms, using voice recording and playback modules for intelligent voice prompts, using OLED screens for information Visual display functions such as temperature and humidity, smoke concentration, indoor occupant status, and alarm status, use relays as home power switches, always have the function of automatic alarm shutdown, use fans for ventilation, and release flammable gas concentrations that are too high to increase the safety of family fires Hidden dangers, use embedded hardware to realize the function of machine vision for face detection to prevent strangers from intruding. Use the GSM module to communicate with the home owner in real time, so that the home owner can obtain the security information status inside the home in real time. The design functions and parameters of this system are as follows.
2.1.1 Design function
(1) Real-time detection of indoor combustible gas and smoke concentration, so as to achieve real-time monitoring and trigger early warning (threshold can be customized).
(2) Collect indoor temperature, humidity and humidity in real time and display them on the OLED screen.
(3) After the system triggers the smoke warning, it will automatically open the window and turn on the fan for ventilation, and at the same time cut off the power supply of indoor appliances.
(4) The system can be set for face recognition (through the wide dynamic face recognition camera module to realize liveness detection and face detection functions), and the number of recognition can be set to be no less than 10. When the identification is unsuccessful three times, it is determined that an unknown person has broken in, and a system warning is triggered.
(5) After the system triggers the alarm, it can notify the user of the warning content through SMS.
2.2.2 Design parameters
(1) Temperature: 0°C ~ +50°C (threshold value can be set), accuracy: ±2°C; humidity: 20-90%RH, accuracy: ±5%RH (2) smoke concentration:
10- 5000PPM, accuracy: ±20ppm
(3) Equipment self-inspection cycle: 180 days
(4) Facial contour parameters: 68 or 128 feature points
(5) Recognition success rate: over 98%, recognition speed: within 1S
2.2 Overall framework of the
system Face detection, using the LCD screen to visualize the collected face data, using the OLED screen to verify the collected temperature and humidity, smoke concentration, and possible face information verification, etc., try to make the system information display intuitive and convenient Users can simply obtain the current system operating status and the data information they need to know. Therefore, the system is composed of temperature and humidity detection module, smoke sensor MQ2, face recognition module K210, and independent button acquisition module to collect data. STM32 single-chip microcomputer processes the collected data, and uses LCD and OLED to display the data in blocks. The LED and buzzer perform sound and light alarm, and use the SIM module to send the alarm information to the user's mobile phone through SMS. The overall framework of the system is shown in Figure 2.1.
insert image description here

in kind

insert image description here
The main work of this system debugging hardware is face recognition module debugging, sensor data collection, display and alarm status. The face recognition module is relatively complicated, because there are many data protocols in this module, so it is necessary to understand the communication process of the entire work of the module in detail. The collection, display and alarm of sensor data are the core of this system, which can collect data normally and Visual display on the screen is the most important physical debugging and sound and light alarm according to the preset.

Debugging of face recognition module

The face recognition module is divided into three functions: face acquisition (entry), face recognition, and face deletion according to the data manual and the system's use requirements for the module. According to the software debugging content in Chapter 4, these three major processes are produced as shown in Figure 5.2 process shown.
Figure 5.2 Debugging of face recognition module
Figure 5.2 Debugging of face recognition module

The three physical debugging results of the corresponding face recognition module are shown in Figure 5.3. It can be seen that the module and the single-chip microcomputer can communicate normally and work normally according to the face recognition process introduced in Chapter 4. It works normally in the real object. When the recognition is successful, the OLED screen can display the owner normally. If a non-recorded person is recognized, it will display an illegal intruder. The face can be registered and deleted in the setting interface.
insert image description here

Sensor acquisition and display

As shown in the figure below, it is the general framework of the system’s physical diagram during debugging. From it, it can be seen that the physical object needs to display multiple interfaces for information collection, display, threshold setting, etc. It can be seen that the pre-designed interface is roughly the same as the interface debugged through the physical object, and some display changes have been made in the middle according to the requirements, but they are generally the same.
insert image description here
insert image description here

modular design

Temperature and humidity module

This system uses the DHT11 temperature and humidity sensor, which collects the temperature and humidity values ​​in the home environment through this temperature and humidity sensor. The specific data of temperature and humidity in different environments are different, such as the temperature and humidity inside and outside the home. Therefore, the use of temperature and humidity can bring home users a more accurate digital environment reference.
insert image description here

Smoke concentration MQ2

This system uses the MQ2 sensor to detect the concentration of smoke and combustibles inside the home. The analog output of the sensor is sent to the analog input IO port of the single-chip microcomputer, and the input voltage is converted by the built-in 12-bit high-precision analog-to-digital converter inside the single-chip microcomputer. It is a digital quantity, and the corresponding concentration value is obtained through nonlinear operation. MQ2 smoke concentration sensor is a gas-sensitive semiconductor component made of metal oxide tin dioxide-based N-type semiconductor. The metal oxide semiconductor component has a low electrical conductivity and can detect smoke in the air, etc. Gas sensitive gas. The concentration detection range of the module is light, the sensitivity is high, the driving circuit is relatively simple, and the stability of the module is very high, and the response to gas detection is very sensitive and fast. The IO port of the single-chip microcomputer of this system can tolerate the analog voltage input of 3.6V the most, but it cannot meet the direct input of the smoke sensor module, because the analog output of the module is up to 5V, so if the MQ2 sensor output is directly connected to the single-chip microcomputer pin, the chip will be damaged. To withstand irreversible damage, so this time in order to meet the design requirements, it is necessary to divide the output of MQ2 to reduce the analog output voltage 5V to the range that the microcontroller can tolerate. This time, a simple resistor divider design is adopted, that is, two A resistor with a resistance value of 3:2 is connected in series to the output pin as a voltage division processing unit. After the voltage is divided, the maximum voltage input to the analog input pin PA1 of the microcontroller is 3V. This method can meet the input requirements of analog design. .
insert image description here

GSM module

The GSMA6-B module is used this time. The module is small in size. Compared with the traditional SIM800A and other GSM modules, the size is more than doubled, and the power supply requirements of the module are reduced. The traditional SIM800A wireless communication module generally requires a power supply. The voltage is above 6V2A, and the module only needs 5V1A to complete the normal power supply requirements. The module supports basic communication functions such as sending SMS text messages, voice calls, and GPRS transmission. The standard AT command of the module uses a baud rate of 115200bps by default to communicate with the microcontroller. PB11 pin. When using the GSMA6 module, it should be noted that the serial port level of the module is 3.3V and cannot be directly connected to the serial port of the 5V microcontroller. When debugging through the USB serial port module, it is also necessary to use a USB debugging module that supports the 3.3V serial port level. Otherwise, the module communication may There will be problems.
insert image description here
insert image description here

face recognition module

This system uses the DEMO board based on the K210 module for face recognition. K210 is a module integrating RISC-V dual-core 64-bit CPU. This module has the highest computing power of 1TOPS and the power consumption is only 0.3W. The module has built-in AI Face recognition algorithm and model library, use serial port to output face recognition information, the module supports adjustable baud rate from 9600bps to 115200bps, the clock frequency of the module is 600MHZ, and inherits an 8MB flash SRAM, the module Support DVP output, the highest output is 60 frames. The built-in AI face recognition algorithm of the K210 module has undergone a lot of training and verification, and the recognition results are mature and reliable. According to the official statement, the recognition rate of the AI ​​face recognition model is greater than 99.9%, and it supports live detection, so it can effectively prevent the use of pictures to confuse Detect system problems. The K210 module has a built-in 500-8000 face feature library, uses a color binocular lens for face acquisition, and uses two infrared fill lights to maintain effective, highly accurate, and highly responsive detection results at night. The K210 module is connected with the serial port 1 of the main control microcontroller of the system, that is, the PA9 and PA10 interfaces for information communication and transmission. Due to the unreasonable design of the K210 DEMO board, the pin interface on the DEMO board cannot be used. This time, the serial port pin and the GND pin of the K210 module are led out through flying wires.
insert image description here
insert image description here

Voice Alarm Module

The voice playback module used in this system is JQ8400F, which supports MP3 and WAV format audio hardware decoding, and supports FAT file system, so it can be directly connected to the computer through the USB port like a U disk to manage audio files such as import and export. The module supports a variety of control modes such as single-line serial mode, asynchronous serial communication mode and parallel IO control mode. The module supports volume adjustment, and the volume is divided into 1-30 levels for volume adjustment.
insert image description here

resource usage

insert image description here

source program

main program

/*******************************************************************************

\* 文件名称:基于STM32单片机的家庭防火防盗系统的设计

\* 实验目的:1.

\* 2.

\* 程序说明:完整程序Q:277 227 2579;@: itworkstation@ hotmail.com

\* 日期版本:本项目分享关键细节,熟悉使用单片机的可做参考代码。完整讲解+源代码工程可联系获取,可定制。

*******************************************************************************/
#ifndef __main_h
#define __main_h

#include "stm32f10x.h"
#include<string.h>
#include<stdio.h>
#include "Def_config.h"
#include "GPIOLIKE51.h"

#include "delay.h"
#include "led.h"


#include "bsp_i2c_gpio.h"
#include "bsp_i2c_OLED.h"


#include "proc.h"


#endif 




/*******************************************************************************  

*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "main.h"  
#include "beep.h"
#include "RELAY.h"
#include "dht11.h"
#include "bsp_adc.h"
#include "usart1.h" 
#include "usart2.h" 
#include "usart3.h" 
#include "HLK210.h"
#include "JQ_8400.h" 
#include "bsp_timer4.h"  
#include "key.h" 
#include "gsmA6.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
STRUCT_NVICPriority NVICPriority_Structure;

u8 state01[2][12]={
    
    
"OFF",
"ON"	
};
u8 PersonNum01[3][15]={
    
    
"      unmanned",
"Illegal person",
"        master",
};
/**
  * @说明     主函数
  * @参数     None 
  * @返回值   None
  */
int main(void)
{
    
    
	int GSMA6_ret = 0;
	
	NVICPriority_Structure.Usart1 = 2;
	NVICPriority_Structure.Usart2 = 3;
	NVICPriority_Structure.Usart3 = 1;
	NVICPriority_Structure.Tim4 = 4;
	Proc_ParamInit();
	
	
	LED_Init();
	BEEP_Init();
	RELAY_Init();
	
	OLED_Init();
	LCD_Display();
	
	USART2_Init();
	JQ8400_Init();
	JQ8400_6x00SendCmd(SELECTE_PLAY,1); //选择指定曲目播放	
	
	if(DHT11_Init() == 0)
	{
    
    
		OLED_Showx8_y16(0,3,(unsigned char*)" 温湿度模块正常 ");				//测试8*16字符 		
	}
	else
	{
    
    	
		OLED_Showx8_y16(0,3,(unsigned char*)" 温湿度模块异常 ");				//测试8*16字符 	
		JQ8400_6x00SendCmd(SELECTE_PLAY,2); //选择指定曲目播放		
	}
	USART3_Init();
	Delay_ms(2000);	
	if(GSMA6_Init() != 1)
	{
    
    
		OLED_Showx8_y16(0,3,(unsigned char*)" GSMA6模块异常 ");				//测试8*16字符 	
		JQ8400_6x00SendCmd(SELECTE_PLAY,3); //选择指定曲目播放		
	}
	else{
    
    
		OLED_Showx8_y16(0,3,(unsigned char*)" GSMA6模块正常 ");				//测试8*16字符 		
	}
	Delay_ms(2000);	
	LCD_Menu = LCD_SHOWMESSAGE; //正常界面
	LCD_Display();
	
	ADC1_Init();
	
	USART1_Init();
	HLK210_CheckFaceID();
		
	Key_Init();
	TIM4_Init();
	
	JQ8400_6x00SendCmd(SELECTE_PLAY,4); //选择指定曲目播放		

	while(1){
    
    		
		
		Proc_Warning();
		Proc_Key();
		Proc_DHT11();
		Proc_MQ2();		 
		Proc_CVHK210();	
		
		if(TIM4_FlagStatus.Flag_1000MS == TRUE)
		{
    
    
			TIM4_FlagStatus.Flag_1000MS = FALSE;
			LED_Control(1,REVERSE);
			
			if(HLK210_Data.NowMode == CHECKFACEID)
			{
    
    
				HLK210_Data.TimeCount  ++;
				if(HLK210_Data.isGetData == FALSE && HLK210_Data.TimeCount>2)
				{
    
    
					LCD_Show.personNum = 0;
					LCD_Display();
					HLK210_Data.TimeCount = 0;
					
//					HLK210_Data.IllegalPersonWarn=FALSE;
//					HLK210_Data.IllegalPersonTime=0;
				}
				if(LCD_Show.personNum == 1 && LCD_Show.warningState==1)
				{
    
    
					JQ8400_6x00SendCmd(SELECTE_PLAY,5); //选择指定曲目播放
					
					HLK210_Data.IllegalPersonTime++;
					if(HLK210_Data.IllegalPersonTime>2)
					{
    
    
						HLK210_Data.IllegalPersonTime=3;
						if(HLK210_Data.IllegalPersonWarn==FALSE)
						{
    
    
							HLK210_Data.IllegalPersonWarn = TRUE;	
							GSMA6_text_message((char *)GSMA6_Data.Send_PhoneNum,
						(char *)"There is a stranger breaking in, please pay attention!");
						}												
					}
				}
			}						
			LCD_Display();
		}
		GSMA6_ret = GSMA6_ReadMessageTest();
		if(GSMA6_ret == TEXT_CMD_CHECK) //查看
		{
    
    
			memset(GSMA6_Data.TestMessage, 0, GSMA6_TextLEN);
			sprintf(GSMA6_Data.TestMessage,"T:%d,H:%d,MQ2:%d,FaceNum:%s,WaringState:%s;CMD:check,WarnOn,WarnOff,RelayOn,RelayOff",
			LCD_Show.tempe,LCD_Show.humi,LCD_Show.Mq2,PersonNum01[LCD_Show.personNum],state01[LCD_Show.warningState]);

			GSMA6_text_message((char *)GSMA6_Data.Send_PhoneNum,(char *)GSMA6_Data.TestMessage);
		}
		else  if(GSMA6_ret == TEXT_CMD_WaringOn)   //部署监测报警
		{
    
    
			LCD_Show.warningState = 1;
			GSMA6_text_message((char *)GSMA6_Data.Send_PhoneNum,(char *)"Alarm mode turn on!");
		}
		else  if(GSMA6_ret == TEXT_CMD_WaringOff)   //解除监测报警
		{
    
    
			LCD_Show.warningState = 0;
			GSMA6_text_message((char *)GSMA6_Data.Send_PhoneNum,(char *)"Alarm mode cancelled!");
		}
		else  if(GSMA6_ret == TEXT_CMD_RelayOn)   
		{
    
    
			LCD_Show.is_relayHandOpen = TRUE;
			GSMA6_text_message((char *)GSMA6_Data.Send_PhoneNum,(char *)"Home power on!");
		}
		else  if(GSMA6_ret == TEXT_CMD_RelayOff)   
		{
    
    
			LCD_Show.is_relayHandOpen = FALSE;
			GSMA6_text_message((char *)GSMA6_Data.Send_PhoneNum,(char *)"Home power off!");
		}
		else{
    
    }
	}     
}



processing logic

#ifndef __proc_h
#define __proc_h

#include "main.h"

#define LCD_BUFFMAX 21

typedef enum
{
    
    
	LCD_DEFAULT,
	LCD_SHOWMESSAGE,
	LCD_SETTH,
	LCD_SETRH,
	LCD_SETPH,
	LCD_SETCV,
	LCD_SETCV02,
	LCD_MENUEND,
	LCD_SETCVMESSAGE,
	LCD_SETCV02MESSAGE,
	LCD_SETCV02MESSAGEOK,
	LCD_GSMSHOWMESSAGE,
//	LCD_MENUEND
}LCD_ENUM;
typedef struct {
    
    
	u8 tempe;
		u8 humi;
	u16 Mq2;
	u8 personNum;
	u8 warningState;
  u8 setTH;
	u8 setRH;
	u16 setMq2H;
	u8 setHostPersonNum;
	u8 setGuestPersonNum;
	ENUM_JUDGE is_relayHandOpen;
	ENUM_JUDGE is_HK210StorgeFaceSuccess;
	
	ENUM_JUDGE is_DHT11_TempeWarn;
	ENUM_JUDGE is_DHT11_HumiWarn;
	ENUM_JUDGE is_Mq2_Warn;
	u8 StorgeFaceId;
	float test;
}LCD_SHOW_MENU;
extern LCD_SHOW_MENU LCD_Show;
extern LCD_ENUM LCD_Menu;
extern char LCD_Buff[LCD_BUFFMAX];

void Proc_ParamInit(void);
void Proc_Warning(void);

void LCD_Display(void);

void Proc_DHT11(void);
void Proc_MQ2(void);
void Proc_CVHK210(void);


void Proc_Key(void);

#endif 




#include "proc.h"
#include "dht11.h"
#include "bsp_adc.h"
#include "RELAY.h"
#include "HLK210.h"
#include "key.h"
#include "bsp_timer4.h"  
#include "gsmA6.h"
#include "BEEP.h"
#include "JQ_8400.h" 

void Proc_ParamInit(void)
{
    
    
	LCD_Show.setGuestPersonNum = 0;
	LCD_Show.setHostPersonNum = 0;
	LCD_Show.setMq2H = 1000;  
	LCD_Show.setRH = 60;
	LCD_Show.setTH = 30;
	LCD_Show.warningState = 1;  //报警模式 ,  
	LCD_Show.is_relayHandOpen = FALSE;
	LCD_Show.is_HK210StorgeFaceSuccess = FALSE;
	
	LCD_Show.is_DHT11_HumiWarn = FALSE;
	LCD_Show.is_DHT11_TempeWarn = FALSE;
	LCD_Show.is_Mq2_Warn = FALSE; 
}
char is_SendWaring = 0;
void Proc_Warning(void)
{
    
    
	if(LCD_Show.warningState == 1) //报警模式
	{
    
    
		if(LCD_Show.is_DHT11_TempeWarn || LCD_Show.is_DHT11_HumiWarn || LCD_Show.is_Mq2_Warn)
		{
    
    
			if(is_SendWaring==0)
			{
    
    
				is_SendWaring=1;
				GSMA6_text_message((char *)GSMA6_Data.Send_PhoneNum,
				(char *)"Abnormal sensor data is detected, please handle it in time!");
			}
					
			BEEP_Control(ON);
			LED_Control(2,ON);
		}
		else{
    
    
			is_SendWaring=0;
			
			BEEP_Control(OFF);
			LED_Control(2,OFF);
		}
		if(LCD_Show.is_Mq2_Warn || LCD_Show.is_relayHandOpen)
		{
    
    
			RELAY_Control(ON);
		}
		else
		{
    
    
			RELAY_Control(OFF);
		}
		if(LCD_Show.personNum == 1)
		{
    
    
		
		}
		else
		{
    
    
			HLK210_Data.IllegalPersonWarn=FALSE;	
			HLK210_Data.IllegalPersonTime=0;
		}
	}
	else{
    
     //非报警模式
		if(LCD_Show.is_relayHandOpen)
		{
    
    
			RELAY_Control(ON);
		}
		else{
    
    
			RELAY_Control(OFF);
		}
		
		LED_Control(2,OFF);
		BEEP_Control(OFF);
		
		is_SendWaring=0;
		
		HLK210_Data.IllegalPersonWarn=FALSE;	
		HLK210_Data.IllegalPersonTime=0;
	}
}
char is_TH_YuYin=0,RH_YuYin=0,is_YanWu_YuYin=0;
void Proc_DHT11(void)
{
    
    
	if(DHT11_Read_Data() != 0)
	{
    
    
		LCD_Show.humi = (u8)DHT11_Structure.Humi;
		LCD_Show.tempe = (u8)DHT11_Structure.Tempe;
		
		if(LCD_Show.tempe > LCD_Show.setTH)
		{
    
    
			LCD_Show.is_DHT11_TempeWarn = TRUE;
			if(is_TH_YuYin==0)
			{
    
    
				is_TH_YuYin=1;
				JQ8400_6x00SendCmd(SELECTE_PLAY,6); //选择指定曲目播放		
			}
		}
		else{
    
    
			LCD_Show.is_DHT11_TempeWarn = FALSE;
			is_TH_YuYin=0;
		}
		if(LCD_Show.humi > LCD_Show.setRH)
		{
    
    
			LCD_Show.is_DHT11_HumiWarn = TRUE;
			if(RH_YuYin==0)
			{
    
    
				RH_YuYin=1;
				JQ8400_6x00SendCmd(SELECTE_PLAY,7); //选择指定曲目播放		
			}
		}
		else{
    
    
			LCD_Show.is_DHT11_HumiWarn = FALSE;
			RH_YuYin=0;
		}
	}
}
void Proc_MQ2(void)
{
    
    
//	LCD_Show.test= (float)(ADCConvertedValue[0] * 3.3 / 4096);  //130 - 3100  1-5000ppm
	LCD_Show.test= ADCConvertedValue[0];  //130 - 3100  1-5000ppm
	if(LCD_Show.test<250)
	{
    
    
		LCD_Show.test = 251;
	}
	LCD_Show.Mq2 = (u16)((LCD_Show.test - 250)*1.67);
	if(LCD_Show.Mq2 > LCD_Show.setMq2H)
	{
    
    
		LCD_Show.is_Mq2_Warn = TRUE;
		if(is_YanWu_YuYin==0)
		{
    
    
			is_YanWu_YuYin=1;
			JQ8400_6x00SendCmd(SELECTE_PLAY,8); //选择指定曲目播放		
		}
	}
	else
	{
    
    
		LCD_Show.is_Mq2_Warn = FALSE;
		is_YanWu_YuYin=0;
	}
}
void Proc_CVHK210(void)
{
    
    
	if(HLK210_Data.isGetData == TRUE && HLK210_Data.NowMode == CHECKFACEID)
	{
    
    
		HLK210_Data.isGetData = FALSE;
		HLK210_Data.TimeCount = 0;
//		for(i=0;i<HLK210_Data.CmdDataLen;i++)
//		{
    
    
//			USART3_SendByte(HLK210_Data.HLK210_Buffer[i]);
//		}
		if(HLK210_Data.HLK210_Buffer[6]==0x02 && HLK210_Data.HLK210_Buffer[7]==0x0D && HLK210_Data.HLK210_Buffer[19]==0X00) 
		{
    
    
			LCD_Show.personNum = 2;
		}
		if(HLK210_Data.HLK210_Buffer[6]==0x02 && HLK210_Data.HLK210_Buffer[7]==0x0D && HLK210_Data.HLK210_Buffer[19]!=0X00) 
		{
    
    
			LCD_Show.personNum = 1;
		}
		LCD_Display();
	}
}

void Proc_Key2Add(u8 menuNow);
void Proc_Key3Dec(u8 menuNow);
void Proc_Key(void)
{
    
    
	u8 keyValue = 0xff;
	keyValue = Key_Scan();
	if(keyValue != 0xff)
	{
    
    
		switch(keyValue)
		{
    
    
			case 1:
				LCD_Menu++;
				if(LCD_Menu >= LCD_MENUEND)
				{
    
    
					LCD_Menu = LCD_SHOWMESSAGE;				
				}						
				break;
			case 2:
				Proc_Key2Add(LCD_Menu);
				break;
			case 3:
				Proc_Key3Dec(LCD_Menu);
				break;
			default:break;
		}
		LCD_Display();
	}
}
void Proc_Key2Add(u8 menuNow)
{
    
    
	switch(menuNow)
	{
    
    
		case LCD_SHOWMESSAGE:
			if(LCD_Show.is_relayHandOpen == TRUE)
			{
    
    				
				LCD_Show.is_relayHandOpen=FALSE;
				JQ8400_6x00SendCmd(SELECTE_PLAY,12); //选择指定曲目播放		
			}	
			else
			{
    
    
				LCD_Show.is_relayHandOpen=TRUE;
				JQ8400_6x00SendCmd(SELECTE_PLAY,11); //选择指定曲目播放		
			}			
			break;
		case LCD_SETTH:
			LCD_Show.setTH ++;
			if(LCD_Show.setTH>99)
				LCD_Show.setTH=99;
			break;
		case LCD_SETRH:
			LCD_Show.setRH ++;
			if(LCD_Show.setRH>99)
				LCD_Show.setRH=99;
			break;
		case LCD_SETPH:
			LCD_Show.setMq2H +=50;
			if(LCD_Show.setMq2H>5000)
				LCD_Show.setMq2H=5000;
			break;
		case LCD_SETCV:
			LCD_Show.is_HK210StorgeFaceSuccess = FALSE;
			LCD_Menu = LCD_SETCVMESSAGE;			
			LCD_Display();	
			HLK210_InputFaceID();
			while(LCD_Menu == LCD_SETCVMESSAGE)
			{
    
    
				if(HLK210_Data.isGetData)
				{
    
    
					HLK210_Data.isGetData = FALSE;
					if(HLK210_Data.HLK210_Buffer[18]!=0x00) //未识别成功
					{
    
    
						
					}
					else{
    
    
						LCD_Show.StorgeFaceId = HLK210_Data.HLK210_Buffer[17]; //获得人脸ID
						LCD_Show.is_HK210StorgeFaceSuccess = TRUE;
						LCD_Display();	
						Delay_ms(3000);  //延时显示信息后结束提示。	
						LCD_Show.is_HK210StorgeFaceSuccess = FALSE;
						HLK210_CheckFaceID();
						LCD_Menu = LCD_SETCV;
						LCD_Display();	
					}
				}							
			}			
			break;
		case LCD_SETCV02:
			LCD_Menu = LCD_SETCV02MESSAGE;
			LCD_Display();		
			break;
		case LCD_SETCV02MESSAGE:		
			while(LCD_Menu == LCD_SETCV02MESSAGE)
			{
    
    
				HLK210_DeleteAllFaceID();
				if(HLK210_Data.isGetData)
				{
    
    
					HLK210_Data.isGetData = FALSE;
					if(HLK210_Data.HLK210_Buffer[15]!=0x00) //未删除成功
					{
    
    
						Delay_ms(2000); 
					}
					else{
    
    
						LCD_Menu = LCD_SETCV02MESSAGEOK;
						LCD_Display();			
						Delay_ms(3000);  //延时显示信息后结束提示。						
						HLK210_CheckFaceID();
						LCD_Menu = LCD_SETCV;
						LCD_Display();	
					}
				}						
			}		
			break;
		default:
			break;
	}
}
void Proc_Key3Dec(u8 menuNow)
{
    
    
	switch(menuNow)
	{
    
    
		case LCD_SHOWMESSAGE:
			if(LCD_Show.warningState!=0)
			{
    
    
				LCD_Show.warningState = 0;			
				JQ8400_6x00SendCmd(SELECTE_PLAY,10); //选择指定曲目播放		
			}
			else
			{
    
    
				LCD_Show.warningState = 1;
				JQ8400_6x00SendCmd(SELECTE_PLAY,9); //选择指定曲目播放		
			}
			break;
		case LCD_SETTH:
			LCD_Show.setTH--;
			if(LCD_Show.setTH<1)
				LCD_Show.setTH=1;
			break;
		case LCD_SETRH:
			LCD_Show.setRH--;
			if(LCD_Show.setRH<1)
				LCD_Show.setRH=1;
			break;
		case LCD_SETPH:
			LCD_Show.setMq2H-=50;
			if(LCD_Show.setMq2H<50)
				LCD_Show.setMq2H=50;
			break;
		case LCD_SETCV:
			LCD_Menu = LCD_SETCV02;
			LCD_Display();
			break;
		case LCD_SETCV02:
			LCD_Menu = LCD_SETCV;
			LCD_Display();
			break;
		case LCD_SETCV02MESSAGE:
			LCD_Menu = LCD_SETCV02;
			LCD_Display();
			break;
		case LCD_GSMSHOWMESSAGE:
			GSMA6_text_message((char *)GSMA6_Data.Send_PhoneNum,(char *)"Alarm mode cancelled!");
			break;
		default:
			break;
	}
}



LCD_ENUM LCD_Menu = LCD_DEFAULT,LCD_Menu_Last = LCD_MENUEND;  
LCD_SHOW_MENU LCD_Show;
char LCD_Buff[LCD_BUFFMAX];
u8 state[2][12]={
    
    
"关闭",
"开启"	
};
u8 PersonNum[3][15]={
    
    
"  无人",
"非法者",
"  主人",
};
void LCD_Display(void)
{
    
    
	if(LCD_Menu_Last != LCD_Menu)
	{
    
    
		LCD_Menu_Last = LCD_Menu;
		OLED_CLS();//清屏
	} 
	if(LCD_Menu == LCD_DEFAULT) 
	{
    
    
		memset(LCD_Buff,'0',LCD_BUFFMAX); 
		sprintf(LCD_Buff,(char *)"欢迎使用家庭防火");
		OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);				//测试8*16字符
		
		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"  防盗报警系统  ");
		OLED_Showx8_y16(0,1,(unsigned char*)LCD_Buff);				

		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"制作人:   **  ");
		OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);				//测试8*16字符
	}
	else if(LCD_Menu == LCD_SHOWMESSAGE)
	{
    
    
		memset(LCD_Buff,'0',LCD_BUFFMAX); 
		sprintf(LCD_Buff,(char *)"温度%d℃ 湿度%d%%",LCD_Show.tempe,LCD_Show.humi);
		OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);				//测试8*16字符									

		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"可燃气体:%4dPPM",LCD_Show.Mq2);
		OLED_Showx8_y16(0,1,(unsigned char*)LCD_Buff);				//测试8*16字符
		
		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"人脸识别: %s",PersonNum[LCD_Show.personNum]);
		OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);				//测试8*16字符
		
		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"报警状态:  %s",state[LCD_Show.warningState]);
		OLED_Showx8_y16(0,3,(unsigned char*)LCD_Buff);	
	}
	else if(LCD_Menu == LCD_SETTH)
	{
    
    
		memset(LCD_Buff,'0',LCD_BUFFMAX); 
		sprintf(LCD_Buff,(char *)"  设定温度阈值  ");
		OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);				//测试8*16字符									

		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"TH:   %2d℃    ",LCD_Show.setTH);
		OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);				//测试8*16字符
	}
	else if(LCD_Menu == LCD_SETRH)
	{
    
    
		memset(LCD_Buff,'0',LCD_BUFFMAX); 
		sprintf(LCD_Buff,(char *)"  设定湿度阈值  ");
		OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);				//测试8*16字符									

		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"RH:   %2d%%    ",LCD_Show.setRH);
		OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);				//测试8*16字符
	}
	else if(LCD_Menu == LCD_SETPH)
	{
    
    
		memset(LCD_Buff,'0',LCD_BUFFMAX); 
		sprintf(LCD_Buff,(char *)"设定可燃气体阈值");
		OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);				//测试8*16字符									

		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"PH:   %3dPPM ",LCD_Show.setMq2H);
		OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);				//测试8*16字符
	}
	else if(LCD_Menu == LCD_SETCV)
	{
    
    
		memset(LCD_Buff,'0',LCD_BUFFMAX); 
		sprintf(LCD_Buff,(char *)"设定人脸识别数据");
		OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);				//测试8*16字符									

		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"  → 录入人脸 ");
		OLED_Showx8_y16(0,1,(unsigned char*)LCD_Buff);				//测试8*16字符
		
		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"     删除人脸 ");
		OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);				//测试8*16字符
		
		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"设置  确定  切换");
		OLED_Showx8_y16(0,3,(unsigned char*)LCD_Buff);				//测试8*16字符
	}
	else if(LCD_Menu == LCD_SETCV02)
	{
    
    
		memset(LCD_Buff,'0',LCD_BUFFMAX); 
		sprintf(LCD_Buff,(char *)"设定人脸识别数据");
		OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);				//测试8*16字符									

		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"     录入人脸 ");
		OLED_Showx8_y16(0,1,(unsigned char*)LCD_Buff);				//测试8*16字符
		
		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"  → 删除人脸 ");
		OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);				//测试8*16字符
		
		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"设置  确定  切换");
		OLED_Showx8_y16(0,3,(unsigned char*)LCD_Buff);				//测试8*16字符
	}
	else if(LCD_Menu == LCD_SETCVMESSAGE)
	{
    
    
		memset(LCD_Buff,'0',LCD_BUFFMAX); 
		sprintf(LCD_Buff,(char *)"请正对摄像头");
		OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);				//测试8*16字符									

		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"正在识别...  ");
		OLED_Showx8_y16(0,1,(unsigned char*)LCD_Buff);				//测试8*16字符
		
		if(LCD_Show.is_HK210StorgeFaceSuccess)
		{
    
    
			memset(LCD_Buff,'0',LCD_BUFFMAX);
			sprintf(LCD_Buff,(char *)"识别成功,ID为:%2d",LCD_Show.StorgeFaceId);
			OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);				//测试8*16字符
			
		
			memset(LCD_Buff,'0',LCD_BUFFMAX);
			sprintf(LCD_Buff,(char *)"人脸信息已存储 ");
			OLED_Showx8_y16(0,3,(unsigned char*)LCD_Buff);				//测试8*16字符
		}		
	}
	else if(LCD_Menu == LCD_SETCV02MESSAGE)
	{
    
    
		memset(LCD_Buff,'0',LCD_BUFFMAX); 
		sprintf(LCD_Buff,(char *)"设定人脸识别数据");
		OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);				//测试8*16字符									

		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"选择清空人脸信息");
		OLED_Showx8_y16(0,1,(unsigned char*)LCD_Buff);				//测试8*16字符
		
		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"   确定选择?  ");
		OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);				//测试8*16字符
			
		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"设置  确定  返回");
		OLED_Showx8_y16(0,3,(unsigned char*)LCD_Buff);				//测试8*16字符
	}
	else if(LCD_Menu == LCD_SETCV02MESSAGEOK)
	{
    
    
		memset(LCD_Buff,'0',LCD_BUFFMAX); 
		sprintf(LCD_Buff,(char *)"设定人脸识别数据");
		OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);				//测试8*16字符									

		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"人脸信息已清空");
		OLED_Showx8_y16(0,1,(unsigned char*)LCD_Buff);				//测试8*16字符
		
	
		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"  请重新录入 ");
		OLED_Showx8_y16(0,3,(unsigned char*)LCD_Buff);				//测试8*16字符
	}
	else if(LCD_Menu == LCD_GSMSHOWMESSAGE)
	{
    
    
		memset(LCD_Buff,'0',LCD_BUFFMAX); 
		sprintf(LCD_Buff,(char *)"GSMA6 - B Test");
		OLED_Showx8_y16(0,0,(unsigned char*)LCD_Buff);				//测试8*16字符									

		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"P:%s ",GSMA6_Data.Rec_PhoneNum);
		OLED_Showx8_y16(0,1,(unsigned char*)LCD_Buff);				//测试8*16字符
		
	
		memset(LCD_Buff,'0',LCD_BUFFMAX);
		sprintf(LCD_Buff,(char *)"M:%s ",GSMA6_Data.TestMessage);
		OLED_Showx8_y16(0,3,(unsigned char*)LCD_Buff);				//测试8*16字符
	}
	else{
    
    }
} 



AD/DA conversion to detect smoke concentration

#ifndef __bsp_adc_h
#define __bsp_adc_h

#include "stm32f10x.h"

#define ADC_BUFFMAX           1
#define ADC1_DR_Address    ((uint32_t)0x4001244C)
extern __IO uint16_t ADCConvertedValue[ADC_BUFFMAX];


void ADC1_Init(void);



#endif 




#include "bsp_adc.h"
// 可燃气体MQ5 PA1  - ADC12_IN1     
__IO uint16_t ADCConvertedValue[ADC_BUFFMAX];
static void ADC1_RCC_Configuration(void)
{
    
    
  RCC_ADCCLKConfig(RCC_PCLK2_Div4); 
  /* Enable peripheral clocks ------------------------------------------------*/
  /* Enable DMA1 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  /* Enable ADC1 and GPIOA clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
}
static void ADC1_GPIO_Configuration(void)
{
    
    
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure PA.00 (ADC Channel) as analog input -------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}
static void ADC1_Configuration(void)
{
    
    
  ADC_InitTypeDef ADC_InitStructure;
  DMA_InitTypeDef DMA_InitStructure;
  /* DMA1 channel1 configuration ----------------------------------------------*/
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = ADC_BUFFMAX;             //1
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;   //     Disable
//  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;   //      Enable
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  
  /* Enable DMA1 channel1 */
  DMA_Cmd(DMA1_Channel1, ENABLE);
  
  /* ADC1 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
//  ADC_InitStructure.ADC_ScanConvMode = ENABLE;              // 如果一次需要对多个通道进行转换,这位就必须设置为ENABLE
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;             
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = ADC_BUFFMAX;      // -----
  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channel1 configuration */ 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);    // 

  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);
  
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);

  /* Enable ADC1 reset calibration register */   
  ADC_ResetCalibration(ADC1);
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));
     
  /* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
void ADC1_Init(void)
{
    
    
  ADC1_RCC_Configuration();
  ADC1_GPIO_Configuration();
  ADC1_Configuration();
}





GSM-A6 module driver

#ifndef __GSMA6_H__
#define __GSMA6_H__

#include "stm32f10x.h"
#include "Def_config.h"

#include "usart3.h" 
#define   GSMA6_USART_SendData       USART3_SendByte
#define   GSMA6_USART_SendStr        USART3_SendString

#define GSMA6_USART_REC_LEN 200
#define GSMA6_REC_PHONENUMLEN 20
#define GSMA6_REC_TextNumLEN    4
#define GSMA6_TextLEN    100
typedef struct
{
    
    
	char Rec_Buff[GSMA6_USART_REC_LEN];
	
	char Rec_PhoneNum[GSMA6_REC_PHONENUMLEN];
	char Rec_TextNum[GSMA6_REC_TextNumLEN];
	
	char TestMessage[GSMA6_TextLEN];
	
	char Send_PhoneNum[GSMA6_REC_PHONENUMLEN];
	
	ENUM_JUDGE isGetData;		//是否获取到数据
	ENUM_JUDGE isParseData;	//是否解析完成
	ENUM_JUDGE isUsefull;		//信息是否有效

}_GSMA6_Data;
extern _GSMA6_Data GSMA6_Data;

#define AT_DELET_SMS_ERROR          -1
#define COMMUNITE_ERROR       11 
#define NO_SIM_CARD_ERROR     22
#define SIM_CARD_NO_REG_ERROR 33
#define CALL_ERROR			  44
#define AT_CPMS_ERROR		  55
#define AT_CMGF_ERROR		  66
#define AT_CSCS_ERROR		  77
#define AT_CMGS_ERROR         88
#define END_char_ERROR		  99
#define NO_SMS_LEN_ERROR      100
#define AT_CSMP_ERROR         111
#define AT_CNMI_ERROR         101


/*************	本地常量声明	**************/
#define TEXT_CMD_READ_ERROR  0
#define TEXT_CMD_READ_NOSM  1

#define TEXT_CMD_SMCHECKError  2
#define TEXT_CMD_NOTCMD  3


#define TEXT_CMD_CHECK    4  //查看指令
#define TEXT_CMD_WaringOn   5  //部署监测报警指令
#define TEXT_CMD_WaringOff   6  //解除监测报警指令
#define TEXT_CMD_RelayOn   7  
#define TEXT_CMD_RelayOff   8

/*************	本地变量声明	**************/
//串口发送回车换行
/*注:指令是以\r结束(十六进制就是0X0D)的,以前是以\r\n(0X0D,0X0A)结束的,
串口助手上就是勾上发送回车换行,程序上就是发送0X0D,
但是现在发送串口助手调试勾上,大部分指令是没有问题的,
但是发送短信或者TCP数据的时候,勾上的时候,就会多发送一个回车也就是\n,
发送PDU短信的时候勾上就会发送视频。*/
//#define GSMA6_UART_SendLR() USART_SendData(USART3,0X0D);USART_SendData(USART3,0X0A)
#define GSMA6_UART_SendLR() GSMA6_USART_SendData(0x0D)


/*************	本地函数声明	**************/
int GSMA6_text_message(char *phoneNum,char *content);
void GSMA6_Receive_Byte(char res);
int GSMA6_ReadMessageTest(void);
int GSMA6_Find(char *a);

int GSMA6_Init(void);

#endif



#include "gsmA6.h"
#include <stdio.h>
#include <string.h>
#include "delay.h"
//#include "proc.h"
//#include "usart2.h" 



char GSMA6_RECEICV_BUFFER[GSMA6_USART_REC_LEN];
uint16_t GSMA6_point = 0;
void GSMA6_Receive_Byte(char res)
{
    
    
	/*发现个很严重的问题,这模块回馈信息不知道怎么回事有0x00,就算我清空用的是255,数组接收中依然有0x00,而这个又代表字符串结束符,导致strstr直接使用时strlen判定字符串长度变成了0*/
	if(res != 0x00)
	{
    
    
		GSMA6_RECEICV_BUFFER[GSMA6_point++] = res;
		if(GSMA6_point>6)
		{
    
    
			GSMA6_Data.isGetData = TRUE;
		}
		if(GSMA6_point>=GSMA6_USART_REC_LEN)
		{
    
    
			GSMA6_point=0;
		}
	}
}
void GSMA6_ClearDate(void)
{
    
    
	uint16_t k=0;
	for(k=0;k<GSMA6_USART_REC_LEN;k++)      //将缓存内容清零
	{
    
    
		GSMA6_RECEICV_BUFFER[k] = 0;
	}

	GSMA6_point=0;	
//	GSMA6_Data.isGetData = FALSE;
}

int GSMA6_Find(char *a)
{
    
     
	if(strstr(GSMA6_RECEICV_BUFFER,a)!=NULL) 
	{
    
    
		return 1;
	}	
	else
	{
    
    
		return 0;
	}	
}

/**********************************
发送命令
**********************************/
void GSMA6_Send_Command(char *s)
{
    
    
	GSMA6_ClearDate(); 
	while(*s != '\0')//检测字符串结束符
	{
    
    
		GSMA6_USART_SendData(*s++);//发送当前字符
	}
	GSMA6_UART_SendLR();
//	GSMA6_ClearDate();		 
}
void GSMA6_Send_Command_END(char *s)
{
    
    
	GSMA6_ClearDate(); 
	while(*s != '\0')//检测字符串结束符
	{
    
    
		GSMA6_USART_SendData(*s++);//发送当前字符
	}
}
int GSMA6_Send_AT_Command(char *b,char *a,char wait_time,u16 interval_time)         
{
    
    
	char i;

	GSMA6_ClearDate(); // 清除缓存数据
	i = 0;
	while(i < wait_time)                    
	{
    
    
		GSMA6_Send_Command(b);
		Delay_ms(interval_time);
		if(GSMA6_Find(a))            //查找需要应答的字符
		{
    
    
			return 1;
		}
		i++;
	}	
	return 0;
}
int GSMA6_Send_AT_Command_END(char *b,char *a,char wait_time,u16 interval_time)         
{
    
    
	char i;

	GSMA6_ClearDate(); 
	i = 0;
	while(i < wait_time)                    
	{
    
    
		GSMA6_Send_Command_END(b);
		Delay_ms(interval_time);
		if(GSMA6_Find(a))            //查找需要应答的字符
		{
    
    
			return 1;
		}
		i++;
	}	
	return 0;
}
/***************************************************************
查询状态。
****************************************************************/
int GSMA6_Check_Status(void)
{
    
    
	int ret;
	
	ret = GSMA6_Send_AT_Command((char *)"AT",(char *)"OK",3,500);//测试通信是否成功
	if(ret == 0)
	{
    
    
		return COMMUNITE_ERROR;
	}
	
	ret = GSMA6_Send_AT_Command((char *)"AT+CPIN?",(char *)"READY",2,1000);//查询卡是否插上
	if(ret == 0)
	{
    
    
		return NO_SIM_CARD_ERROR;
	}
	
	ret = GSMA6_Send_AT_Command((char *)"AT+CREG?",(char *)"+CREG: 1,1",3,1000);//查询卡是否注册到网络
	if(ret == 0)
	{
    
    
		return SIM_CARD_NO_REG_ERROR;
	}
	ret = GSMA6_Send_AT_Command((char *)"AT+CMGD=1,4",(char *)"OK",3,3000);//删除所有短信   新增
	if(ret == 0)
	{
    
    
		return AT_DELET_SMS_ERROR;
	}
	return 1;
}

int GSMA6_Config_Format(void)
{
    
    
	int ret;
	
	//设置存储位置
	ret = GSMA6_Send_AT_Command((char *)"AT+CPMS=\"SM\",\"ME\",\"SM\"",(char *)"OK",3,1000);
	if(ret == 0)
	{
    
    
		return AT_CPMS_ERROR;
	}
	
	ret = GSMA6_Send_AT_Command((char *)"AT+CMGF=1",(char *)"OK",3,1000);//配置为TEXT模式
	if(ret == 0)
	{
    
    
		return AT_CMGF_ERROR;
	}
	
	ret = GSMA6_Send_AT_Command((char *)"AT+CSCS=\"GSM\"",(char *)"OK",3,1000);//设置字符格式
	if(ret == 0)
	{
    
    
		return AT_CSCS_ERROR;
	}
	
	ret = GSMA6_Send_AT_Command((char *)"AT+CNMI=2,1",(char *)"OK",3,1000);//设置收到短信提示
	if(ret == 0)
	{
    
    
		return AT_CNMI_ERROR;
	}
	return 1;
}
/***************************************************************
发送短信给对应手机号
****************************************************************/
char AT_Cmd_GMGS[30];
int GSMA6_text_message(char *phoneNum,char *content)
{
    
    
	int ret;
	char end_char[2];  	//信息结束字符串
	end_char[0] = 0x1A;//结束字符
	end_char[1] = '\0';	

	memset(AT_Cmd_GMGS,'\0',30);			 //先清空,再 对AT_CMGR 赋值   
	strcpy((char *)AT_Cmd_GMGS,"AT+CMGS=\"");  // strcpy从目标地址0 开始拷贝
	strcat((char *)AT_Cmd_GMGS,(char *)phoneNum);	   //strcat从目标地址字符串后开始连接
	strcat((char *)AT_Cmd_GMGS,"\"\r");
	
	//设置存储位置
	ret = GSMA6_Config_Format();
	if(ret != 1)
	{
    
    
		return ret;
	}
	ret = GSMA6_Send_AT_Command(AT_Cmd_GMGS,(char *)">",3,1000);//输入收信人的电话号码	  set_phone_num
	if(ret == 0)
	{
    
    
    return AT_CMGS_ERROR;
	}	
	GSMA6_USART_SendStr(content); //此函数发送短信内容 不加回车换行
	ret = GSMA6_Send_AT_Command_END(end_char,(char *)"OK",1,4000);//发送结束符,等待返回ok,等待5S发一次,因为短信成功发送的状态时间比较长
	if(ret == 0)
	{
    
    
		return END_char_ERROR;
	}	
	return 1;
}
int GSMA6_ReadMessageTest(void)
{
    
    
	char *subString;
	char *subStringNext;
	char AT_CMGR[15];
	if(GSMA6_Data.isGetData  == TRUE)
	{
    
    
		Delay_ms(100);
		GSMA6_Data.isGetData = FALSE;
		
		if(GSMA6_Find("+CMTI"))
		{
    
    								
			memset(GSMA6_Data.Rec_Buff, 0, GSMA6_USART_REC_LEN);
			memcpy(GSMA6_Data.Rec_Buff, GSMA6_RECEICV_BUFFER, GSMA6_point);
//			USART2_SendString(GSMA6_Data.Rec_Buff);		
			
			if((subString = strstr(GSMA6_Data.Rec_Buff, "SM\",")) != NULL)
			{
    
    
				subString+=4;
				if ((subStringNext = strstr(subString, "\r")) != NULL)
				{
    
    
					memset(GSMA6_Data.Rec_TextNum, 0, GSMA6_REC_TextNumLEN);
					memcpy(GSMA6_Data.Rec_TextNum, subString, subStringNext - subString);
					
//					memset(LCD_Buff,'0',LCD_BUFFMAX);
//					sprintf(LCD_Buff,(char *)"P:%d L:%s ",GSMA6_point,GSMA6_Data.Rec_TextNum); 
//					OLED_Showx8_y16(0,2,(unsigned char*)LCD_Buff);				//测试8*16字符
					
					memset(AT_CMGR,'\0',15);
					strcpy(AT_CMGR,"AT+CMGR=");
					strcat(AT_CMGR,GSMA6_Data.Rec_TextNum);
					
					if(GSMA6_Send_AT_Command((char *)AT_CMGR,(char *)"OK",3,1000))
					{
    
    
						Delay_ms(100);
						
//						USART2_SendString(GSMA6_RECEICV_BUFFER);		
						
						if((subString = strstr(GSMA6_RECEICV_BUFFER, "+86")) != NULL)
						{
    
    
							subString+=3;
							if((subStringNext = strstr(subString, "\"")) != NULL)
							{
    
    
								memset(GSMA6_Data.Rec_PhoneNum, 0, GSMA6_REC_PHONENUMLEN);
								memcpy(GSMA6_Data.Rec_PhoneNum, subString, subStringNext - subString); //获取手机号
							}
						}
						else{
    
    
							GSMA6_ClearDate();
							return TEXT_CMD_SMCHECKError;
						}
						if(GSMA6_Find("check"))  //指令
						{
    
    
							GSMA6_ClearDate();
							return TEXT_CMD_CHECK;
						}
						else if(GSMA6_Find("WarnOn"))  //指令
						{
    
    
							GSMA6_ClearDate();
							return TEXT_CMD_WaringOn;
						}
						else if(GSMA6_Find("WarnOff"))  //指令
						{
    
    
							GSMA6_ClearDate();
							return TEXT_CMD_WaringOff;
						}
						else if(GSMA6_Find("RelayOn"))  //指令
						{
    
    
							GSMA6_ClearDate();
							return TEXT_CMD_RelayOn;
						}
						else if(GSMA6_Find("RelayOff"))  //指令
						{
    
    
							GSMA6_ClearDate();
							return TEXT_CMD_RelayOff;
						}
						else
						{
    
    
							GSMA6_ClearDate();
							return TEXT_CMD_NOTCMD;
						}
					}
					else
					{
    
    
						GSMA6_ClearDate();
						return TEXT_CMD_SMCHECKError;
					}
				}
			}
			GSMA6_ClearDate();
			return TEXT_CMD_READ_NOSM;
		}
		else  //必须要有
		{
    
    
			GSMA6_ClearDate();
		}
	}
	return TEXT_CMD_READ_ERROR;
}
_GSMA6_Data GSMA6_Data;
int GSMA6_Init(void)
{
    
    
	int ret = 0;
	
	GSMA6_ClearDate();
	
	ret = GSMA6_Check_Status();
	if(ret != 1)
	{
    
    
		return ret;
	}
	ret = GSMA6_Config_Format();
	if(ret != 1)
	{
    
    
		return ret;
	}
	GSMA6_ClearDate();
	
	GSMA6_Data.isGetData = FALSE;
	memset(GSMA6_Data.Rec_Buff, 0, GSMA6_REC_PHONENUMLEN);
	memset(GSMA6_Data.Rec_PhoneNum, 0, GSMA6_REC_PHONENUMLEN);
	memset(GSMA6_Data.Rec_TextNum, 0, GSMA6_REC_TextNumLEN);
	
	memset(GSMA6_Data.TestMessage, 0, GSMA6_TextLEN);
	
	memset(GSMA6_Data.Send_PhoneNum, 0, GSMA6_REC_PHONENUMLEN);
	strcpy(GSMA6_Data.Send_PhoneNum,"15805468097");   //设定指定发送人的手机号

	return 1;
}



















HLK210 face recognition module driver

#ifndef __HLK210_h
#define __HLK210_h

#include "stm32f10x.h"
#include <string.h>
#include <stdio.h>
#include "Def_config.h"
#include "delay.h"

//
#include "usart1.h" 
#define HLK210_SendByte  USART1_SendByte  


//模组返回的消息类型说明
#define HLK210_CTROK           0x00 // 操作成功
#define HLK210_CHECKEDFACE     0x01 // 检测到人脸
#define HLK210_LIVINGBODY      0x02 // 活体通过
#define HLK210_STRERROR        0x03 // 存储操作错误
#define HLK210_STRFULL         0x04 // 人脸库已满
#define HLK210_CHECKOUT        0x05 // 检测超时
#define HLK210_IDERROR         0x06 // 人脸编号ID不存在
#define HLK210_FORMERROR       0x07 // 参数或格式错误
#define HLK210_OTHERERROR      0x08 // 其他错误
#define HLK210_RAMERROR        0x09 // RAM中暂缓的模板不存在
#define HLK210_HAVEDFACE       0x0A // 此人脸已注册

typedef enum {
    
    NORMAL,INPUTFACEID,CHECKFACEID,DELETEFACEID}ENUM_HLK210;

#define HLK210_NORMALANSWERLEN   18  //命令发出应答长度
#define HLK210_FACEANSWERLEN     21  //人脸录入时反馈字节长度
#define HLK210_RECOANSWERLEN     22  //人类识别时反馈字节长度

#define HLK210_USART_REC_LEN 50
typedef struct SaveData 
{
    
    
	char HLK210_Buffer[HLK210_USART_REC_LEN];
	char CmdDataLen;		
	ENUM_JUDGE isGetData;		//是否获取到GPS数据
	ENUM_JUDGE isParseData;	//是否解析完成
	ENUM_JUDGE isUsefull;		//信息是否有效
	ENUM_HLK210 NowMode;
	
	ENUM_JUDGE IllegalPersonWarn;
	char IllegalPersonTime;
	
	char TimeCount;
} _HLK210_Data;
extern _HLK210_Data HLK210_Data;

void HLK210_ClearDate(void);
void HLK210_Receive_Byte(u8 res);
void HLK210_InputFaceID(void);
void HLK210_CheckFaceID(void);
void HLK210_DeleteAllFaceID(void);

#endif 








#include "HLK210.h"

#include "bsp_i2c_gpio.h"
#include "bsp_i2c_OLED.h"
#include "delay.h"
//#include "usart3.h" 

unsigned char HLK210_FaceStorageCmd[18] ={
    
    0x5A, 0x2C, 0x00, 0x00, 0x00, 0x12, 0x03, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xE5};//人脸录入指令
unsigned char HLK210_FaceCheckCmd[18] = {
    
    0x5A, 0x2C, 0x00, 0x00, 0x00, 0x12, 0x02, 0x0C, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xA8};  //人脸识别指令
unsigned char HLK210_AllFaceDeleteCmd[18] = {
    
    0x5A, 0x2C, 0x00, 0x00, 0x00, 0x12, 0x0D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x1E};  //人脸清空指令
unsigned char HLK210_LightOn[18] = {
    
    0x5A, 0x2C, 0x00, 0x00, 0x00, 0x12, 0x12, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xAA, 0x15};  //开补光灯指令

unsigned char HLK210_RECEICV_BUFFER[HLK210_USART_REC_LEN];

_HLK210_Data HLK210_Data;
u8 HLK210_point=0;
void HLK210_Receive_Byte(u8 res)
{
    
    
	HLK210_RECEICV_BUFFER[HLK210_point++] = res;
	if(HLK210_point>1 && (HLK210_RECEICV_BUFFER[HLK210_point-2]==0x5a && HLK210_RECEICV_BUFFER[HLK210_point-1]==0x2c))
	{
    
    
		HLK210_RECEICV_BUFFER[0]=HLK210_RECEICV_BUFFER[HLK210_point-2];
		HLK210_RECEICV_BUFFER[1]=HLK210_RECEICV_BUFFER[HLK210_point-1];
		HLK210_point=2;
	}
	if(HLK210_point>=HLK210_Data.CmdDataLen)
	{
    
    
		HLK210_Data.isGetData = TRUE;
		memset(HLK210_Data.HLK210_Buffer, 0, HLK210_USART_REC_LEN);      //清空
		memcpy(HLK210_Data.HLK210_Buffer,HLK210_RECEICV_BUFFER, HLK210_point); 	//保存数据
	}
	if(HLK210_point>HLK210_USART_REC_LEN)
	{
    
    
		HLK210_point=HLK210_USART_REC_LEN-1;
	}
}
void HLK210_ClearDate(void)
{
    
    
	memset(HLK210_RECEICV_BUFFER, 0, HLK210_USART_REC_LEN);      //清空
	HLK210_point=0;
	
	HLK210_Data.CmdDataLen = HLK210_NORMALANSWERLEN;
	memset(HLK210_Data.HLK210_Buffer, 0, HLK210_USART_REC_LEN);      //清空
	HLK210_Data.isGetData = FALSE;
	HLK210_Data.isParseData = FALSE;
	HLK210_Data.isUsefull =  FALSE;
	HLK210_Data.NowMode = NORMAL;
	HLK210_Data.TimeCount = 0;
	HLK210_Data.IllegalPersonTime=0;
	HLK210_Data.IllegalPersonWarn = FALSE; 
}

void HLK210_Send_Cmd(u8 *cmd)
{
    
    
	u8 i=0;
	for(i=0;i<18;i++)
	{
    
    
		HLK210_SendByte(*cmd++);  // == *(cmd++) 取cmd所指单元的值,cmd指向下一单元,即cmd自加1
	}
}
void HLK210_InputFaceID(void)
{
    
    

	HLK210_ClearDate();
	HLK210_Data.CmdDataLen = HLK210_NORMALANSWERLEN;
	HLK210_Data.NowMode = INPUTFACEID;
	
	HLK210_Send_Cmd(HLK210_LightOn);  //开补光灯
	while(HLK210_Data.isGetData == FALSE); //等待接收完应答数据
	HLK210_Data.isGetData = FALSE;
//	for(i=0;i<HLK210_Data.CmdDataLen;i++)
//	{
    
    
//		USART3_SendByte(HLK210_Data.HLK210_Buffer[i]);
//	}
	
	HLK210_Send_Cmd(HLK210_FaceStorageCmd); //存人脸指令
	while(HLK210_Data.isGetData == FALSE); //等待接收完应答数据
	HLK210_Data.isGetData = FALSE;
//	for(i=0;i<HLK210_Data.CmdDataLen;i++)
//	{
    
    
//		USART3_SendByte(HLK210_Data.HLK210_Buffer[i]);
//	}
	HLK210_Data.CmdDataLen = HLK210_FACEANSWERLEN;
//	while(HLK210_Data.isGetData == FALSE); //等待接收完应答数据
//	HLK210_Data.isGetData = FALSE;
//	for(i=0;i<HLK210_Data.CmdDataLen;i++)
//	{
    
    
//		USART3_SendByte(HLK210_Data.HLK210_Buffer[i]);
//	}
}
void HLK210_CheckFaceID(void)
{
    
    

	HLK210_ClearDate();
	HLK210_Data.CmdDataLen = HLK210_NORMALANSWERLEN;
	HLK210_Data.NowMode = CHECKFACEID;
	
	HLK210_Send_Cmd(HLK210_LightOn);  //开补光灯
	while(HLK210_Data.isGetData == FALSE); //等待接收完应答数据
	HLK210_Data.isGetData = FALSE;
//	for(i=0;i<HLK210_Data.CmdDataLen;i++)
//	{
    
    
//		USART3_SendByte(HLK210_Data.HLK210_Buffer[i]);
//	}
	
	HLK210_Send_Cmd(HLK210_FaceCheckCmd);
	while(HLK210_Data.isGetData == FALSE); //等待接收完应答数据
	HLK210_Data.isGetData = FALSE;
//	for(i=0;i<HLK210_Data.CmdDataLen;i++)
//	{
    
    
//		USART3_SendByte(HLK210_Data.HLK210_Buffer[i]);
//	}
	HLK210_Data.CmdDataLen = HLK210_RECOANSWERLEN;
}
void HLK210_DeleteAllFaceID(void)
{
    
    

	HLK210_ClearDate();
	HLK210_Data.CmdDataLen = HLK210_NORMALANSWERLEN;
	HLK210_Data.NowMode = DELETEFACEID;
	
	HLK210_Send_Cmd(HLK210_AllFaceDeleteCmd);
	while(HLK210_Data.isGetData == FALSE); //等待接收完应答数据
//	HLK210_Data.isGetData = FALSE;
//	for(i=0;i<HLK210_Data.CmdDataLen;i++)
//	{
    
    
//		USART3_SendByte(HLK210_Data.HLK210_Buffer[i]);
//	}
}


















DHT11 module driver

#ifndef __DHT11_H
#define __DHT11_H

#include "stm32f10x.h"

#define GPIO_PORT_DHT11	  GPIOB		                /* GPIO端口 */
#define RCC_DHT11_PORT 	  RCC_APB2Periph_GPIOB		/* GPIO端口时钟 */
#define DHT11_DQ_PIN      GPIO_Pin_13		          /* 连接到DQ数据线的GPIO */


typedef struct {
    
    
   uint8_t Humi;
   uint8_t Tempe;
}STRUCT_DHT11;
extern STRUCT_DHT11 DHT11_Structure;

u8 DHT11_Init (void );
unsigned int DHT11_Read_Data(void);



#endif

#include "dht11.h"
#include "delay.h"
void mode_input(void )
{
    
    
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = DHT11_DQ_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIO_PORT_DHT11, &GPIO_InitStructure);
}
void mode_output(void )
{
    
    
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = DHT11_DQ_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIO_PORT_DHT11, &GPIO_InitStructure);
}
STRUCT_DHT11 DHT11_Structure;
unsigned int DHT11_Read_Data(void)
{
    
    
  int i;
  long long val;
  int timeout;

  GPIO_ResetBits(GPIO_PORT_DHT11, DHT11_DQ_PIN);
  Delay_ms(18);  //pulldown  for 18ms
  GPIO_SetBits(GPIO_PORT_DHT11, DHT11_DQ_PIN);
  Delay_us(20);	//pullup for 30us

  mode_input();

  //等待DHT11拉高,80us
  timeout = 0;
  while( (! GPIO_ReadInputDataBit(GPIO_PORT_DHT11, DHT11_DQ_PIN)) && (timeout < 80) )  {
    
     timeout++;Delay_us(1); }//wait HIGH

  //等待DHT11拉低,80us
  timeout = 0;
  while( GPIO_ReadInputDataBit (GPIO_PORT_DHT11, DHT11_DQ_PIN) && (timeout < 80) )  {
    
     timeout++;Delay_us(1); } //wait LOW

#define CHECK_TIME 28

  for(i=0;i<40;i++)
  {
    
    
	timeout = 0;
	while( (! GPIO_ReadInputDataBit(GPIO_PORT_DHT11, DHT11_DQ_PIN)) && (timeout < 80) )  {
    
     timeout++;Delay_us(1); }//wait HIGH

	Delay_us(CHECK_TIME);
	if ( GPIO_ReadInputDataBit (GPIO_PORT_DHT11, DHT11_DQ_PIN) )
	{
    
    
	  val=(val<<1)+1;
	} else {
    
    
	  val<<=1;
	}

	timeout = 0;
	while( GPIO_ReadInputDataBit (GPIO_PORT_DHT11, DHT11_DQ_PIN) && (timeout < 80) ) {
    
     timeout++;Delay_us(1); }	 //wait LOW
  }

  mode_output();
  GPIO_SetBits(GPIO_PORT_DHT11, DHT11_DQ_PIN);
  DHT11_Structure.Humi = (u8)(val>>32);
	DHT11_Structure.Tempe = (u8)(val>>16);
  if (((val>>32)+(val>>24)+(val>>16)+(val>>8) -val ) & 0xff  ) return 0;
    else return 1; 
}
u8 DHT11_Init(void )
{
    
    
  int  timeout = 0;
  GPIO_InitTypeDef GPIO_InitStructure;
  /* Enable  clock */
  RCC_APB2PeriphClockCmd(RCC_DHT11_PORT , ENABLE);
  
  /* Configure Ports */
  GPIO_InitStructure.GPIO_Pin = DHT11_DQ_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIO_PORT_DHT11, &GPIO_InitStructure);

  GPIO_ResetBits(GPIO_PORT_DHT11, DHT11_DQ_PIN);
  Delay_ms(18);  //pulldown  for 18ms
  GPIO_SetBits(GPIO_PORT_DHT11, DHT11_DQ_PIN);
  Delay_us(20);	//pullup for 30us
  mode_input();

  //等待DHT11拉高,80us
  timeout = 0;
  while( (! GPIO_ReadInputDataBit(GPIO_PORT_DHT11, DHT11_DQ_PIN)) && (timeout < 80) )  {
    
     timeout++;Delay_us(1); }//wait HIGH

  if(timeout >= 80)
    return 1;

  //等待DHT11拉低,80us
  timeout = 0;
  while( GPIO_ReadInputDataBit (GPIO_PORT_DHT11, DHT11_DQ_PIN) && (timeout < 80) )  {
    
     timeout++;Delay_us(1); } //wait LOW
  if(timeout >= 80)
    return 1;
  return 0;
}


JQ8400 voice module driver

#ifndef __JQ_8400_H__
#define __JQ_8400_H__

#include "main.h"
#include "usart2.h" 

#define JQ8400_GPIO_PORT    	GPIOA			                /* GPIO端口 */
#define JQ8400_GPIO_CLK 	    RCC_APB2Periph_GPIOA		  /* GPIO端口时钟 */
#define JQ8400_GPIO_PIN		    GPIO_Pin_11	 //播放时为高电平,其余时间为低电平

#define JQ8400_BUSY  GPIO_ReadInputDataBit(JQ8400_GPIO_PORT,JQ8400_GPIO_PIN)//读取判忙状态,是否正在播放


#define  JQ8400_SendData   USART2_SendByte

#define SET_CMD    0X00	    //仅设置模式,并不送入数据指令

#define PLAY_ON    0X02	    //	播放
#define PLAY_SUSPEND   0X03			//暂停
#define PLAY_OFF   0X04			 //停止
#define PLAY_LAST   0X05		  //上一曲
#define PLAY_NEXT   0X06		  //下一曲


#define SELECTE_PLAY 0X07       //指定曲目  后面要加曲目号

#define SET_SOUND  0X13	   //音量设置	   1-30级,要送16进制即: 0-0X1E
#define SOUND_ADD  0X14	   //音量加
#define SOUND_DEC  0X15		  //音量减

#define SELECTE_MODE  0X18  //模式
#define MODE_DQXH  0X01  //单曲循环
#define MODE_DQTZ  0X02  //单曲停止
#define MODE_SJBF  0X03  //随机播放

//sbit JQ8400_BUSY=P2^4;	//播放时为高电平,其余时间为低电平
void JQ8400_Init(void);

void JQ8400_6x00SendCmd(u8 cmd,u16 dat);//发送命令

#endif




#include "JQ_8400.h" 
#include "delay.h"
/*****在线语音合成工具http://tools.bugscaner.com/tts/ ********/
void JQ8400_Init(void)
{
    
    
	GPIO_InitTypeDef GPIO_InitStructure;  /*定义一个GPIO_InitTypeDef类型的结构体*/
	
 	RCC_APB2PeriphClockCmd(JQ8400_GPIO_CLK,ENABLE);//使能PORTB时钟

	GPIO_InitStructure.GPIO_Pin  = JQ8400_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;    //设置成上拉输入
 	GPIO_Init(JQ8400_GPIO_PORT, &GPIO_InitStructure);         //初始化

	JQ8400_6x00SendCmd(SET_SOUND,0X1E);  //设置默认播放声音
	JQ8400_6x00SendCmd(SELECTE_MODE,MODE_DQTZ);  //设置默认播放模式,单曲停止
//	JQ8400_6x00SendCmd(SELECTE_PLAY,1); //选择指定曲目播放
}
void JQ8400_SendMultiByte(u8 *Buff, u8 Len )
{
    
    
    u8 i;
    for ( i = 0 ; i < Len ; i++ )
    {
    
    
        JQ8400_SendData( Buff[i] );        
    }
}
u8 JQ8400_SumCheck ( u8 *Str, u8 len ) //和校验
{
    
    
	u16 xorsum = 0;
	u8 i;
	for ( i = 0; i < len; i++ )
	{
    
    
		xorsum = xorsum + ( *Str++ );
	}
	return ( ( u8 ) ( xorsum & 0x00ff ) );
}
void JQ8400_6x00SendCmd(u8 cmd,u16 dat)//发送命令
{
    
    
	 u8 pbuff[6];
	 u8 xorsum;
	 pbuff[0]=0xAA;
	 pbuff[1]=cmd;
	 if(cmd==SET_SOUND)
	 {
    
    
	 	pbuff[2]=0x01;
		pbuff[3]=(u8)dat;
		xorsum=JQ8400_SumCheck(pbuff,4);
		pbuff[4]=xorsum;
		JQ8400_SendMultiByte(pbuff,5); 	
	 }
	 else if(cmd==SELECTE_PLAY)
	 {
    
    
	 	pbuff[2]=0x02;
		pbuff[3]=(u8)(dat>>16)&0xff;
		pbuff[4]=(u8)(dat&0xff);
		xorsum=JQ8400_SumCheck(pbuff,5);
		pbuff[5]=xorsum;
		JQ8400_SendMultiByte(pbuff,6); 	
	 }
	 else if(cmd==SELECTE_MODE)
	 {
    
    
	 	pbuff[2]=0x01;
		pbuff[3]=(u8)dat;
		xorsum=JQ8400_SumCheck(pbuff,4);
		pbuff[4]=xorsum;
		JQ8400_SendMultiByte(pbuff,5); 	
	 }
	 else
	 {
    
     
	 	pbuff[2]=0x00;
		xorsum=JQ8400_SumCheck(pbuff,3);
		pbuff[3]=xorsum;
		JQ8400_SendMultiByte(pbuff,4); 	
	 }					 	
	Delay_ms(500);	 
	while(JQ8400_BUSY);	//播放时为高电平,其余时间为低电平	
} 
  




Serial driver

Since the serial port drivers are similar, you only need to change the GPIO corresponding to different serial ports and the communication format, so put a template.

#ifndef __usart1_h
#define __usart1_h

#include "stm32f10x.h"


void USART1_Init(void);
void USART1_SendByte(u8 date);




#endif 





#include "usart1.h" 
#include <stdio.h>
#include <string.h>

#include "proc.h"
#include "HLK210.h"

//reference:     ..\2.STM32固件库v3.5\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\USART\Interrupt
//TXD1 - PA9      RXD1 - PA10
static void USART1_NVIC_Configuration(void)
{
    
    
  NVIC_InitTypeDef NVIC_InitStructure;
  /* Enable the USART1 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVICPriority_Structure.Usart1;   
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);
}
static void USART1_RCC_Configuration(void)
{
    
       
  /* Enable GPIO clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  /* Enable USARTy Clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);  //在使用串口复用功能的时候,要开启相应的功能时钟USART ,且此时钟源在APB1上!!!  
}
static void USART1_GPIO_Configuration(void)
{
    
    
  GPIO_InitTypeDef GPIO_InitStructure;
  /* Configure USARTy Rx as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Configure USARTy Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

static void USART1_Configuration(void)
{
    
    
  USART_InitTypeDef USART_InitStructure;
	/* USARTy and USARTz configuration ------------------------------------------------------*/
  /* USARTy and USARTz configured as follow:
        - BaudRate = 9600 baud  
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
  */
	USART_InitStructure.USART_BaudRate = 115200;//波特率设置;
	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_InitStructure.USART_Mode = USART_Mode_Rx;	//收模式
	
    USART_Init(USART1, &USART_InitStructure); //初始化串口
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
    USART_Cmd(USART1, ENABLE);                    //使能串口 	
}
void USART1_Init(void)
{
    
    
   USART1_NVIC_Configuration();
   USART1_RCC_Configuration();
   USART1_GPIO_Configuration();
   USART1_Configuration();
	
	HLK210_ClearDate();
}
void USART1_SendByte(u8 date)
{
    
    
    USART_SendData(USART1,date); 
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); 
}

void USART1_IRQHandler(void)                	//串口1中断服务程序
{
    
    
	u8 Res=0;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 
	{
    
    
		Res =USART_ReceiveData(USART1);//(USART1->DR);	//读取接收到的数据
//		Proc_ShowTest(Res);
		HLK210_Receive_Byte(Res); 
	}
}







Guess you like

Origin blog.csdn.net/qq_20467929/article/details/126143086