【STM32学习记录04】传感器计数&旋转编码器计数

学习目标 

        学习STM32的外部中断。STM32的每个 IO 口都可以作为外部中断的中断输入口。本次内容需要我们掌握外设、EXTI、NVIC之间的关系。

一、任务要求

        (1)通过对传感器的设计,在OLED 屏幕上实现计数操作。

        (2)通过旋转编码器实现OLED屏上的数字加减。

二、传感器计数

1.主函数main
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "OLED.h"
#include "CountSensor.h"

int main(void)
{
	OLED_Init();
	CountSensor_Init();
	
	OLED_ShowString(1, 3, "HelloWorld!");
	OLED_ShowString(2, 1, "Count:");
	while (1)
	{
		OLED_ShowNum(2, 7, Count_Get(), 5);
	}
}
2.函数封装CountSensor
//CountSensor.c
#include "stm32f10x.h"                  // Device header

uint16_t Count = 0;

void CountSensor_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	//开启GPIO时钟。
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);	//开启AFIO时钟。
	
	//(1)设定GPIO模式
	GPIO_InitTypeDef GPIO_InitStuct;
	GPIO_InitStuct.GPIO_Mode = GPIO_Mode_IPU;	//上拉输入
	GPIO_InitStuct.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStuct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStuct);
	
	//(2)设定EXTI触发条件
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);	//设置IO口与中断线的映射关系
	
	EXTI_InitTypeDef EXTI_InitStuct;
	EXTI_InitStuct.EXTI_Line = EXTI_Line14;				//指定要配置的中断线
	EXTI_InitStuct.EXTI_LineCmd = ENABLE;				//使能 OR失能
	EXTI_InitStuct.EXTI_Mode = EXTI_Mode_Interrupt; 	//模式:事件 OR中断
	EXTI_InitStuct.EXTI_Trigger = EXTI_Trigger_Falling;	//触发方式:上升沿/下降沿/双沿触发
	EXTI_Init(&EXTI_InitStuct); 						//初始化中断线:触发方式等
	
	//(3)配置中断优先级(NVIC)
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		//配置 NVIC 优先级组
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;		//配置中断源
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;			//使能中断通道
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;	//配置抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;			//配置子优先级
	NVIC_Init(&NVIC_InitStruct);		
}

//(4)编写中断服务函数。
void EXTI15_10_IRQHandler()
{
	if (EXTI_GetITStatus(EXTI_Line14) ==SET){  	//判断中断线中断状态是否发生
		Count++;
	}
	EXTI_ClearITPendingBit(EXTI_Line14);		//清除中断线上的中断标志位
}

uint16_t Count_Get(void)
{
	return Count;
}


//CountSensor.h
#ifndef _COUNT_SENSOR_H
#define _COUNT_SENSOR_H

uint16_t Count_Get(void);
void CountSensor_Init(void);

#endif

三、旋转编码器

1.主函数main
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "OLED.h"
#include "counter.h"

int16_t Num;

int main(void)
{
	OLED_Init();
	counter_Init();
	OLED_ShowString(1, 1, "Num:");
	
	while (1)
	{
		Num += Get_counter();
		OLED_ShowSignedNum(2,5,Num,5);
	}
}
2.函数封装counter
#include "stm32f10x.h"                  // Device header

void counter_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource11);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource12);
	
	EXTI_InitTypeDef EXTI_InitStruct;
	EXTI_InitStruct.EXTI_Line = EXTI_Line11;
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStruct);
	
	EXTI_InitTypeDef EXTI_InitStruct1;
	EXTI_InitStruct1.EXTI_Line = EXTI_Line12;
	EXTI_InitStruct1.EXTI_LineCmd = ENABLE;
	EXTI_InitStruct1.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStruct1.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStruct1);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);
}

int16_t counter;

void EXTI15_10_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line11) == SET){
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12) == 0){
			counter ++;		
		}
		EXTI_ClearITPendingBit(EXTI_Line11);
	}
	if (EXTI_GetITStatus(EXTI_Line12) == SET){
		if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0){
			counter --;
		}
		EXTI_ClearITPendingBit(EXTI_Line12);
	}
}

int16_t Get_counter(void) //返回变化值
{
	int16_t temp;
	temp = counter;
	counter = 0;
	return temp;
}

四、OLED封装函数

        温馨提示:OLED的函数封装代码可以私信找我拿(免费)!

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gui林

你的热爱是我更新的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值