STM32F103蓝丸从头中断

问题描述

如何从头开始为蓝色药丸创建中断?

我不想使用任何类型的特殊库。此外,我使用 Keil IDE,因此,通过“从头开始构建”,我指的是不使用任何额外的库,而不是在没有 IDE 帮助的情况下组装项目。

我试图寻找资源,但没有成功。有人可以帮助我并至少为我提供一些信息/参考书目吗?我将不胜感激。

此外,“奇怪的库”是指除 stmf32f1xx.h 头文件之外的任何其他库。当其中一个引脚的输入值切换时,我想触发一个中断。为了做到这一点,在 AVR MCU 上非常简单,只要更改几个寄存器值即可。不幸的是,我不知道 ARM MCU 中的中断是如何工作的,以及我应该在哪些寄存器中写入哪些值。

此外,更好地了解 ARM MCU 的中断机制将使我为解决去抖动问题做好更充分的准备。

解决方法

当您要求“无库”时,我不会完全从字面上理解您,因为没有人想要完成工作并知道他们在 Cortex-M 上做什么 - 我会假设 至少您将使用 CMSIS - 为所有 ARM Cortex-M 设备提供的通用 API,它使您的代码更具可移植性。

所有 CMSIS 代码都是作为源代码提供的,而不是静态库,因此没有任何隐藏内容,如果您选择不使用它,您可以查看它的工作原理,并根据需要(不必要地)复制该功能。

>

在 CMSIS 中,默认实现是作为“弱链接”提供的,用户代码可以简单地通过定义一个预定义名称的函数来覆盖默认实现。默认实现通常是一个无限循环 - 以便“捕获”未处理的中断,以便您可以干预调试器或等待看门狗重置。

Cortex-M 内核中断处理程序和异常处理程序在所有 Cortex-M 部件中具有通用名称:

Reset_Handler      
NMI_Handler        
HardFault_Handler  
MemManage_Handler  
BusFault_Handler   
UsageFault_Handler 
SVC_Handler        
DebugMon_Handler   
PendSV_Handler     
SysTick_Handler    

外设中断处理程序的名称由供应商定义,但命名约定为 <interrupt_source>_IRQHandler。例如,在 STM32F1xx 上,EXTI0_IRQHandler 是分配给 GPIO 端口零位的共享外部中断。

要实现 CMSIS 中断处理程序,您需要做的就是:

  1. 使用 CMSIS 处理函数名称实现中断处理函数
  2. 在 NVIC(中断控制器)中启用中断。

您还可以做其他一些事情,例如分配中断优先级方案(抢占优先级和子优先级之间的划分),但让我们暂时保持简单。

因为它在所有 Cortex-M 部件中无处不在,并且因为它在几乎所有重要应用程序中都很有用,所以使用 SYSTICK 中断的插图作为起点很有用。

#include "stm32f1xx.h"
  
volatile uint32_t msTicks = 0 ;
  
void SysTick_Handler(void)  
{
    msTicks++ ;
}
  
int main (void)  
{
    if( SysTick_Config( SystemCoreClock / 1000 ) != 0 ) // 1ms tick
    {
        // Error Handling 
    }
  
    ...

}

SysTick_Config() 是另一个 CMSIS 函数。在 core_cm3.h 中它看起来像这样:

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
  {
    return (1UL);                                                   /* Reload value impossible */
  }

  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
  NVIC_SetPriority (SysTick_IRQn,(1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
  return (0UL);                                                     /* Function successful */
}

假设您在 GPIOA 引脚 0 的下降沿有一个外部中断源,那么您将使用 STM32 EXTI0 中断。最小的处理程序看起来像:

void EXTI0_IRQHandler(void)
{
    EXTI->PR |= (1<<0);                           // clear pending interrupt

    // Handle interrupt...
}

设置 EXTI 需要启用 GPIO 和 EXTI 本身以及 NVIC:

RCC->APB2ENR |= RCC_APB2ENR_IOPAEN ;           // enable clock for GPIOA
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN ;           // enable clock for Alternate Function
AFIO->EXTICR[0] |= AFIO_EXTICR1_EXTI0 ;        // set pin to use

EXTI->IMR = EXTI_IMR_MR0 ;             // unmask interrupt
EXTI->EMR = EXTI_EMR_MR0 ;             // unmask event
EXTI->FTSR = EXTI_FTSR_TR0 ;           // set falling edge

NVIC->ISER[0] |= (1 << (EXTI0_IRQChannel & 0x1F));    // enable interrupt EXTI 0

外围寄存器和结构在 stm32f10weakx.h 中定义,要覆盖的“弱”默认外围处理程序在 startup_stm32f10x_cl.s 中针对您的特定部分。您覆盖的任何处理程序都必须与这些符号名称完全匹配。

所有外设中断源以及如何配置它们都在 ST Reference Manual RM0008 中定义。

所有 Cortex-M 内核特定的东西 - systtick、NVIC、异常处理程序等都由 ARM 在 https://developer.arm.com/ip-products/processors/cortex-m/cortex-m3 处提供

CM3 的 CMSIS 记录在 https://developer.arm.com/documentation/dui0552/a/

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...