前言
之前写过一篇关于人体红外的简单使用,是用库函数进行开发,并且没有添加任何中断,最近在比赛课题中使用到低功耗设置,便是使用人体红外进行设置,已在arduino芯片上实现,现在迁移至stm32上,使用库函数很便利,但是使用寄存器能加深对stm32的理解,更接近底层,并且语句更加简练。
一、所用人体红外传感器模块
?因为作品的设定是小体积、低功耗,所以在元器件的选择上,我们选择了这款,体积小,且其静态电流也是很低,为20um。
那么作用到现实的产品中,我们需要考虑的是其感应范围,而买来的人体红外一般都是具有很高的灵敏度,所以我们需要改变他的贴片电阻来改变其感应距离,而其感应距离是0-3.5m,我们希望最后能得到的距离是20cm。
二、人体红外与寄存器——GPIO设置(STM32F103系列)
1.开启对应的外设时钟(设置PC3端口)
根据时钟树或查阅手册可以看到,PC在GAPB2总线上,所以我们查看RCC_APB2ENR寄存器。
其中位4就是关于PC端口的时钟开关
?对应代码如下
RCC->APB2ENR |= 1<<4; //第4位置1,开启PC端口对应时钟
2.设置端口模式
我们先查找对应的寄存器,发现PC3的设置在端口配置低寄存器(对应y=0-7)中?
端口的数值是由传感器进行采集的,所以我们需要设置其端口模式为浮空输入,我们选择的是PC3口,所以需要设置CNF3=01,代码如下:
需要设置CRL对应位为输入,再设置输入模式
RCC->APB2ENR |= 1<<4; //第4位置1,开启PC端口对应时钟
GPIOC->CRL &= ~(3<<(3*4)); //设置输入模式
GPIOC->CRL &= ~(1<<15); //第15位置0
GPIOC->CRL |= 1<<14; //第14位置1,设置浮空输入模式
3.查看端口状态
通过查看寄存器GPIOC_IDR的位3来查看对应的输入值。
?通过读取寄存器位3上的数据来判断是否是高电平还是低电平从而判断是否有人。
if((GPIOC->IDR & (1<<3)) != 0) //输出高电平
{
return 1;
}
else return 0;
三、人体红外与寄存器——外部中断(STM32F103系列)
接下来就是关于PC3设置为中断触发,根据手册,其设置方法如下:
1、使能IO时钟,配置IO口模式为输入
这个在上面已经实现,不再重复
2、开启AFIO时钟,设置IO口语中断线的映射关系
首先找到对应的时钟寄存器,可以看到AFIO时钟在第0位
?根据手册我们可以看到只需要置0位为1即可开启对应的时钟寄存器
RCC->APB2ENR |= 1<<0;
可以看到想要开启对应端口的位置,需要对EXTIx进行对应的设置,我们要设置的是PC3口,因此,需要设置EXTI3[3:0]对应为0010。
?我们使用以下语句:
AFIO->EXTICR[3] |= 1<<1; //EXTI[2]第2位置1
AFIO->EXTICR[3] &= 0<<0;
AFIO->EXTICR[3] &= 0<<2;
AFIO->EXTICR[3] &= 0<<3;
3、使能中断
?首先,我们先开启3口上的中断请求。
EXTI->IMR |= 1<<3;
4、选择触发方式
因为我们使用的是人体红外,所以在检测到有人时,会从0跳变到1,因此我们需要设置其触发方式为上升沿触发,其寄存器如下:
EXTI->RTSR |= 1<<3;
5、配置中断分组(NVIC),并使能中断【配置失败】
NVIC_EnableIRQ(EXTI3_IRQn)
我的资料里面找不到NVIC配置的寄存器,所以只能使用库函数暂时代替了。
6、编写中断处理函数
先看一下挂起寄存器,当检测到中断发生时,PR3会置位1,我们检查该为,如果为1则执行中断处理函数,在处理完之后便将该位写1进行清除。
?编写函数如下,0x00008意思为低20位(20-31保留),对应为即第3位置1.
void EXTI3_IRQHandler(void)
{
if(EXTI->PR & 0x00008)
{
//delay_ms(10);
LED2=!LED2;
}
EXTI->PR = 0x00008;
}
Tip:因为找不到NVIC寄存器配置手册,所以在寄存器配置失败(原谅我看不懂英文版的),但是中断配置使用库函数配置是很简单的,建议使用库函数配置,等后续有看到其他资料再补上,除了中断配置外,其他代码均测试过,可以使用(包括中断处理函数)
|