当前位置: 首页 > news >正文

第五章第二节 对射式红外传感器计次旋转编码器计次

一、对射式红外传感器计次

① 外部中断(EXTI) 初始化

EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line14;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);

(1) 功能:配置外部中断线14的参数

(2) 逐行解释:

  • EXTI_InitTypeDef EXTI_InitStructure:定义 EXTI 配置结构体
  • EXTI_Line = EXTI_Line14:选择中断线14
  • EXTI_Mode = EXTI_Mode_Interrupt:设置为中断模式
  • EXTI_Trigger = EXTI_Trigger_Falling:关键设置-下降沿触发
  • EXTI_Linecmd = ENABLE:使能此中断线
  • EXTI_Init(&EXTI_InitStructure):应用配置

② NVIC 配置分组

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);

(1) 中断优先级分组

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  • 将4位优先级分成:2位用于抢占优先级(可设置0-3),2位用于子优先级(可设置0-3)
  • 抢占优先级高的中断可以打断正在执行的抢占优先级低的中断(抢占式)
  • 相同抢占优先级时,子优先级决定执行顺序(非抢占)

(2) 中断通道选择

NVIC_IRQChannel = EXTI15_10_IRQn;
  • 外部中断线 10-15 共享同一个中断通道

③ main.c 模块

int main(void)
{// 初始化OLED显示屏和计数器传感器OLED_Init();CountSensor_Init();// 在OLED屏幕第一行第一列显示"Count:"文本OLED_ShowString(1, 1, "Count:");// 进入无限循环,持续更新显示while (1){// 在屏幕第一行第七列显示计数器的数值// 参数说明://   1 - 显示在第一行//   7 - 从第7列开始显示//   CountSensor_Get() - 获取传感器计数值//   5 - 显示5位数字OLED_ShowNum(1, 7, CountSensor_Get(), 5);}
}

(1) OLED_ShowNum(1, 7, CountSensor_Get(), 5):包含多层功能:

  • CountSensor_Get():调用获取当前计数值的函数
  • 将获取的数值显示在屏幕第一行第七列
  • 5:显示总位数为5位(如数值23显示为“00023”)

二、旋转编码器计次

1. 中断服务函数(核心逻辑)

(1) 全局变量声明

int16_t Encoder_Count;  // 全局计数器,记录编码器转动步数

① 为什么选择 int16_t,而不是 uint16_t?

  • 旋转编码器需要表示两个旋转方向:正数为顺时针转动(增加数值),负数(减少数值)

(2) 编码器数值获取函数

int16_t Encoder_Get(void)
{int16_t Temp;         // 声明临时变量Temp = Encoder_Count; // 读取当前计数值Encoder_Count = 0;    // 立即清零计数器(用于下次测量)return Temp;          // 返回读取的计数值(此方向转动步数)
}

① 核心功能:

  • 读取当前计数值 → Temp = Encoder_Count
  • 立即清零计数器 → Encoder_Count = 0
  • 返回读取值 → return Temp

② 工作流程示例:

时间点动作Encoder_Count
初始状态编码器开始旋转0
旋转5步后5
调用函数Temp = 5; Encoder_Count = 00 → 返回5
再旋转3步3
调用函数Temp = 3; Encoder_Count = 00 → 返回3

(3) 检测编码器旋转方向并计数

void EXTI0_IRQHandler(void) 
{// 确认是否发生Line0中断if (EXTI_GetITStatus(EXTI_Line0) == SET) {// 读取B相电平(关键:方向判断)if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) {Encoder_Count--; // B相为低电平时逆时针转动}EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志}
}
http://www.dtcms.com/a/300847.html

相关文章:

  • 8.c语言指针
  • 标签驱动的可信金融大模型训练全流程-Agentar-Fin-R1工程思路浅尝
  • AI驱动的金融推理:Fin-R1模型如何重塑行业决策逻辑
  • JSON格式化与结构对比
  • 2025年量子计算与前沿技术融合:六大变革性方向深度解析
  • Rust实战:高效开发技巧
  • 02人工智能中优雅草商业实战项目视频字幕翻译以及声音转译之以三方AI模型API制作方式预算-卓伊凡|莉莉
  • 【在Unity游戏开发中Dictionary、List介绍】
  • 基于Springboot+UniApp+Ai实现模拟面试小工具七:前端项目创建及框架搭建
  • 深入理解 Spring 中的 XmlBeanFactory 原理及实践
  • 【最新版】防伪溯源一体化管理系统+uniapp前端+搭建教程
  • ArKTS:List 数组
  • 机器学习特征选择 explanation and illustration of ANOVA
  • ROS2总结(二)
  • UDS 0x29 身份验证服务 Authentication service
  • Rust Web 全栈开发(十一):WebAssembly 尝鲜
  • 2507rust,rust写驱动
  • rust- 定义模块以控制作用域和隐私
  • 无刷电机三项霍尔连接线序组合详细分析与波形实例
  • ETF历史每笔成交分钟级高频数据深度解析
  • 墨者:通过手工解决SQL手工注入漏洞测试(MongoDB数据库)
  • Rust与Java DynamoDB、MySQL CRM、tokio-pg、SVM、Custors实战指南
  • 零基础 “入坑” Java--- 十四、字符串String
  • mybatis-plus实体类主键生成策略
  • 使用uni-app开发一个点餐收银台系统前端静态项目练习
  • 车辆网络安全规定之R155与ISO/SAE 21434
  • 09_opencv_遍历操作图像像素
  • uniapp input 聚焦时键盘弹起滚动到对应的部分
  • 基础配置介绍,VLAN配置,DHCP配置
  • 迷宫生成与路径搜索(A算法可视化)