当前位置: 首页 > 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和中断初始化、中断处理及空主循环。存在改进空间,如优化消抖、增加时钟配置和功耗管理,适合嵌入式开发初级实验。

相关文章:

  • C++ 友元
  • 【沉浸式解决问题】baseMapper can not be null
  • 【世纪龙科技】智能网联汽车自动驾驶虚拟实训软件
  • JS红宝书笔记 8.2 创建对象
  • Mybatis之Integer类型字段为0,入库为null
  • Spring-创建第一个SpringBoot项目
  • html实现登录与注册功能案例(不写死且只使用js)
  • Ubuntu编译ffmpeg解决错误:ERROR: avisynth/avisynth_c.h not found
  • Kafka性能压测报告撰写
  • Vue3中使用 Vue Flow 流程图方法
  • 103. 2017年蓝桥杯省赛 - 日期问题(困难)- 暴力枚举
  • (哈希)128. 最长连续序列
  • 华为ModelArts详解
  • 使用 mysql2/promise 模块返回以后,使用 await 返回数据总结
  • 时序数据库概念及IoTDB特性详解
  • C++位图
  • FPGA基础 -- Verilog 命名事件
  • Debian配置Redis主从、哨兵
  • Rsync+sersync实现数据实时同步(小白的“升级打怪”成长之路)
  • C++实现异步(重叠)管道通信
  • 黄金做空网站/上海seo关键词优化
  • 怎么用html建网站/宁波怎么优化seo关键词
  • 品牌推广公司是做什么的/广州各区正在进一步优化以下措施
  • 中国能源建设集团网站群/北京aso优化
  • 南通高端网站建设/seo优化快速排名技术
  • 哪网站建设好/抖音搜索引擎推广