使用外部中断方式在oled屏幕上显示计次
步骤:
-打开GPIO、AFIO外设并配置
-配置EXTI、NVIC(EXTI、NVIC这些模块已经自动准备就绪,无需额外的启动步骤)
-配置中断函数
不断获取被中断函数操作的变量,把变量信息显示在oled屏幕上
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Encoder.h"
int16_t Count;
int main(void)
{
/*模块初始化*/
OLED_Init(); //OLED初始化
Encoder_Init(); //旋转编码器初始化
/*OLED显示*/
OLED_ShowString(1, 1, "Count:"); //1行3列显示字符串HelloWorld!
while (1)
{
Count += Count_Get();
OLED_ShowSignedNum(2,1,Count,5);
}
}
配置外部中断 Encoder.c
#include "stm32f10x.h" // Device header
int16_t Count_num;
void Encoder_Init(void)
{
//开启GPIO、AFIO的外设
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2ENR_AFIOEN,ENABLE);
GPIO_InitTypeDef GPIO_InitStrcuture;
//上拉输入方式
GPIO_InitStrcuture.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStrcuture.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_Init(GPIOB, &GPIO_InitStrcuture);
//配置AFIO 不同GPIO组也不能使用相同的GPIO_PinSourceX
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource1);
//配置EXTI
EXTI_InitTypeDef EXTI_InitStructuer;
EXTI_InitStructuer.EXTI_Line = EXTI_Line0 | EXTI_Line1;
EXTI_InitStructuer.EXTI_LineCmd = ENABLE;
//这里设置的是外部中断
EXTI_InitStructuer.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructuer.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStructuer);
//配置NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&NVIC_InitStructure);
}
int16_t Count_Get(void)
{
int16_t temp = Count_num;
Count_num = 0;
return temp;
}
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) == SET)
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0)
{
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0) == 0);
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) //PB0的下降沿触发中断,此时检测另一相PB1的电平,目的是判断旋转方向
{
Count_num --; //此方向定义为反转,计数变量自减
}
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
void EXTI1_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line1) == SET)
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)
{
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0);
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0) //PB0的下降沿触发中断,此时检测另一相PB1的电平,目的是判断旋转方向
{
Count_num ++; //此方向定义为反转,计数变量自减
}
}
EXTI_ClearITPendingBit(EXTI_Line1);
}
}
评论 (0)