对射式红外传感器计次
代码:
#include "stm32f10x.h" // Device header
//声明一个名为CountSensor_Count的uint16_t类型的变量,用于保存计数传感器的计数值。
uint16_t CountSensor_Count;
//定义了一个名为CountSensor_Init的函数,用于初始化计数传感器。
void CountSensor_Init(void)
{
//使能GPIOB的时钟,使能AFIO(复用功能IO)的时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//定义一个名为GPIO_InitStructure的结构体,用于配置GPIO的初始化参数。
GPIO_InitTypeDef GPIO_InitStructure;
//设置GPIO引脚为输入模式,启用上拉电阻。
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//设置GPIO引脚为引脚14
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
//设置GPIO引脚的速度为50MHz。
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//使用上述配置初始化GPIOB引脚。
GPIO_Init(GPIOB, &GPIO_InitStructure);
//配置外部中断线路。
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
//定义一个名为EXTI_InitStructure的结构体,用于配置外部中断的初始化参数。
EXTI_InitTypeDef EXTI_InitStructure;
//配置外部中断线为引脚14。
EXTI_InitStructure.EXTI_Line = EXTI_Line14;
//使能外部中断线。
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
//配置外部中断为中断模式。
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
//配置外部中断触发方式为下降沿触发。
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
//使用上述配置初始化外部中断。
EXTI_Init(&EXTI_InitStructure);
//定义一个名为NVIC_InitStructure的结构体,用于配置中断向量表的初始化参数。
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//
NVIC_InitTypeDef NVIC_InitStructure;
//配置中断通道为EXTI15_10_IRQn。
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
//使能中断通道。
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//配置抢占优先级为1。
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
//配置子优先级为1。
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
}
uint16_t CountSensor_Get(void)
{
return CountSensor_Count;
}
void EXTI15_10_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line14) == SET)
{
/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
{
CountSensor_Count ++;
}
EXTI_ClearITPendingBit(EXTI_Line14);
}
}
STM32的中断类型:
-
外部中断:通过外部触发信号(如按键、传感器等)引发的中断。
-
定时器中断:定时器到达设定的时间或计数值时触发的中断。用于实现定时、计时等功能。
-
UART(串口)中断:当串口接收或发送数据时触发的中断。用于实现串口通信。
-
DMA(直接存储器访问)中断:当DMA传输完成时触发的中断。用于高速数据传输。
-
ADC(模数转换器)中断:当模数转换器完成一次模数转换时触发的中断。用于模拟信号采集。
-
I2C(I²C总线)中断:当I2C总线传输完成或出现错误时触发的中断。用于实现I2C设备之间的通信。
-
SPI(串行外设接口)中断:当SPI接口传输完成或出现错误时触发的中断。用于实现SPI设备之间的通信。
-
USB(通用串行总线)中断:与USB相关的中断,用于USB设备的连接和通信。
STM32单片机的GPIO模式配置:
对于WK_UP——配置下拉输入
KEY0,KEY1——配置上拉输入
-
输入浮空模式(GPIO_Mode_IN_FLOATING):
- 特点:GPIO口为输入模式,无上拉或下拉电阻,处于浮空状态。
- 应用场景:适用于外部传感器信号输入,如按键、开关、触摸传感器等。
-
输入上拉模式(GPIO_Mode_IPU,Input Pull-Up):
- 特点:GPIO口为输入模式,内部上拉电阻启用,连接到VDD(高电平)。
- 应用场景:适用于外部信号输入,如按键,信号线断开时保持高电平。
-
输入下拉模式(GPIO_Mode_IPD,Input Pull-Down):
- 特点:GPIO口为输入模式,内部下拉电阻启用,连接到地(低电平)。
- 应用场景:适用于外部信号输入,如按键,信号线断开时保持低电平。
-
模拟模式(GPIO_Mode_AIN,Analog Input):
- 特点:GPIO口为模拟输入模式,用于ADC模数转换输入。
- 应用场景:适用于模拟传感器信号采集,如温度传感器、光敏传感器等。
-
推挽输出模式(GPIO_Mode_Out_PP,Output Push-Pull):
- 特点:GPIO口为输出模式,推挽输出,可提供高电平和低电平输出。
- 应用场景:适用于驱动大多数外设和数字电路,如LED、继电器、电机驱动等。
-
开漏输出模式(GPIO_Mode_Out_OD,Output Open-Drain):
- 特点:GPIO口为输出模式,开漏输出,只能提供低电平输出,高电平需要外部上拉电阻。
- 应用场景:适用于需要多个输出端合并的场景,如I2C总线,多路开关控制等。
-
复用推挽输出模式(GPIO_Mode_AF_PP,Alternate Function Output Push-Pull):
- 特点:GPIO口为复用功能输出模式,可用于驱动某些外设的特殊功能。
- 应用场景:适用于复用功能模式下的外设控制,如串口、定时器等。
-
复用开漏输出模式(GPIO_Mode_AF_OD,Alternate Function Output Open-Drain):
- 特点:GPIO口为复用功能输出模式,开漏输出,只能提供低电平输出,高电平需要外部上拉电阻。
- 应用场景:适用于复用功能
注意"开漏输出模式"(GPIO_Mode_Out_OD)是一种高电平无驱动能力的模式。在这种模式下,GPIO口可以提供低电平输出,但无法主动提供高电平输出。
复用推挽输出模式和推挽输出模式的区别是什么?
主要的区别在于复用推挽输出模式可以将GPIO口用于复用功能输出,而推挽输出模式仅用于普通数字信号的输出。
在STM32单片机中,每个GPIO引脚都有多个功能。除了基本的输入和输出功能外,它们还可以用于连接到其他外设(如串口、定时器、SPI等)以实现特定的功能。
复用功能输出是指将GPIO口配置为某个特定外设功能的输出接口。通过配置GPIO引脚的复用功能模式,我们可以利用同一个GPIO引脚输出不同的功能信号,而不仅仅是普通的数字信号。
例如,我们可以将一个GPIO引脚配置为串口功能的复用输出模式。这样,该GPIO引脚就可以用于向外部设备发送串口通信数据。同样地,我们可以将其他GPIO引脚配置为定时器、SPI、I2C等功能的复用输出模式,以实现与这些外设的通信或控制信号输出。
简而言之,复用功能输出允许我们在同一个GPIO引脚上实现多种不同的功能,通过配置不同的复用功能模式,可以将GPIO引脚连接到不同的外设,以实现特定功能的输出。这提供了更大的灵活性和功能扩展性,使单个GPIO引脚可以适应不同的应用需求。
旋转编码器计次
代码:
#include "stm32f10x.h" // 设备头文件
int16_t Encoder_Count;
void Encoder_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // GPIO口配置为输入上拉模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; // GPIO口引脚为0和1
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // GPIO口速度设置为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIOB
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1; // 外部中断线选择0和1
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能外部中断线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 外部中断模式为中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发中断
EXTI_Init(&EXTI_InitStructure); // 初始化外部中断配置
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 中断优先级分组配置
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; // 中断通道选择为EXTI0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级设置为1
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; // 中断通道选择为EXTI1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级设置为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; // 子优先级设置为2
NVIC_Init(&NVIC_InitStructure);
}
int16_t Encoder_Get(void)
{
int16_t Temp;
Temp = Encoder_Count;
Encoder_Count = 0;
return Temp;
}
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0) == SET)
{
/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
{
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
{
Encoder_Count --;
}
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
void EXTI1_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line1) == SET)
{
/*如果出现数据乱跳的现象,可再次判断引脚电平,以避免抖动*/
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
{
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
{
Encoder_Count ++;
}
}
EXTI_ClearITPendingBit(EXTI_Line1);
}
}