主要是编写传感器的驱动、配合OLED,每遮挡对射红外传感器,OLED屏幕的计数就加一。
首先新建.c文件和.h文件,命名为CountSensor
国际惯例,.c文件内要包含stm32.h头文件,然后编写?CountSensor_Init()函数,即传感器计数函数。一步一步来,首先函数体内部要首先使能时钟,没有时钟不工作。总体的函数内部需要配置的东西有:
1.配置RCC时钟;
2.配置GPIO,端口配置为输入模式;
3.配置AFIO,选择GPIO链接到EXTI;
4.配置EXTI,选择边沿触发方式和触发的响应方式;
5.配置NVIC,配置中断优先级。
void CountSensor_Init(void)
//第一步配置RCC,没有时钟不行;第二部配置GPIO,配置端口为输入模式;第三步配置AFIO,选择我们的GPIO链接到EXTI
//第四步配置EXTI,选择边沿的触发方式,和触发的响应方式。第五步,配置NVIC,配置中断优先级。
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启GPIOB的时钟,因为传感器引脚接在了GPIOB
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//AFIO时钟开启
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//EXTI输入,推荐配置是浮空,上拉或下拉
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
首先定义GPIO参数结构体,GPIO_Mode选择上拉输入;使能第14号管脚,因为传感器的信号端接的是GPIOB_14;速度万年50MHz,最后调用GPIO_Init(GPIOB,&结构体名称)初始化GPIO14.
AFIO外设没有专门分配的库函数,它的库函数跟GPIO在同一个文件中,在GPIO.h中的第350行开始。使用函数:GPIO_EXTILineConfig()函数,选择指定的GPIO引脚链接EXTI,如果不知道这个函数怎么用,右键然后看它的定义,如下图所示:
函数上面的注释中@brief是函数功能简介,这里说的很清楚,本函数是选择GPIO管脚链接到EXTI?。函数的第一个参数是GPIO源,就是GPIO哪个片区,是GPIOA还是GPIOB;第二个参数是具体的管脚号。我们这个例子是用GPIOB_14,所以函数的调用形式为:
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
首先要用结构体定义EXTI参数,具体包括EXTI_Line,配置中断线;EXTI_LineCmd,开启或关闭中断;EXTI_Mode,选择中断模式;EXTI_Trigger,触发方式选择。总体就是这么几个地方要配置,最后调用EXTI_Init()函数,初始化EXTI。总体代码如下:
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line14;//配置中断线
EXTI_InitStructure.EXTI_LineCmd=ENABLE;//开启或关闭中断
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//定义中断模式
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;//触发中断方式,是下降沿还是上升沿
EXTI_Init(&EXTI_InitStructure);
回顾上一篇讲的内容,NVIC的作用是管理中断,更具体地是管理中断的优先级。
首先要配置优先级分组,优先级分组有6种方式,这里选择第二种。
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//优先集分组定义
接下来使用结构体定义NVIC的参数,包括?NVIC_IRQChannel:指定NVIC通道;NVIC_IRQChannelCmd使能或关闭;NVIC_IRQChannelPreemptionPriority抢占优先级;NVIC_IRQChannelSubPriority响应优先级。最后调用NVIC_Init函数初始化NVIC。
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;//指定NVIC的通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
函数的返回值是变量CountSensor_Count
uint16_t CountSensor_Get(void)
{
return CountSensor_Count;
}
EXTI_GerITStatus()函数的返回值是SET或者RESET,如果是SET代表管脚14触发,因此CountSensor+1
void EXTI15_10_IRQHandler(void)//中断函数的名字
{
if (EXTI_GetITStatus(EXTI_Line14) == SET)
{
CountSensor_Count++;
EXTI_ClearITPendingBit(EXTI_Line14);
}
}
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"
int main(void)
{
OLED_Init();
CountSensor_Init();
OLED_ShowString(1,1, "Count:");
while(1)
{
OLED_ShowNum(1,7,CountSensor_Get(),5);
}
}