裸机开发--光电开关、火焰传感器、人体红外传感器

一、光电开关

在这里插入图片描述

左侧有一个光敏三极管,当无遮挡物时,有光,三极管导通,电压减小,即电压比较器正输入减小,正输入电压小于负输入电压时,输出低电平,LD5的电路导通,LD5亮。
当有遮挡物时,无光,三极管截止,电压增大,电压比较器正输入电压大于负输入电压时,输出高电平,LD5电路截止,LD5灯灭。

注意:需要调节滑动变阻器R55,使负输入的电压值大于0.6且小于3.3,这样才能在有无遮挡物时输出不同的电平。

光电开关 --> PE15 --> EXTI15 --> 输入事件编号15 --> 选择上升沿检测 --> 中断号:159
在这里插入图片描述

二、火焰传感器

火焰传感器的原理是利用火焰产生的红外线对它非常敏感的特点,
当火焰亮度变大时,发出的红外线越多,火焰传感器管脚间的阻抗变小,
当火焰亮度变小时,发出的红外线越少,火焰传感器管脚间的阻抗变大。
在这里插入图片描述

当有火焰时,火焰传感器阻抗变小,分压变小(负输入那一点的电压与火焰传感器是并联,电压相等,因此火焰传感器分压变小,负输入的电压就减小),电压比较器负输入电压减小,正输入电压大于负输入电压,输出高电平,LD6熄灭
当没有火焰时,火焰传感器阻抗变大,分压变大,,电压比较器的负输入增大,正输入小于负输入电压,输出低电平,LD6亮

注:当没有火焰时,需要调节滑动变阻器R67, 让LD6指示灯亮。

火焰传感器 --> PF5 --> EXTI5 --> 输入事件编号5 --> 选择上升沿检测 --> 中断号:55

在这里插入图片描述

三、人体红外传感器

在这里插入图片描述
如图可知,需要找网络标号RELOUT的引脚。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

人体红外传感器 --> PF12 --> EXTI12 --> 输入事件编号12 --> 选择上升沿检测 --> 中断号:108
在这里插入图片描述

四、代码实现

sentor.c

#include "../include/sentor.h"

//光电开关 PE15
void sentor_light_gpio_init(){
    RCC_AHB4->gpioe_en=1;

    gpio_init_t gpioInit;
    gpioInit.mode = GPIO_MODE_INPUT;
    gpioInit.pupd = GPIO_PUPD_NONE;
    gpioInit.type = GPIO_TYPE_OUTPUT_PP;
    gpio_init(GPIOE,GPIO_PIN_15,&gpioInit);
}

//火焰传感器 PF5
void sentor_fire_gpio_init(){
    RCC_AHB4->gpiof_en=1;

    gpio_init_t gpioInit;
    gpioInit.mode = GPIO_MODE_INPUT;
    gpioInit.pupd = GPIO_PUPD_NONE;
    gpioInit.type = GPIO_TYPE_OUTPUT_PP;
    gpio_init(GPIOF,GPIO_PIN_5,&gpioInit);
}

//红外传感器 PF12
void sentor_red_gpio_init(){
    RCC_AHB4->gpiof_en=1;

    gpio_init_t gpioInit;
    gpioInit.mode = GPIO_MODE_INPUT;
    gpioInit.pupd = GPIO_PUPD_NONE;
    gpioInit.type = GPIO_TYPE_OUTPUT_PP;
    gpio_init(GPIOF,GPIO_PIN_12,&gpioInit);
}

gic.c

void gic_sentor_init(void){
    /***EXTI****/
    //GPIO引脚与EXTI关联
    EXTI->EXTICR4.GPIO3_7_11_15=PE;  //将EXTI7和PF7关联
    EXTI->EXTICR2.GPIO1_5_9_13=PF;
    EXTI->EXTICR4.GPIO0_4_8_12=PF;
    //配置上升沿触发
    EXTI->RTSR1.event15=1;
    EXTI->RTSR1.event5=1;
    EXTI->RTSR1.event12=1;    
    //使能EXTI
    EXTI->C1IMR1.event15=1;
    EXTI->C1IMR1.event5=1;
    EXTI->C1IMR1.event12=1;
    //使能GICD中断号
    GICD->ISENABLER[4] |= (0x1<<31);        //使能GICD中断号  159/32=4...31
    GICD->ISENABLER[1] |= (0x1<<23);        //55/32=1...23
    GICD->ISENABLER[3] |= (0x1<<12);        //108/32=3...12
    //设置优先级
    GICD->IPRIORITYR[39] &= ~(0xf<<27);
    GICD->IPRIORITYR[39] |= (0x5<<27);    //设置优先级   159/4=39...3
    GICD->IPRIORITYR[13] &= ~(0xf<<27);
    GICD->IPRIORITYR[13] |= (0x5<<27);    //设置优先级   55/4=13...3
    GICD->IPRIORITYR[27] &= ~(0xf<<3);
    GICD->IPRIORITYR[27] |= (0x5<<3);    //设置优先级   108/4=27...0
    //分配CPU
    GICD->ITARGETSR[39] &= ~(0x3<<24);
    GICD->ITARGETSR[39] |= (0x1<<24);  //设置中断给CPU0  159/4=39...3
    GICD->ITARGETSR[13] &= ~(0x3<<24);
    GICD->ITARGETSR[13] |= (0x1<<24); 
    GICD->ITARGETSR[27] &= ~(0x3<<0);
    GICD->ITARGETSR[27] |= (0x1<<0); 

    GICD->CTRL |= (0x1<<0);      //使能GICD组0
    //配置GICC
    GICC->PMR |= 0x1f<<3;         //31
    GICC->CTLR|= 0x1<<0;         //使能GICC
}

do_irq.c

void do_irq(void) 
{
    int irqnum=0;
    irqnum = GICC->IAR & 0x1ff;
    switch(irqnum){
        case 159:
            printf("sentor light!\n");
            EXTI->RPR1.event15=1;
            GICD->ICPENDR[4] |= (0x1<<31); //159/32=4...31
        break;
        case 55:
            printf("sentor fire~\n");
            EXTI->RPR1.event5=1;
            GICD->ICPENDR[1] |= (0x1<<23); //55/32=1...23
        break;
        case 108:
            printf("sentor human red!\n");
            EXTI->RPR1.event12=1;
            GICD->ICPENDR[3] |= (0x1<<12); //108/32=3...12
        break;
    }  
    GICC->EOIR = irqnum;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值