一:热释电红外传感器HC-SR505,在有人的时候会变为高,延时一段时间后变为低电平。同时在8s内触发不是很精确,所以可以通过一些操作延长每次高低电平检测的时间。
#include "stm32f10x.h" // Device header
//热释电红外传感器
uint8_t SR505_Flag;
void HC_SR505_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);//打开GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);//打开AFIO复用时钟
GPIO_InitTypeDef GPIO_InitStructure; //初始化GPIO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA , &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource7);//AFIO,将PA7口挂到复用通道7
EXTI_InitTypeDef EXTI_InitStruct; //初始化外部中断
EXTI_InitStruct.EXTI_Line = EXTI_Line7;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//中断触发模式
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿
EXTI_Init(&EXTI_InitStruct);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置NVIC(中断信号处理以及优先级)
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
}
uint8_t HC_SR505_GetFlag(void)
{
return SR505_Flag;//获取HC_SR505的值
}
void HC_SR505_CleanFlag(void)
{
SR505_Flag = 0;//清空HC505的值
}
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line7) == SET)//外部中断7号线的中断标志位
{
SR505_Flag = 1;
EXTI_ClearITPendingBit(EXTI_Line7);//清除标志位
}
}
二:: 光敏电阻传感器,有光照时为低电平,没光照时为低电平。接入DO口,可通过滑动变阻调节灵敏度。
#include "stm32f10x.h"
//光敏传感器
void Light_Senson_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //??A0~A7
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB , &GPIO_InitStructure);
}
uint8_t Light_Senson_GetFlag(void)
{
uint8_t Flag=0;
Flag = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12);
return Flag;
}
三:继电器,看触发方式,本文低电平导通。
#include "stm32f10x.h"
//继电器
void Relay_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA , &GPIO_InitStructure);
GPIO_ResetBits(GPIOA, GPIO_Pin_5);
}
void Relay_ON(void)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_5);
}
void Relay_OFF(void)
{
GPIO_SetBits(GPIOA, GPIO_Pin_5);
}
四:主函数的逻辑不是很难,当光敏值为1时(黑夜),热释电为1(检测有人)时,会触发if语句,进行四秒打开继电器,同时四秒的关闭延时继电器保证下一次检测的准度。(接线就按文件中的配置进行)
#include "stm32f10x.h"
#include "OLED.h"
#include "HC_SR505.h"
#include "Delay.h"
#include "Light_Senson.h"
#include "Relay.h"
uint8_t SR505_Flag1 , LightSenson_Flag;
int main(void)
{
OLED_Init();
HC_SR505_Init();
Light_Senson_Init();
Relay_Init();
OLED_ShowString(1,4, "Savage!");
OLED_ShowString(3,1, "SR505:");
OLED_ShowString(4,1, "Light:");
Delay_s(2);
while(1)
{
LightSenson_Flag = Light_Senson_GetFlag();//获取光敏传感器值
SR505_Flag1 = HC_SR505_GetFlag();//获取热释电红外传感器值
OLED_ShowNum(3,7,SR505_Flag1,1);//在OLED显示值
OLED_ShowNum(4,7,LightSenson_Flag,1);
if(LightSenson_Flag != 0 && HC_SR505_GetFlag() != 0)//当黑夜时候检测到人,执行if操作
{
Relay_OFF();//打开继电器
Delay_s(5);
Relay_ON();//关闭继电器
Delay_s(3);
SR505_Flag1 = 0;
HC_SR505_CleanFlag();
}
Delay_ms(50);
}
}
Savage--欢迎大家一起讨论指正