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

stm32之使用中断控制led灯

#include "stm32f10x.h"void delay_ms(uint32_t ms)
{for (uint32_t i = 0; i < ms * 8000; i++){ // 8 MHz HSI}
}void GPIO_Inits(void)
{// 1. 启用 GPIO 时钟、AFIO时钟使能RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN;GPIOA->CRL |= GPIO_CRL_CNF0_1;GPIOA->CRL &= ~GPIO_CRL_CNF0_0;GPIOA->CRL &= ~GPIO_CRL_MODE0;GPIOA->ODR &= ~GPIO_ODR_ODR0;//  配置 PA1 为推挽输出(2 MHz)GPIOC->CRH &= ~(GPIO_CRH_CNF13 | GPIO_CRH_MODE13);GPIOC->CRH |= GPIO_CRH_MODE13_1; // 2 MHz 输出 (10)GPIOC->ODR &= ~GPIO_ODR_ODR13;// 2. 选择 EXTI0 的PA0AFIO->EXTICR[0] |= AFIO_EXTICR1_EXTI0_PA;// 3.配置EXTI// 上升沿触发EXTI->RTSR |= EXTI_RTSR_TR0;// 开启中断频闭寄存器EXTI->IMR |= EXTI_IMR_MR0;NVIC_SetPriorityGrouping(3);NVIC_SetPriority(EXTI0_IRQn, 1); // 设置优先级// 启用中断NVIC_EnableIRQ(EXTI0_IRQn); // 启用 TIM1 更新中断
}void EXTI0_IRQHandler(void)
{EXTI->PR |= EXTI_PR_PR0; // 清除中断标志位delay_ms(10);if ((GPIOA->IDR & GPIO_IDR_IDR0) != 0){GPIOC->ODR ^= GPIO_ODR_ODR13; // 翻转PA0}
}int main(void)
{GPIO_Inits();while (1){}
}

代码总体功能

该代码为STM32F10x微控制器设计,通过外部中断(EXTI)实现PA0引脚(输入,通常连接按钮)检测上升沿信号,触发中断后翻转PC13引脚(输出,通常连接LED)的状态,实现类似按键控制LED亮灭的功能。代码包括延时函数、GPIO和EXTI初始化、中断处理及主循环。


详细总结

1. 延时函数 (delay_ms)
  • 功能:提供毫秒级别的延时,用于中断消抖。
  • 实现细节
    • 函数参数为 uint32_t ms,表示延时毫秒数。
    • 使用忙等待循环:for (uint32_t i = 0; i < ms * 8000; i++)
    • 假设系统使用8 MHz HSI内部时钟,ms * 8000 循环大致对应1毫秒(每循环耗时约1/8微秒,8000次循环约1ms)。
  • 注意点
    • 延时精度依赖于系统时钟频率(HSI 8 MHz,未明确配置)。
    • 忙等待方式占用CPU资源,适合简单应用但效率较低。
2. GPIO初始化 (GPIO_Inits)
  • 功能:配置GPIOA、GPIOC引脚及EXTI0中断,启用相关时钟。
  • 实现细节
    1. 时钟使能
      • 通过 RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN 使能GPIOA、GPIOC和AFIO外设时钟。
      • 确保相关外设可用。
    2. PA0配置(输入)
      • GPIOA->CRL |= GPIO_CRL_CNF0_1; GPIOA->CRL &= ~GPIO_CRL_CNF0_0;:配置PA0为浮空输入(CNF0 = 10)。
      • GPIOA->CRL &= ~GPIO_CRL_MODE0;:模式设为输入(MODE0 = 00)。
      • GPIOA->ODR &= ~GPIO_ODR_ODR0;:清除输出数据寄存器,可能用于初始化PA0为低电平(若后续启用下拉)。
      • 注意:代码未明确启用上拉/下拉电阻,可能依赖外部电路(如按钮外接上拉/下拉电阻)。
    3. PC13配置(输出)
      • GPIOC->CRH &= ~(GPIO_CRH_CNF13 | GPIO_CRH_MODE13);:清除PC13的配置和模式。
      • GPIOC->CRH |= GPIO_CRH_MODE13_1;:配置PC13为2 MHz推挽输出(MODE13 = 10,CNF13 = 00)。
      • GPIOC->ODR &= ~GPIO_ODR_ODR13;:初始化PC13输出为低电平(LED初始熄灭,假设低电平关闭LED)。
    4. EXTI0配置
      • AFIO->EXTICR[0] |= AFIO_EXTICR1_EXTI0_PA;:选择PA0作为EXTI0的输入源。
      • EXTI->RTSR |= EXTI_RTSR_TR0;:配置EXTI0为上升沿触发。
      • EXTI->IMR |= EXTI_IMR_MR0;:使能EXTI0中断。
    5. NVIC配置
      • NVIC_SetPriorityGrouping(3);:设置中断优先级分组为3(2位抢占优先级,2位子优先级)。
      • NVIC_SetPriority(EXTI0_IRQn, 1);:设置EXTI0中断的优先级为1(较高优先级)。
      • NVIC_EnableIRQ(EXTI0_IRQn);:使能EXTI0中断。
  • 注意点
    • PA0未明确配置上拉/下拉,可能需外部电路支持。
    • PC13常用于STM32开发板上的板载LED。
    • NVIC优先级分组和优先级设置适合简单应用,但复杂系统中需考虑优先级冲突。
3. 中断处理函数 (EXTI0_IRQHandler)
  • 功能:处理EXTI0中断,检测PA0状态并翻转PC13输出。
  • 实现细节
    • EXTI->PR |= EXTI_PR_PR0;:清除EXTI0中断标志位,防止重复触发。
    • delay_ms(10);:调用10ms延时,防止按键抖动导致多次触发。
    • if ((GPIOA->IDR & GPIO_IDR_IDR0) != 0):检查PA0输入状态是否为高电平。
      • 如果PA0为高,执行 GPIOC->ODR ^= GPIO_ODR_ODR13; 翻转PC13输出状态(LED亮灭切换)。
  • 注意点
    • 10ms延时用于消抖,但忙等待可能影响中断响应实时性。
    • 仅在PA0仍为高电平时翻转PC13,确保有效按键动作(进一步消抖)。
    • 中断处理较为简单,未考虑复杂按键模式(如长按、双击)。
4. 主函数 (main)
  • 功能:初始化系统并保持运行,等待中断触发。
  • 实现细节
    • 调用 GPIO_Inits 完成GPIO和中断初始化。
    • 进入 while (1) {} 无限循环,系统仅靠中断驱动。
  • 注意点
    • 主循环为空,CPU空闲,适合低功耗场景但未优化(如进入低功耗模式)。

整体功能与应用场景

  • 功能:实现按键(PA0)控制LED(PC13)的亮灭切换,检测按键的上升沿触发中断,翻转LED状态。
  • 应用场景
    • 适用于STM32F10x开发板的入门实验(如按键控制板载LED)。
    • 典型用于学习GPIO配置、EXTI中断和NVIC中断管理的教学案例。
  • 硬件假设
    • PA0连接按钮,外部电路提供上拉/下拉电阻(代码未启用内部上下拉)。
    • PC13连接LED(常见于STM32F103开发板,如蓝板或最小系统板)。
    • 系统时钟为8 MHz HSI(延时函数依赖此频率)。

总结

该代码实现了一个基础的按键控制LED功能,通过PA0的外部中断(EXTI0)检测上升沿,触发后翻转PC13输出状态。代码结构清晰,适合初学者学习STM32的GPIO、EXTI和NVIC配置。主要包括延时函数、GPIO和中断初始化、中断处理及空主循环。存在改进空间,如优化消抖、增加时钟配置和功耗管理,适合嵌入式开发初级实验。

http://www.lryc.cn/news/572437.html

相关文章:

  • 新生活的开启:从 Trae AI 离开后的三个月
  • linux操作命令(最常用)
  • 打破物理桎梏:CAN-ETH网关如何用UDP封装重构工业网络边界
  • 大模型更重要关注工艺
  • 目标检测之YOLOV11自定义数据使用OBB训练与验证
  • Neo4j常用语法-path
  • JS红宝书笔记 8.3 继承
  • 煤矿井下Modbus转Profibus网关的传感器与PLC互联解决方案
  • 机器学习×第十二卷:回归树与剪枝策略——她剪去多余的分支,只保留想靠近你的那一层
  • 运维人员常用网站列表
  • 【unitrix】 3.2 位取反运算(not.rs)
  • 【数字人开发】Unity+百度智能云平台实现长短文本个性化语音生成功能
  • 吃透 Golang 基础:Goroutine
  • golang excel导出时需要显示刷新
  • Set_path_margin 命令介绍
  • C++中所有数据类型
  • Jenkins通过Pipeline流水线方式编译Java项目
  • Docker+Jenkins+git实现Golang项目自动部署
  • springboot 打的可执行jar包单独更新某个jar包
  • JMeter 高阶玩法:分布式压测的技术核心技术要点
  • 【K8S】详解NodePort 和 ClusterIP
  • 大数据复习HDFS
  • 11.0592MHz晶振:电脑主板的“心脏”
  • 通过Docker挂载nginx并修改页面
  • ros中相机话题在web页面上的显示,尝试js解析sensor_msgs/Image数据
  • 嵌入式开发之freeRTOS移植
  • Kafka性能调优全攻略:从JVM参数到系统优化
  • Java的SpringAI+Deepseek大模型实战
  • 基于keepalived、vip实现高可用nginx (centos)
  • mongodb单节点改副本集模式